Notice: This Wiki is now read only and edits are no longer possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.
JakartaEE Maven Versioning Rules
Maven and OSGi packaging, naming, and versioning rules
- Version 12 - 2/25/2020
- Bill Shannon
- Version 13 - 2/25/2020
- Replace JPMS note with link to EE10 conventions.
NOTE: The JPMS can be found in the Platform project JPMS_Naming_Rules page: https://github.com/eclipse-ee4j/jakartaee-platform/wiki/JPMS_Naming_Rules
This note describes our general rules for choosing Maven, OSGi, and jar file manifest names and version numbers for implementation artifacts related to Jakarta EE standard technologies. Not all Jakarta EE standards will produce all artifacts described here, but if they do they should use the approach described here. These are the rules that the EE4J implementation should follow; other compatible implementations will use different names. A given technology will commonly produce two artifacts: - an API jar file The API jar file typically includes only the spec-defined classes/interfaces/etc. that define the API, that is, usually just the javax.* class files. The purpose of the API jar file is *only* to allow programs to be compiled against the API without the risk of depending on non-API classes. The API jar file is *not* intended to be used at runtime (although in some cases it may be), and it is *not* intended to be a portable implementation of the API classes that can be used by others to derive their own implementation of the specification (although in some cases it will be). An extreme example of an API jar file is the "jakartaee.jar" file that we produce, which contains *no* code at all for any of the classes, and is not a valid class file for use at runtime. It is suitable only for reference by the compiler. Most other API jar files will not take this extreme approach. We require API jar files to be published to the Maven central repository. To that end, the API jar file must be accompanied by two additional jar files: The API javadoc jar This is a jar file containing the generated documentation for the spec. The index.html file of the javadoc tree must be at the top level of this jar file. The API source jar For debugging purposes, this is the source from which the API jar file was compiled. It need not be compilable on its own. - an implementation jar file If the specification defines a standalone version of the technology, the implementation jar file will be such a standalone implementation of the specification, and will meet all the compatibility requirements of the specification. The implementation jar file typically includes all the classes from the API jar file, plus whatever implementation classes are needed to produce a complete runtime. In some cases the implementation jar file might contain only the implementation artifacts, and depend on the API jar file for the API definitions, although this is discouraged for standalone implementations. Not all specifications will define a standalone version, and even when they do a standalone version following the recommendations described here might not be available. For example, while the Servlet spec allows for a standalone implementation, we do not produce a standalone Servlet implementation packaged as a single jar file. There might still be a standalone Servlet implementation, e.g., composed of multiple jar files, but we don't define naming or packaging for that here. - Naming To illustrate the general approach, we'll use three existing technologies: - Jakarta Connectors, a technology only available as a part of GlassFish - Jakarta Server Faces, a technology closely associated with GlassFish, but available independently - Jakarta Mail, a technology included with GlassFish, but widely used independently The general approach is described using the following "variables": API_PACKAGE - the primary Java package defining the API, with "javax" replaced by "jakarta" IMPL_NAMESPACE - the primary Java package or namespace used by the implementation of the API, or with which the implementation of the API is associated STANDALONE_IMPL - a boolean indicating whether a standalone implementation is available; if false, no implementation jar file is defined Given these variables, the following names should be used: API jar file: ${API_PACKAGE}-api.jar OSGi Bundle-SymbolicName: ${API_PACKAGE}-api Maven group ID, artifact ID: ${API_PACKAGE}:${API_PACKAGE}-api jar Extension-Name: ${API_PACKAGE} API javadoc jar file: ${API_PACKAGE}-api-javadoc.jar API source jar file: ${API_PACKAGE}-api-sources.jar Implementation jar file: ${API_PACKAGE}.jar OSGi Bundle-SymbolicName: ${IMPL_NAMESPACE}.${API_PACKAGE} Maven group ID, artifact ID: ${IMPL_NAMESPACE}:${API_PACKAGE} jar Extension-Name: ${API_PACKAGE} These names are appropriate for the EE4J implementation of a specification. Other compatible implementations should create an implementation jar file named ${IMPL_NAMESPACE}.${API_PACKAGE}.jar. Other compatible implementations should not produce an API jar file. The jar file names above are the names that should be used for jar files that are made available in a download bundle, such as a zip file distribution for the technology. Note that, when building with Maven, the jar file names will include the version number, as described in the following section. Note that the above would produce both an API jar and an implementation jar with the same jar Extension-Name. In the case where an implementation jar file depends on the API jar file (rather than including the API definitions), the API jar file should *not* have an Extension-Name header. Note that even though the API jar file is not usable at runtime, it should have OSGi metadata to allow it to be used by development tools that understand OSGi bundles. Applying these rules to our three examples, we get: Jakarta Connectors: API_PACKAGE=jakarta.resource IMPL_NAMESPACE=org.glassfish STANDALONE_IMPL=false API jar file: jakarta.resource-api.jar OSGi Bundle-SymbolicName: jakarta.resource-api Maven group ID, artifact ID: jakarta.resource:jakarta.resource-api jar Extension-Name: jakarta.resource API javadoc jar file: jakarta.resource-api-javadoc.jar API source jar file: jakarta.resource-api-sources.jar Jakarta Server Faces: API_PACKAGE=jakarta.faces IMPL_NAMESPACE=org.glassfish STANDALONE_IMPL=true API jar file: jakarta.faces-api.jar OSGi Bundle-SymbolicName: jakarta.faces-api Maven group ID, artifact ID: jakarta.faces:jakarta.faces-api jar Extension-Name: jakarta.faces API javadoc jar file: jakarta.faces-api-javadoc.jar API source jar file: jakarta.faces-api-sources.jar Implementation jar file: jakarta.faces.jar OSGi Bundle-SymbolicName: org.glassfish.jakarta.faces Maven group ID, artifact ID: org.glassfish:jakarta.faces jar Extension-Name: jakarta.faces Jakarta Mail: API_PACKAGE=jakarta.mail IMPL_NAMESPACE=com.sun.mail STANDALONE_IMPL=true API jar file: jakarta.mail-api.jar OSGi Bundle-SymbolicName: jakarta.mail-api Maven group ID, artifact ID: jakarta.mail:jakarta.mail-api jar Extension-Name: jakarta.mail API javadoc jar file: jakarta.mail-api-javadoc.jar API source jar file: jakarta.mail-api-sources.jar Implementation jar file: jakarta.mail.jar OSGi Bundle-SymbolicName: com.sun.mail.jakarta.mail Maven group ID, artifact ID: com.sun.mail:jakarta.mail jar Extension-Name: jakarta.mail For technologies that are closely associated with GlassFish, the org.glassfish name should be used as IMPL_NAMESPACE. For technologies that are more independent of GlassFish, a name should be chosen based on the Java packages used for the implementation, or the web site hosting the project. - Version numbers In addition to names, we also need to specify version numbers for each of the artifacts produced. The version numbers of the API are specified through the Jakarta EE Specification Process. Two common approaches are used for the version numbers of the implementation: 1. The implementation version tracks the API version, using a "dot-dot" version number to distinguish versions of the implementation that all implement the same API version. This approach is most often used when the implementation is primarily intended to be only a compatible implementation of the given technology. 2. The implementation version number is completely independent of the API version number. This approach is most often used when the implementation has a purpose different from, or larger than, being just a compatible implementation of a specification. For example, the GlassFish version number is independent of the version numbers of any specification implemented by GlassFish. A version number is a Dewey-decimal number of two or three components, either <major>.<minor> or <major>.<minor>.<micro>. We define the following additional variables: SPEC_VERSION - version number of the specification, always of the form <major>.<minor> SPEC_IMPL_VERSION - version number of the API classes, derived from SPEC_VERSION by adding a required micro version number IMPL_VERSION - version number of the implementation Having a separate SPEC_VERSION and SPEC_IMPL_VERSION allows the API definition classes to be updated (e.g., to fix spec or implementation bugs) in cases where the corresponding spec has not changed. In case #1 above, SPEC_IMPL_VERSION and IMPL_VERSION will have the same value. In case #2 above, SPEC_IMPL_VERSION will need to be maintained and updated separately from IMPL_VERSION. Adding the version number information to our general rules, we get: API jar file: ${API_PACKAGE}-api.jar OSGi Bundle-SymbolicName: ${API_PACKAGE}-api OSGi bundle specversion: ${SPEC_VERSION} OSGi Bundle-Version: ${SPEC_IMPL_VERSION} Maven group ID, artifact ID: ${API_PACKAGE}:${API_PACKAGE}-api Maven version: ${SPEC_IMPL_VERSION} Maven API jar file: ${API_PACKAGE}-api-${SPEC_IMPL_VERSION}.jar jar Extension-Name: ${API_PACKAGE} jar Specification-Version: ${SPEC_VERSION} jar Implementation-Version: ${SPEC_IMPL_VERSION} Implementation jar file: ${API_PACKAGE}.jar OSGi Bundle-SymbolicName: ${IMPL_NAMESPACE}.${API_PACKAGE} OSGi bundle specversion: ${SPEC_VERSION} OSGi Bundle-Version: ${IMPL_VERSION} Maven group ID, artifact ID: ${IMPL_NAMESPACE}:${API_PACKAGE} Maven version: ${IMPL_VERSION} Maven impl jar file: ${API_PACKAGE}-${IMPL_VERSION}.jar jar Extension-Name: ${API_PACKAGE} jar Specification-Version: ${SPEC_VERSION} jar Implementation-Version: ${IMPL_VERSION} For technologies that are closely associated with GlassFish, and especially for technologies that are built with the main GlassFish repository, the version number of the implementation should track the version number of GlassFish. Applying the above rules to our examples gives: Jakarta Connectors: API_PACKAGE=jakarta.resource IMPL_NAMESPACE=org.glassfish STANDALONE_IMPL=false SPEC_VERSION=1.6 SPEC_IMPL_VERSION=1.6.0 API jar file: jakarta.resource-api.jar OSGi Bundle-SymbolicName: jakarta.resource-api OSGi bundle specversion: 1.6 OSGi Bundle-Version: 1.6.0 Maven group ID, artifact ID: jakarta.resource:jakarta.resource-api Maven version: 1.6.0 Maven API jar file: jakarta.resource-api-1.6.0.jar jar Extension-Name: jakarta.resource jar Specification-Version: 1.6 jar Implementation-Version: 1.6.0 Jakarta Server Faces: API_PACKAGE=jakarta.faces IMPL_NAMESPACE=org.glassfish STANDALONE_IMPL=true SPEC_VERSION=2.3 SPEC_IMPL_VERSION=2.3.0 IMPL_VERSION=2.3.0 API jar file: jakarta.faces-api.jar OSGi Bundle-SymbolicName: jakarta.faces-api OSGi bundle specversion: 2.3 OSGi Bundle-Version: 2.3.0 Maven group ID, artifact ID: jakarta.faces:jakarta.faces-api Maven version: 2.3.0 Maven API jar file: jakarta.faces-api-2.3.0.jar jar Extension-Name: jakarta.faces jar Specification-Version: 2.3 jar Implementation-Version: 2.3.0 Implementation jar file: jakarta.faces.jar OSGi Bundle-SymbolicName: org.glassfish.jakarta.faces OSGi bundle specversion: 2.3 OSGi Bundle-Version: 2.3.0 Maven group ID, artifact ID: org.glassfish:jakarta.faces Maven version: 2.3.0 Maven imp jar file: jakarta.faces-2.3.0.jar jar Extension-Name: jakarta.faces jar Specification-Version: 2.3 jar Implementation-Version: 2.3.0 Jakarta Mail: API_PACKAGE=jakarta.mail IMPL_NAMESPACE=com.sun.mail STANDALONE_IMPL=true SPEC_VERSION=1.6 SPEC_IMPL_VERSION=1.6.3 IMPL_VERSION=1.6.3 API jar file: jakarta.mail-api.jar OSGi Bundle-SymbolicName: jakarta.mail-api OSGi bundle specversion: 1.6 OSGi Bundle-Version: 1.6.3 Maven group ID, artifact ID: jakarta.mail:jakarta.mail-api Maven version: 1.6.3 Maven API jar file: jakarta.mail-api-1.6.3.jar jar Extension-Name: jakarta.mail jar Specification-Version: 1.6 jar Implementation-Version: 1.6.3 Implementation jar file: jakarta.mail.jar OSGi Bundle-SymbolicName: com.sun.mail.jakarta.mail OSGi bundle specversion: 1.6 OSGi Bundle-Version: 1.6.3 Maven group ID, artifact ID: com.sun.mail:jakarta.mail Maven version: 1.6.3 Maven imp jar file: jakarta.mail-1.6.3.jar jar Extension-Name: jakarta.mail jar Specification-Version: 1.6 jar Implementation-Version: 1.6.3 Note that the Maven API jar file name contains the *implementation* version number. This allows the API definitions to be updated, e.g., to fix bugs, even though the API *specification* hasn't changed. - Version numbers for non-final specifications While a Jakarta EE standard specification is under development, we need to be able to publish artifacts corresponding to the non-final specification. Maven version rules define a version number with a modifier as being "less then", or older than a version number without a modifier. This allows us to use modifiers for these intermediate versions without confusion with the final version number. Ideally, the modifiers would correspond to the Jakarta EE stages, but since modifiers sort lexicographically this won't work. Unfortunately, this makes it difficult to determine (e.g.) which artifact corresponds to which interim draft version of the specification. Unfortunately, OSGi defines modifiers as being "greater than" the base version number, as does the jar extension spec. This prevents us from using modifiers in the same way as we would with Maven. Instead, we adopt a convention that a "micro" version number of "99" means a non-final version of the following version number. For consistency with Maven version processing, the use of the following version modifiers is strongly suggested for non-final specifications and associated artifacts: Builds -Bn (this one will be used in the examples below) Milestones -Mn Release Candidates -RCn Some variables to define the new version numbers: SPEC_BUILD - the number of a particular build of the API jar file, e.g., "01", "02", etc. IMPL_BUILD - the number of a particular build of the implementation jar file, e.g., "01", "02", etc. SPEC_VERSION - version number of the last final specification, always of the form <major>.<minor> IMPL_VERSION - version number of the previous final implementation OSGI_IMPL_VERSION - IMPL_VERSION truncated to <major>.<minor> NEW_SPEC_VERSION - the version number of the specification under development NEW_IMPL_VERSION - the version number of the implementation that will be used when the implementation is final This gives us the general rules for versioning a non-final artifact: API jar file: ${API_PACKAGE}-api.jar OSGi Bundle-SymbolicName: ${API_PACKAGE}-api OSGi bundle specversion: ${SPEC_VERSION}.99.B${SPEC_BUILD} OSGi Bundle-Version: ${SPEC_VERSION}.99.B${SPEC_BUILD} Maven group ID, artifact ID: ${API_PACKAGE}:${API_PACKAGE}-api Maven version: ${NEW_SPEC_VERSION}-B${SPEC_BUILD} jar Extension-Name: ${API_PACKAGE} jar Specification-Version: ${SPEC_VERSION}.99.${SPEC_BUILD} jar Implementation-Version: ${NEW_SPEC_VERSION}-B${SPEC_BUILD} Implementation jar file: ${API_PACKAGE}.jar OSGi Bundle-SymbolicName: ${IMPL_NAMESPACE}.${API_PACKAGE} OSGi bundle specversion: ${SPEC_VERSION}.99.B${SPEC_BUILD} OSGi Bundle-Version: ${OSGI_IMPL_VERSION}.99.B${IMPL_BUILD} Maven group ID, artifact ID: ${IMPL_NAMESPACE}:${API_PACKAGE} Maven version: ${NEW_IMPL_VERSION}-B${IMPL_BUILD} jar Extension-Name: ${API_PACKAGE} jar Specification-Version: ${SPEC_VERSION}.99.${SPEC_BUILD} jar Implementation-Version: ${NEW_IMPL_VERSION}-B${IMPL_BUILD} Let's apply these rules to our examples: Jakarta Connectors: API_PACKAGE=jakarta.resource IMPL_NAMESPACE=org.glassfish STANDALONE_IMPL=false SPEC_BUILD=01 SPEC_VERSION=1.6 NEW_SPEC_VERSION=2.0 (making this up) API jar file: jakarta.resource-api.jar OSGi Bundle-SymbolicName: jakarta.resource-api OSGi bundle specversion: 1.6.99.B01 OSGi Bundle-Version: 1.6.99.B01 Maven group ID, artifact ID: jakarta.resource:jakarta.resource-api Maven version: 2.0.0-B01 jar Extension-Name: jakarta.resource jar Specification-Version: 1.6.99.01 jar Implementation-Version: 2.0.0-B01 Jakarta Server Faces: API_PACKAGE=jakarta.faces IMPL_NAMESPACE=org.glassfish STANDALONE_IMPL=true SPEC_VERSION=2.3 SPEC_IMPL_VERSION=2.3.2 IMPL_VERSION=2.3.2 OSGI_IMPL_VERSION=2.3 NEW_SPEC_VERSION=2.4 SPEC_BUILD=01 NEW_IMPL_VERSION=2.4.0 IMPL_BUILD=01 API jar file: jakarta.faces-api.jar OSGi Bundle-SymbolicName: jakarta.faces-api OSGi bundle specversion: 2.3.99.B01 OSGi Bundle-Version: 2.3.99.B01 Maven group ID, artifact ID: jakarta.faces:jakarta.faces-api Maven version: 2.4.0-B01 jar Extension-Name: jakarta.faces jar Specification-Version: 2.3.99.01 jar Implementation-Version: 2.4.0-B01 Implementation jar file: jakarta.faces.jar OSGi Bundle-SymbolicName: org.glassfish.jakarta.faces OSGi bundle specversion: 2.3.99.B01 OSGi Bundle-Version: 2.3.99.B01 Maven group ID, artifact ID: org.glassfish:jakarta.faces Maven version: 2.4.0-B01 jar Extension-Name: jakarta.faces jar Specification-Version: 2.3.99.01 jar Implementation-Version: 2.4.0-B01 Jakarta Mail: API_PACKAGE=jakarta.mail IMPL_NAMESPACE=com.sun.mail STANDALONE_IMPL=true SPEC_VERSION=1.6 SPEC_IMPL_VERSION=1.6.4 IMPL_VERSION=1.6.4 OSGI_IMPL_VERSION=1.6 NEW_SPEC_VERSION=1.7 SPEC_BUILD=01 NEW_IMPL_VERSION=1.7.0 IMPL_BUILD=01 API jar file: jakarta.mail-api.jar OSGi Bundle-SymbolicName: jakarta.mail-api OSGi bundle specversion: 1.6.99.B01 OSGi Bundle-Version: 1.6.99.B01 Maven group ID, artifact ID: jakarta.mail:jakarta.mail-api Maven version: 1.7.0-B01 jar Extension-Name: jakarta.mail jar Specification-Version: 1.6.99.01 jar Implementation-Version: 1.7.0-B01 Implementation jar file: jakarta.mail.jar OSGi Bundle-SymbolicName: com.sun.mail.jakarta.mail OSGi bundle specversion: 1.6.99.B01 OSGi Bundle-Version: 1.6.99.B01 Maven group ID, artifact ID: com.sun.mail:jakarta.mail Maven version: 1.7.0-B01 jar Extension-Name: jakarta.mail jar Specification-Version: 1.6.99.01 jar Implementation-Version: 1.7.0-B01 - Dependencies If the API definition of a given technology depends on the API of another technology, the API jar file should represent that dependency. Likewise, if the implementation of a given technology depends on the API or implementation of another technology, the implementation jar file should represent that dependency. The dependency should be represented using each of the relevant module technologies: -- Maven dependencies Maven dependencies should be represented in the pom.xml file for the artifact that has the dependency. API jar files should only have dependencies on other API jar file artifacts. Implementation jar files should generally have dependencies on other implementation jar file artifacts. Note that such implementation dependencies might include artifacts not defined by a JCP specification, such as Apache Commons modules. Because versions of Jakarta EE specifications are generally maintained to be upwards compatible, a dependency on an API jar artifact should include a version reference that specifies the minimum version of the dependent technology, as defined by the specification, with no maximum version number, e.g., "[1.6,)". On the other hand, implementations often depend intimately on the implementation details of dependent implementations. The version reference of a dependent implementation might be very specific or open-ended. -- OSGi dependencies We strongly recommend the use of the OSGi Import-Package header to specify dependencies. The version references should be as described above for Maven. ISSUE: We hope to provide more detailed recommendations for OSGi versioning in the future. -- jar extension dependencies The manifest of the API and implementation jar files should be used to specify dependencies on other extensions, using the extension names defined by this document. The mechanism is defined by this document: https://docs.oracle.com/javase/6/docs/technotes/guides/extensions/ Note that specification version references always use a "greater than or equal to" comparison. An API jar should use only Specification-Version references. An implementation jar might also use Implementation-Vendor-Id and Implementation-Version references. While not defined here, we recommend that jar file manifests also include the following attributes: Specification-Vendor, Implementation-Vendor, and Implementation-Vendor-Id. In addition to using the jar extension manifest headers to specify dependencies, the jar Class-Path header should be used. The simple names of the dependent jar files (using the names specified by this document) should be included in the Class-Path header. The Class-Path header of an API jar file should only include other API jar files. The Class-Path header of an implementation jar file might include other implementation jar files. - Non-standalone implementations For technologies that don't define a standalone implementation (e.g., Jakarta Connectors), or for which no standalone implementation is produced (e.g., Jakarta Servlets), we don't define the naming, packaging, or versioning of the implementation artifacts. In general, we would expect the implementation to follow the conventions of the larger project or product in which it is embedded. For example, the Jakarta Connectors and Jakarta Servlet implementation artifacts follow the conventions used by other implementation artifacts that are part of GlassFish. - Source code jar files When licensing allows, we recommend that source code jar files be published to the Maven repository using the Maven convention of: Maven API jar file: ${API_PACKAGE}-api-${SPEC_IMPL_VERSION}-sources.jar Maven impl jar file: ${API_PACKAGE}-${IMPL_VERSION}-sources.jar - Special considerations for GlassFish For technologies that are included in the GlassFish repository, it is sometimes necessary to separate the API definitions from the API implementation, e.g., in order to avoid circular dependencies between modules. In such cases, separate API and implementation jar files may be generated and delivered with GlassFish. These artifacts are not intended to be reused outside of GlassFish, and may have artifact names and version numbers that are specific to GlassFish. If a standalone version of these technologies is also made available, it should follow the rules described in this document. It might be necessary to repackage the artifacts to do so. - Transition Many of our existing artifacts are not following the guidelines above. Switching to these guidelines may disrupt users of current products and thus doing so should be done carefully and with sufficient notification to users. For example, if version 1.6.2 of the Jakarta Mail implementation was previously available at http://repo2.maven.org/maven2/javax/mail, and version 1.6.3 is published at http://repo2.maven.org/maven2/jakarta/mail, users may not notice that a new version is available, or may not be able to find it easily. The Maven relocation feature described at http://maven.apache.org/guides/mini/guide-relocation.html may be used to redirect users to the new location for the artifacts. - Maven hints If a Maven build is set up to produce an implementation jar file as defined above (that includes both the API classes and the implementation classes), an API jar file can be produced using a pom.xml of the following form: <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <parent> <groupId>${IMPL_NAMESPACE}</groupId> <artifactId>all</artifactId> <version>${IMPL_VERSION}</version> </parent> <modelVersion>4.0.0</modelVersion> <groupId>${API_PACKAGE}</groupId> <artifactId>${API_PACKAGE}-api</artifactId> <version>${SPEC_IMPL_VERSION}</version> <packaging>jar</packaging> <name>${API_PACKAGE} API jar</name> <build> <plugins> <plugin> <artifactId>maven-dependency-plugin</artifactId> <executions> <execution> <id>unpack</id> <phase>process-sources</phase> <goals> <goal>unpack</goal> </goals> </execution> </executions> <configuration> <artifactItems> <artifactItem> <groupId>${API_PACKAGE}</groupId> <artifactId>${API_PACKAGE}-api</artifactId> <version>${$IMPL_VERSION}</version> </artifactItem> </artifactItems> <outputDirectory> ${project.build.outputDirectory} </outputDirectory> <includes> javax/**, META-INF/* </includes> </configuration> </plugin> <plugin> <artifactId>maven-jar-plugin</artifactId> <configuration> <finalName>${project.artifactId}</finalName> <archive> <manifestFile> ${project.build.outputDirectory}/META-INF/MANIFEST.MF </manifestFile> </archive> </configuration> </plugin> </plugins> </build> </project> Requirements for publishing to maven central may be found at <https://docs.sonatype.org/display/Repository/Central+Sync+Requirements>. ISSUE: Need Maven example for relocation