简体   繁体   English

jar名称中的版本号 - 如何处理persistence.xml?

[英]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.jarother-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.jarsecond-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.jarsecond-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.jarsecond-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.jarsecond-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 . 以下值是有效的standardno-versionfullno-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: 因此,有两种选择:

  1. jar-file must be a specific version - do not allow other versions to be used jar-file必须是特定版本 - 不允许使用其他版本
  2. 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM