如何修改 mvn.cmd 以在 MANIFEST.MF 文件中获取正确的 jdk 构建版本

How to modify mvn.cmd to get the correct jdk build version in MANIFEST.MF file

我在我的机器上安装了 2 个版本的 java,1.7 和 1.8。 为了构建我的 java 项目,我使用的是 maven 3.5.0.

有些情况下我必须使用 java 1.7 构建我的 java 项目, 所以我将 %JAVA_HOME% 环境变量从 "C:\Program Files\Java\jdk1.8.0_131".

更改为 "C:\Program Files\Java\jdk1.7.0_80"

然后我想如果我能做到的话,pom.xml 确定 java 的版本,应该根据哪个版本构建项目。

一开始我的pom.xml是这样的

<plugins>
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <configuration>
            <source>1.7</source>
            <target>1.7</target>
        </configuration>
    </plugin>
...
</plugins>

如您所见,有 <source><target> 标签,但此标签不适用于 java 1.7、1.8,也许它适用于早期版本。

所以我不得不在 Mavens "settings.xml" 和 "pom.xml" 文件中进行一些更改:

settings.xml

<profiles>
    <profile>
        <id>compiler</id>
          <properties>
            <JAVA_1_7_HOME>C:\Program Files\Java\jdk1.7.0_80\bin\javac</JAVA_1_7_HOME>
            <JAVA_1_8_HOME>C:\Program Files\Java\jdk1.8.0_131\bin\javac</JAVA_1_8_HOME>
          </properties>
    </profile>
</profiles>

<activeProfiles>
        <activeProfile>compiler</activeProfile>
</activeProfiles>

pom.xml

<plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
                <source>1.7</source>
                <target>1.7</target>
                <executable>${JAVA_1_7_HOME}</executable>
                <verbose>true</verbose>
                <fork>true</fork>               
            </configuration>
        </plugin>
...
</plugins>

然后使用 mvn install 进行构建,它成功了!!!如果我将可执行文件更改为 ${JAVA_1_8_HOME} ,则生成的 jar 文件的大小会发生变化。

但是 MANIFEST.MF 中有一个大问题。 JDK 的构建版本是 1.8.0_161,所以 MANIFEST.MF 会骗人,谁想要找出构建 jdk 版本。

原因是 Maven(mvn.cmd 文件)查找 %JAVA_HOME% 并采用 java 的路径。如果环境中没有 %JAVA_HOME% 变量,它采用默认系统 java -版本,在我的例子中是 1.8.0_161 (JRE 版本).

这里是 mvn.cmd 代码片段

@REM ==== START VALIDATION ====
if not "%JAVA_HOME%"=="" goto OkJHome
for %%i in (java.exe) do set "JAVACMD=%%~$PATH:i"
goto checkJCmd

挑战来了

如何告诉mvn.cmd它是由写在pom.xml中的java7构建的?

如何让 mvn.cmd 在 MANIFEST.MF 文件中写入正确的构建 jdk?

我刚刚尝试使用 maven-archiver 插件强制自定义 MANIFEST.MF 并以某种方式确定 "Build-Jdk" 条目。但它似乎总是覆盖 java 版本。如果您想尝试一下,请查看 https://maven.apache.org/shared/maven-archiver/examples/manifestFile.html

我不认为更改 maven.cmd 可以使此脚本了解项目的特殊性。

如果重点是避免在某些构建之前手动更改 JAVA_HOME,也许您只需要为 maven 制作一个包装器批处理文件 引用你的 jdk1.7:

SET "JAVA_HOME=C:\Program Files\Java\jdk1.7.0_80"
mvn.cmd %*

将这个批处理文件另存为 mvn_j7.bat 在你的 [MAVEN_HOME]\bin folder.Then 你可以 运行 它在任何地方,就像下面的例子一样:

mvn_j7 clean package

这是解决方案,如何修复 MANIFEST.MF 文件中不正确的 JDK 版本。此修复永远不会让您错误地构建项目(如果您的配置正确)。

首先需要从环境 PATH 中删除 Java link C:\Program Files\Java\jdk1.7.0_80\bin%java_home%\bin

然后你必须在 maven settings.xml 文件中添加新的配置文件

settings.xml

<profile>
  <id>buildByJava7</id>
  <activation>
    <property>
      <name>java</name>
      <value>7</value>
    </property>
  </activation>
  <properties>
    <java-version>1.7</java-version>
    <java-1.7>C:\Program Files\Java\jdk1.7.0_80\bin\javac</java-1.7>
    <jdk>1.7.0_80</jdk>
    <wsimport>C:\Program Files\Java\jdk1.7.0_80\bin\wsimport.exe</wsimport>
  </properties>
</profile>

<profile>
  <id>buildByJava8</id>
  <activation>
    <property>
      <name>java</name>
      <value>8</value>
    </property>
  </activation>
  <properties>
     <java-version>1.8</java-version>
     <java-1.8>C:\Program Files\Java\jdk1.8.0_131\bin\javac</java-1.8>
     <jdk>1.8.0_131</jdk>
     <wsimport>C:\Program Files\Java\jdk1.8.0_131\bin\wsimport.exe</wsimport>
  </properties>
</profile>

如您所见,有全局属性 <java-version>, <java-1.8>, <jdk>, <wsimport>。您可以使用 mvn -Djava=7mvn -Djava=8 命令

激活配置文件

现在你要这样改Pom.xml

pom.xml

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-compiler-plugin</artifactId>
  <configuration>
    <verbose>true</verbose>
    <fork>true</fork>
    <source>${java-version}</source>  <!-- java compile version -->
    <target>${java-version}</target>  <!-- java compile version -->
    <executable>${java-1.8}</executable>  <!-- ..\bin\javac.exe file path -->
  </configuration>
</plugin>

.....

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-jar-plugin</artifactId>
  <configuration>
    <archive>
      <manifest>
        <addClasspath>true</addClasspath>
        <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
      </manifest>
      <manifestEntries>
        <Build-Jdk>${jdk}</Build-Jdk>  <!-- jdk version to set in manifest.mf file -->
      </manifestEntries>
    </archive>
  </configuration>
</plugin>

...

如果您使用 wsimport 从 *wsdl 生成 类,则必须添加具有 wsimport.exe 文件路径的可执行文件。 请预见,如果您在 %PATH%

中有 java link,这将不起作用
<plugin>
  <groupId>org.codehaus.mojo</groupId>
  <artifactId>jaxws-maven-plugin</artifactId>
  <executions>
    <execution>
      <goals>
        <goal>wsimport</goal>
      </goals>
      <configuration>
        <wsdlDirectory>${basedir}/src/main/resources/wsdl/app</wsdlDirectory>
        <packageName>ge.jibo.app.client</packageName>
        <sourceDestDir>${basedir}/target/generated-sources</sourceDestDir>
        <keep>true</keep>
        <bindingFiles>
          <bindingFile>${basedir}/src/main/resources/wsdl/app/binding.xml</bindingFile>
          <bindingFile>${basedir}/src/main/resources/wsdl/app/jaxb-binding.xml</bindingFile>
        </bindingFiles>
        <verbose>true</verbose>
        <executable>${wsimport}</executable>  <!-- ...\bin\wsimport.exe file path -->
      </configuration>
    </execution>
  </executions>
</plugin>

修改后你可以运行命令mvn -Djava=8 clean package

此命令将激活 buildByJava8 配置文件。 pom.xml 将从配置文件中获取所有 java 版本和 java/wsimport 路径,并且所有内容都将成功正确地编译和构建。