我们正在构建包含大量jar的ear-files。其中一些包含persistence.xml文件,这些文件定义了使用
引用其他jar的持久性单元<jar-file>other.jar</jar-file>
现在我们计划将来使用Maven,jar名称现在包含版本号。对于上述机制来说,这是一个巨大的问题:我们需要指定other.jar
,而不是other-1.2.3.jar
。但是在构建jar时无法知道正确的版本号,因为在构造ear时,依赖中介可以用other-1.2.3.jar
替换other-2.3.4.jar
,以便我在jar的persistence.xml中的引用变为无效。
所以我的问题是:在构建大型ear文件时,如何在Maven中正确管理persistence.xml文件?
编辑:
让我试着构建一个小例子,让我的观点更加清晰:
让我们first-ejb-1.0.0.jar
取决于other-1.2.3.jar
和second-ejb-1.0.0.jar
,具体取决于other-2.3.4.jar
。 first-ejb-1.0.0.jar
和second-ejb-1.0.0.jar
都包含带有<jar-file>
条目的persistence.xml。 first-ejb-1.0.0.jar
指向other-1.2.3.jar
,second-ejb-1.0.0.jar
指向other-2.3.4.jar
。到目前为止,非常好。
现在我从first-ejb-1.0.0.jar
和second-ejb-1.0.0.jar
建立一个耳朵。解析了依赖关系,但只有一个other-*.jar
可以包含在耳中。比如,我们的依赖调解选择other-2.3.4.jar
。然后first-ejb-1.0.0.jar
有一个死<jar-file>
条目,指向一个不存在的jar。
答案 0 :(得分:3)
maven-ear-plugin
具有属性fileNameMapping
,您可以通过该属性指定文件名映射以用于EAR文件中包含的所有依赖项。以下值有效standard
,no-version
,full
,no-version-for-ejb
。 standard
表示文件名是artifactId incl。工件的版本。 no-version
表示文件只是没有版本的artifactId。 full
表示文件名是工件的groupId + artifactId +版本。 no-version-for-ejb
表示文件名是artifactId,没有EJB类型的版本。
所以指定耳塞如下:
<plugin>
<artifactId>maven-ear-plugin</artifactId>
<version>2.10.1</version>
<configuration>
<fileNameMapping>no-version</fileNameMapping>
</configuration>
</plugin>
可能适合你。
备选方案2:外部化persistence.xml
另一种方法可能是persistence.xml
外部化。最直接的方法是创建一个包含persistence.xml
的jar并将其放入耳中的lib文件夹中:
EAR +
|- lib +
| |- core-module.jar
| \- persistence-module.jar +
| \- META-INF +
| \- persistence.xml
|- ejb1-module.jar
\- ejb2-module.jar
EJB模块可以是jar存档或展开目录。在上面的设置中,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>
在EAR级别定义的持久性单元通常对应用程序中的所有组件可见。但是,如果EAR中的EJB-JAR,WAR或应用程序jar文件定义了同名的持久性单元,那么在EAR级别定义的该名称的持久性单元将不会对该EJB定义的组件可见 - JAR,WAR或应用程序jar文件,除非持久性单元引用使用持久性单元名称#
语法指定路径名以消除引用的歧义。使用#
语法时,路径名相对于引用应用程序组件jar文件。例如,语法../lib/persistenceUnitRoot.jar#myPersistenceUnit
指的是一个持久性单元,其名称(在persistence.xml
文件的name元素中指定)为myPersistenceUnit
,并且其根的相对路径名称为持久性单位是../lib/persistenceUnitRoot.jar
。
可以通过使用@PersistenceContext(unitName = "../lib/persistenceUnitRoot.jar#myPersistenceUnit")
注释entityManager来指定持久性单元。
答案 1 :(得分:2)
所以,就像你自己说的那样,当你构建EAR时,你的工件已经构建,jar-file
已经定义并且无法更改。因此,有两种选择:
jar-file
必须是特定版本 - 不允许使用其他版本jar-file
可以是任何版本 - 从jar名称<强> 1。严格版
您可以使用single-version range强制Maven仅考虑特定版本的依赖关系:
<dependency>
<groupId>my.company</groupId>
<artifactId>persistence</artifactId>
<!-- require specifically this version -->
<version>[1.0.2]</version>
</dependency>
<强> 2。从jar名称中排除版本
您可以使用任何名称even without version:
将广告添加到EAR <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>
答案 2 :(得分:2)
由于您有 EAR 项目和其他项目,我假设您有一个父项目。
我不完全确定你的意思
但是在构建jar时无法知道正确的版本号,因为在构建耳朵时,依赖中介可以用其他2.3.4.jar替换other-1.2.3.jar
我了解其他在构建 ear 之前不知道其版本(但为什么?)。 您可以执行以下操作:在父项目中,定义一个变量以保存实际的最终版本。
<properties>
<my.final.version>...</my.final.version>
</properties>
显然,应使用您的实际预期值设置 my.final.version 。 然后,将persistence.xml更改为:
<jar-file>other-${my.final.version}.jar</jar-file>
然后,在其他的pom.xml中,添加以下内容:
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
启用过滤告诉maven替换变量。
如果您不想对所有资源进行过滤(出于性能或其他原因),您可能希望对过滤进行微调。在。
下查找包含标记