如何在maven中构建两个不同的ear,在java6和java11中使用相同的java文件,在两个java版本中使用不同的jar?

bqjvbblv  于 2021-07-06  发布在  Java
关注(0)|答案(2)|浏览(425)

我的项目目前在ant中,我们想迁移到maven。我们必须为不同的服务器同时支持Java6和Java11构建(我们的代码库与Java6和更高版本兼容)。Java6使用旧的jar文件,而Java11使用新的jar文件。我们想用java6和java11以及它们自己的jar集来编译这个项目(最终构建为两个不同的ear)是否可以在maven中实现这一点,如果可以,那么如何实现?
编辑:我想说清楚,我没有需要Java7和更高版本来编译的代码。我的代码库如果完全兼容Java6和更高版本。我只需要用具有较新依赖项的Java11编译它,以便在较新版本的服务器上运行它,同时支持Java6用于旧服务器,因此一个ear使用Java6,另一个ear使用Java11。当我们的所有客户都迁移到新服务器时,我们最终将只支持Java11。

4szc88ey

4szc88ey1#

我会选择一个多模块项目,其中包含两个用于两个耳朵的模块,另外还有用于您要构建的jar的模块。
然后您可以将java版本设置为一个ear中的6,另一个ear中的11。

3j86kqsm

3j86kqsm2#

首先你需要不同的编译器。向后兼容性有一个限制。据我所知,oraclejdk支持当前的两个主要版本。因此jdk 11 javac可以编译jdk 8,包括第一个片段,因此——我假设——是这样的:

<properties>
  <java.version>11</java.version>
</properties>

每个(简单)pom.xml只能发生一次此设置,因为它会影响 maven-compiler-plugin 设置源和目标。我再次假设您有一个带有jdk6代码的源目录和另一个带有jdk11代码的源目录。您的目标是将所有jdk6源代码以兼容的方式绑定到一个ear。同时,您的jdk 11源代码最终位于不同的ear中,并且必须类似于jdk 11字节码。
为jdk8目标编译jdk11源代码是完全不同的—仍然与jdk6vm不兼容。我还假设,仅通过编译器将JDK11源代码转换为JDK6字节码既不需要也不容易。
接下来我假设在类路径中至少有一个共享元素。它可以是您自己的api jar或外部库。这样的依赖最终会导致 dependencyManagement 所谓的父pom。这与包含所有模块定义的pom相同。
第三,需要定义groupid和各种artifactid。我强烈建议您至少在artifactid中表达jdk亲和力。然后可以基于jdk关联来表示依赖关系。skeleton(parent)pom.xml可能如下所示:

<project>
  <groupId>com.stackoverflow</groupId>
  <artifactId>sample-cross-release</artifactId>
  <version>1.0.0-SNAPSHOT</version>

  <modules>
    <module>sample-cross-release-api</module>
    <module>sample-cross-release-source6</module>
    <module>sample-cross-release-source11</module>
    <module>sample-cross-release-war6</module>
    <module>sample-cross-release-war11</module>
    <module>sample-cross-release-ear6</module>
    <module>sample-cross-release-ear11</module>
  </modules>

  <dependencyManagement>
    <dependencies>
      <dependency><!-- necessary for 6 and 11 source/ WAR/ EAR -->
        <groupId>com.stackoverflow</groupId>
        <artifactId>sample-cross-release-api</artifactId>
        <version>${project.version}</version>
      <dependency>
      <dependency><!-- only 6 is shown, 11 looks the similar -->
        <groupId>com.stackoverflow</groupId>
        <artifactId>sample-cross-release-sources6</artifactId>
        <version>${project.version}</version>
      <dependency>
      <dependency><!-- only 6 is shown, 11 looks the similar -->
        <groupId>com.stackoverflow</groupId>
        <artifactId>sample-cross-release-war6</artifactId>
        <version>${project.version}</version>
      <dependency>
    </dependencies>
  </dependencyManagement>
</project>

我省略了来源和战争部分。但它有一个 dependencysample-cross-release-sources6 还有-api。ear的pom.xml如下所示:

<project>
  <groupId>com.stackoverflow</groupId>
  <artifactId>sample-cross-release-ear11</artifactId>
  <version>1.0.0-SNAPSHOT</version>

  <parent>
    <groupId>com.stackoverflow</groupId>
    <artifactId>sample-cross-release</artifactId>
    <version>1.0.0-SNAPSHOT</version>
  </parent>

  <properties>
    <java.version>11</java.version>
  </properties>

  <dependencies>

    <dependency><!-- does not need version, determined by parent -->
      <groupId>com.stackoverflow</groupId>
      <artifactId>sample-cross-release-api</artifactId>
    <dependency>

    <dependency><!-- does not need version, determined by parent -->
      <groupId>com.stackoverflow</groupId>
      <artifactId>sample-cross-release-war6</artifactId>
    <dependency>

    <!-- other dependencies, like logging, persistence... -->
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>${maven-compile.version}</version>
        <configuration>
            <source>${java.version}</source>
            <target>${java.version}</target>
        </configuration>
      </plugin>

    </plugins>
  </build>
</project>

在文件系统中,项目结构如下所示:

|
+-- pom.xml (parent)
+-- sample-cross-release-api
|    +-- pom.xml
|    +-- src/main/java
|    +-- src/main/resources
|    ...
...
+-- sample-cross-release-ear11
     +-- pom.xml
     ...

最后,我建议您使用完全独立的jdk6和jdk11代码库/projects/pom.xml-s。不要将它们与父pom合并。一旦您试图为不同的jdk/工具链设置(maven-)支持发布插件的概要文件,您就会陷入依赖地狱。它可能适用于简单的情况。一旦引入静态代码分析、surefire/failsafe和可能的war-and-ear创建,它就会崩溃(我假设一个jdk6 ear是用一个匹配的jee依赖项构建的,它不同于jdk11的jee依赖项。这反过来又会强制使用兼容的maven插件(每个jdk不同)
而且你永远不会知道:在jdk11上运行的应用服务器会禁止第三方库中的反射访问,而第三方库最终会出现在你11的ear类路径中。从一开始就注意安全,将不同的jdk分开,仔细检查两次。
为了简洁起见,我省略了:
可传递依赖项/编写pom的良好风格
maven enforcer插件具有可复制的构建
war-maven和ear-maven插件的使用,因为它们在jdk-6和jdk-11的版本之间在如何设置类路径上有很大的不同
使用工具链使所有开发人员都有一个共同的平台,可以扩展到构建节点
关于jdeps的建议部分是因为maven插件,部分是因为对多版本jar的处理(这将在jdk11依赖项中显示)
允许命令行开关改变构建行为的maven配置文件
通过maven发布,介绍了基于jdk、maven和scm的有趣怪癖。
静态代码分析,pmd是在这个设置中运行的最灵活的方法之一,即使对于两个jdk都有相同的规则集,而其他的规则集可能不太容易(coverity,sonarqube,cast,…)
安全检查,组织。owasp:dependency-check-maven will 在jdk6分支中触发很多警告,一些库不再为这个目标jdk进化
通常情况下,父pom包含很多 dependencyManagement 以及 pluginManagement 因此,所有模块pom都可以省略版本和详细配置。您的方法与此相反,强制jdk6分支和jdk11分支通过同一个父级。它总是从父级强制到模块上,后者不能更改或选择。
如果从ant到maven之间没有真正的权衡,那就不要这么做。maven需要很多契约,特别是当涉及到文件系统布局和工件内容时——要构建一个war/ear,你要么需要遵循规则,要么需要大量的插件配置。

相关问题