[英]Version number in jar name - how to handle persistence.xml?
We are building ear-files with a large number of jars. 我们正在制作带有大量罐子的耳朵文件。 Some of them contain persistence.xml files defining persistence units which reference other jars with
其中一些包含persistence.xml文件,用于定义引用其他jar的持久性单元
<jar-file>other.jar</jar-file>
Now we plan to use Maven in the future and jar names now contain version numbers. 现在我们计划将来使用Maven,jar名称现在包含版本号。 This is a huge problem for the mechanism described above: Instead of
other.jar
, we need to specify other-1.2.3.jar
. 这是上述机制,一个巨大的问题:与其
other.jar
,我们需要指定other-1.2.3.jar
。 But the correct version number cannot be known when the jar is built because in the construction of the ear, the dependency mediation could replace other-1.2.3.jar
with other-2.3.4.jar
so that my reference in the persistence.xml of the jar becomes invalid. 但是,当罐子在耳朵的建设,因为建立正确的版本号无法知道,依赖调解可以取代
other-1.2.3.jar
与other-2.3.4.jar
,使我在persistence.xml参考罐子变得无效。
So my question is: How can I manage the persistence.xml files properly in Maven when building a large ear file? 所以我的问题是:在构建大型ear文件时,如何在Maven中正确管理persistence.xml文件?
EDIT: 编辑:
Let me try to construct a small examples to make my point clearer: 让我尝试构建一个小例子,让我的观点更加清晰:
Let us have first-ejb-1.0.0.jar
depending on other-1.2.3.jar
and second-ejb-1.0.0.jar
depending on other-2.3.4.jar
. 让我们得到
first-ejb-1.0.0.jar
取决于other-1.2.3.jar
和second-ejb-1.0.0.jar
取决于other-2.3.4.jar
。 Both first-ejb-1.0.0.jar
and second-ejb-1.0.0.jar
contain a persistence.xml with a <jar-file>
entry. first-ejb-1.0.0.jar
和second-ejb-1.0.0.jar
都包含带有<jar-file>
条目的persistence.xml。 first-ejb-1.0.0.jar
points to other-1.2.3.jar
and second-ejb-1.0.0.jar
points to other-2.3.4.jar
. first-ejb-1.0.0.jar
指向other-1.2.3.jar
, second-ejb-1.0.0.jar
指向other-2.3.4.jar
。 So far, so good. 到现在为止还挺好。
Now I build an ear from first-ejb-1.0.0.jar
and second-ejb-1.0.0.jar
. 现在我从
first-ejb-1.0.0.jar
和second-ejb-1.0.0.jar
构建一个ear。 The dependencies are resolved, but only one of the other-*.jar
can be included in the ear. 解析了依赖关系,但只有一个
other-*.jar
可以包含在耳中。 Say, our dependency mediation chooses other-2.3.4.jar
. other-2.3.4.jar
说,我们的依赖调解选择other-2.3.4.jar
。 Then first-ejb-1.0.0.jar
has a dead <jar-file>
entry, pointing to a non-existent jar. 然后
first-ejb-1.0.0.jar
有一个死<jar-file>
条目,指向一个不存在的jar。
The maven-ear-plugin
has a property fileNameMapping
by which you can specify the file name mapping to use for all dependencies included in the EAR file. maven-ear-plugin
有一个属性fileNameMapping
,您可以通过该属性指定文件名映射以用于EAR文件中包含的所有依赖项。 The following values are valid standard
, no-version
, full
, no-version-for-ejb
. 以下值是有效的
standard
, no-version
, full
, no-version-for-ejb
。 The standard
means the filename is the artifactId incl. standard
意味着文件名是artifactId incl。 the version of the artifact. 工件的版本。 The
no-version
means the files is only the artifactId without the version. no-version
意味着文件只是没有版本的artifactId。 The full
means the filename is the groupId+artifactId+version of the artifact. full
表示文件名是工件的groupId + artifactId +版本。 The no-version-for-ejb
means the filename is the artifactId without the version in case of EJB type. no-version-for-ejb
意味着文件名是artifactId,没有EJB类型的版本。
So specifying the ear plugin as follows: 所以指定耳塞如下:
<plugin>
<artifactId>maven-ear-plugin</artifactId>
<version>2.10.1</version>
<configuration>
<fileNameMapping>no-version</fileNameMapping>
</configuration>
</plugin>
might do the trick for you. 可能会为你做的伎俩。
Alternative 2: Externalize persistence.xml 备选方案2:外部化persistence.xml
An alternative approach could be to externalize the persistence.xml
. 另一种方法可能是外
persistence.xml
。 The most straight forward approach would be to create a jar containing the persistence.xml
and put it into the lib folder of the ear: 最直接的方法是创建一个包含
persistence.xml
的jar并将其放入ear的lib文件夹中:
EAR +
|- lib +
| |- core-module.jar
| \- persistence-module.jar +
| \- META-INF +
| \- persistence.xml
|- ejb1-module.jar
\- ejb2-module.jar
EJB modules may be either jar archives or exploded directories. EJB模块可以是jar存档或展开目录。 In the setup as above the
persistence.xml
would look like: 在上面的设置中,
persistence.xml
看起来像:
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0">
<persistence-unit name="my-persistence-unit">
<!-- Note: it's relative to `persistence-module.jar` file location in EAR -->
<jar-file>../ejb1-module.jar</jar-file>
<jar-file>../ejb2-module.jar</jar-file>
....
</persistence-unit>
</persistence>
A persistence unit that is defined at the level of the EAR is generally visible to all components in the application. 在EAR级别定义的持久性单元通常对应用程序中的所有组件可见。 However, if a persistence unit of the same name is defined by an EJB-JAR, WAR, or application jar file within the EAR, the persistence unit of that name defined at EAR level will not be visible to the components defined by that EJB-JAR, WAR, or application jar file unless the persistence unit reference uses the persistence unit name
#
syntax to specify a path name to disambiguate the reference. 但是,如果EAR中的EJB-JAR,WAR或应用程序jar文件定义了同名的持久性单元,那么在EAR级别定义的该名称的持久性单元将不会对该EJB定义的组件可见 - JAR,WAR或应用程序jar文件,除非持久性单元引用使用持久性单元名称
#
语法指定路径名以消除引用的歧义。 When the #
syntax is used, the path name is relative to the referencing application component jar file. 使用
#
语法时,路径名相对于引用应用程序组件jar文件。 For example, the syntax ../lib/persistenceUnitRoot.jar#myPersistenceUnit
refers to a persistence unit whose name, as specified in the name element of the persistence.xml
file, is myPersistenceUnit
and for which the relative path name of the root of the persistence unit is ../lib/persistenceUnitRoot.jar
. 例如,语法
../lib/persistenceUnitRoot.jar#myPersistenceUnit
引用一个持久性单元,其名称(在persistence.xml
文件的name元素中指定)是myPersistenceUnit
并且其根的相对路径名称为持久性单元是../lib/persistenceUnitRoot.jar
。
The persistence unit can be specified by annotating the entityManager with @PersistenceContext(unitName = "../lib/persistenceUnitRoot.jar#myPersistenceUnit")
. 可以通过使用
@PersistenceContext(unitName = "../lib/persistenceUnitRoot.jar#myPersistenceUnit")
注释entityManager来指定持久性单元。
So, like you said yourself, by the time you are building EAR, your artifact is built, the jar-file
is already defined and cannot be changed. 所以,就像你自己说的那样,当你构建EAR时,你的工件就被构建了,
jar-file
已经被定义并且无法更改。 There are, therefore, two options: 因此,有两种选择:
jar-file
must be a specific version - do not allow other versions to be used jar-file
必须是特定版本 - 不允许使用其他版本 jar-file
can be any version - exclude version from jar name jar-file
可以是任何版本 - 从jar名称中排除版本 1. Strict version 1.严格的版本
You can force Maven to consider only a specific version of dependency by using single-version range : 您可以通过使用单版本范围强制Maven仅考虑特定版本的依赖关系:
<dependency>
<groupId>my.company</groupId>
<artifactId>persistence</artifactId>
<!-- require specifically this version -->
<version>[1.0.2]</version>
</dependency>
2. Exclude version from jar name 2.从jar名称中排除版本
You can add jars to EAR with any name, even without version : 您可以使用任何名称向EAR添加jar, 即使没有版本 :
<build>
<plugins>
<plugin>
<artifactId>maven-ear-plugin</artifactId>
<version>2.10.1</version>
<configuration>
<modules>
<ejbModule>
<groupId>my.company</groupId>
<artifactId>persistence</artifactId>
<!-- rename artifact in ear -->
<bundleFileName>persistence.jar</bundleFileName>
</ejbModule>
</modules>
</configuration>
</plugin>
</plugins>
</build>
Since you have a EAR project and an Other project, I assume you have a parent project. 由于您有一个EAR项目和一个其他项目,我假设您有一个父项目。
I'm not entirely sure what you mean by 我不完全确定你的意思
But the correct version number cannot be known when the jar is built because in the construction of the ear, the dependency mediation could replace other-1.2.3.jar with other-2.3.4.jar
但是在构建jar时无法知道正确的版本号,因为在构建耳朵时,依赖调解可以用其他2.3.4.jar替换other-1.2.3.jar
I understand that other does not know its version until ear is built (but why?). 我知道其他人不知道它的版本,直到建立耳朵 (但为什么?)。 You can do the following: in the parent project, define a variable to hold the actual final version.
您可以执行以下操作:在父项目中,定义一个变量以保存实际的最终版本。
<properties>
<my.final.version>...</my.final.version>
</properties>
Obviously, my.final.version should be set with your actual expected value. 显然, my.final.version应该用您的实际预期值设置。 Then, Change persistence.xml to this:
然后,将persistence.xml更改为:
<jar-file>other-${my.final.version}.jar</jar-file>
Then, in other 's pom.xml, add this: 然后,在其他的pom.xml中,添加:
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
Enabling filtering tells maven to replace variables. 启用过滤告诉maven替换变量。
You may wish to fine tune the filtering if you don't want to do filtering on all resources (for performance or what ever other reason). 如果您不想对所有资源进行过滤(出于性能或其他原因),您可能希望对过滤进行微调。 Look for the tag includes under .
寻找标签包括下。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.