Maven发布插件:指定java编译器版本 [英] Maven release plugin: specify java compiler version

查看:140
本文介绍了Maven发布插件:指定java编译器版本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这个项目由多个罐子和战争组成的耳朵。我在快照中构建了所有内容并且效果很好。然后我为每个项目发布了一个版本,发现罐子和战争的大小与快照的大小略有不同。

I have this project made of multiple jars and war to make an ear. I build everything in snapshot and it works great. Then I made a release for every single project and saw that the jars and the war were slightly different in size than the snapshot ones.

比较文件到文件我意识到.class文件都存在,但略大或稍大,一般不超过40个字节。

Comparing file to file I realized that the .class files were all there, but slightly larger or bigger, nothing more than 40 bytes generally.

我强制编译在Maven中使用此标记使用java 1.5:

I force compilation to use java 1.5 using this tag in Maven:

<build>
    <pluginManagement>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.0.2</version>
                <configuration>
                    <source>1.5</source>
                    <target>1.5</target> 
                </configuration>

我在发布插件中使用此标记:

I use this tag for the release plugin:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-release-plugin</artifactId>
    <version>2.0</version>
    <configuration>
        <releaseProfiles>release</releaseProfiles>
        <goals>deploy</goals>
    </configuration>
</plugin>

可能是发布插件正在1.6或其他编译,解释类的大小差异?如果可以的话,我可以让发布插件在1.5中编译吗?

Could it be that the release plugin is compiling in 1.6 or other, explaining the classes size difference ? If so can I make the release plugin compile in 1.5 ?

感谢您的输入。

推荐答案

--- SPOILER ALERT ---

简短的回答是为了将源代码编译为旧版本版本,您需要提供 -source 选项以及 -bootclasspath 。请参阅本文。如果您想将源代码编译为较新版本,则需要设置< source> < target> < compilerVersion> < fork> ,以及< executable> 关于编译器插件,在surefire插件上设置< jvm> ...

The short answer is that in order to compile source to an older version, you need to supply both the -source option as well as the -bootclasspath. See this article. And if you want to compile source to a newer version, you need to set <source>, <target>, <compilerVersion>, <fork>, and <executable> on the compiler plugin, and set <jvm> on the surefire plugin...

现在的故事......

我遇到了同样的问题。事实证明,编译以前的版本可能不如设置< source> < target> 一样简单。我的具体情况是我有一个Java 1.7 JDK,而我的类与1.7 不兼容(他们为我正在实现的接口添加了一个新方法)。当我尝试编译它时,编译器给了我一条错误消息,指出我没有实现接口方法。无论如何,我尝试设置编译器插件:

I ran into the same problem. It turns out that compiling a previous version may not be as easy as setting <source> and <target>. My specific case is that I have a Java 1.7 JDK and I my class has an incompatibility with 1.7 (they added a new method to an interface that I am implementing). When I tried to compile it, the compiler gave me an error message stating that I had not implemented the interface method. Anyway, I tried setting the compiler plugin:

  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>2.3.2</version>
    <configuration>
      <source>1.6</source>
      <target>1.6</target>
      <encoding>UTF-8</encoding>
    </configuration>
  </plugin>

但是当我运行构建时,我得到了同样的错误。所以我在调试中运行maven并看到了这个:

but when I ran the build, I got the same error. So I ran maven in debug and saw this:

[INFO] [DEBUG] Command line options:
[INFO] [DEBUG] -d C:\... -nowarn -target 1.6 -source 1.6 -encoding UTF-8

请注意,为简洁起见,......代替实际参数

输出中。以 -d 开头的消息是实际的完整编译参数列表。因此,如果您删除 -nowarn 标志并在命令行上粘贴其余的 javac ,您可以看到实际编译器的输出:

in the output. The message starting with -d is the actual full compile argument list. So, if you remove the -nowarn flag and paste the rest after javac on the command line you can see the actual output from the compiler:

javac -d C:\... -target 1.6 -source 1.6 -encoding UTF-8
warning: [options] bootstrap class path not set in conjunction with -source 1.6

这打印出与-source 1.6 一起设置的方便花花公子 bootstrap类路径。有点谷歌搜索显示这篇文章,其中说明:

This prints out the handy-dandy warning bootstrap class path not set in conjunction with -source 1.6. A little googling on that turns up this article which states:


要使用JDK N的javac交叉编译到较旧的平台
版本,正确的做法是:

To use javac from JDK N to cross-compiler to an older platform version, the correct practice is to:


  • 使用旧的-source设置。

  • 设置bootclasspath以针对旧平台的rt.jar(或等效项)进行编译。

如果不采取第二步,javac将尽职尽责地使用旧的
语言规则与新库结合使用导致
类文件在旧版平台上无效,因为可以包含对
不存在的方法的引用。

If the second step is not taken, javac will dutifully use the old language rules combined with new libraries, which can result in class files that do not work on the older platform since references to non-existent methods can get included.

现在引用 maven文档编译器插件 giv es:

Now referencing the maven documentation for the compiler plugin gives:

  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>2.5.1</version>
    <configuration>
      <compilerArguments>
        <verbose />
        <bootclasspath>${java.home}\lib\rt.jar</bootclasspath>
      </compilerArguments>
    </configuration>
  </plugin>

然后您可以将其与之前的配置结合使用:

Which you can then combine with your earlier configuration to get:

  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>2.3.2</version>
    <configuration>
      <source>1.6</source>
      <target>1.6</target>
      <encoding>UTF-8</encoding>
      <bootclasspath>${java.home}\lib\rt.jar</bootclasspath>
    </configuration>
  </plugin>

现在你只需要制作 $ {java.home} 你的mvn可用的变量(通过-D系统属性,或通过普通的旧环境变量,或者你可能真的很喜欢它并把它放在用户设置的java 6配置文件中)。

And now you just need to make the ${java.home} variable available to your mvn (through -D system properties, or through plain old environment variables, or you could get really fancy and stuff it in a java 6 profile in your user settings).

现在只需运行你的构建,然后去拿一杯冰镇啤酒吧...

Now just run your build and go grab a cold beer while it chugs away...

----编辑 - -

---- EDIT ----

最后一件事......在你的bootclasspath中包含rt.jar是总是,但是,我发现可能需要更多根据具体情况而定。我必须包含jce.jar(与rt.jar在同一目录中),因为我的应用程序正在进行加密工作。

One last thing... Including rt.jar in your bootclasspath is always required, however, I discovered that more may be needed on a case by case basis. I had to include jce.jar (in the same directory as rt.jar) because my app was doing crypto work.

----编辑2 ----

---- EDIT 2 ----

对于笑容,我尝试了另一个方向。我没有使用Java 7编译为java 6运行maven,而是使用Java 6编译java 7运行maven。第一次尝试非常简单:

For grins, I tried it the other direction. Instead of running maven with java 7 compiling for java 6, I ran maven with java 6 compiling for java 7. The first attempt is pretty straight forward:

  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>2.5.1</version>
    <configuration>
      <source>1.7</source>
      <target>1.7</target>
      <fork>true</fork>
      <verbose>true</verbose>
      <compilerVersion>1.7</compilerVersion>
      <executable>${JAVA_7_HOME}/bin/javac</executable>
      <encoding>UTF-8</encoding>
    </configuration>
  </plugin>

基本上,我设置< source> < target> 到1.7,但这显然是不够的,因为6不能编译7代码。回到编译器插件,实际上是示例页面描述了需要完成的工作。也就是说,您需要使用java 7 < executable> 关闭新进程的< fork> 。所以现在我觉得我已经准备好了。是时候启动构建...

Basically, I set my <source> and <target> to 1.7, but that clearly would not be enough because 6 cant compile 7 code. So back to the compiler plugin, there is actually an example page describing what needs to be done. Namely, you need to <fork> off a new process using the java 7 <executable>. So now I think I'm all set. Time to fire up the build...

C:\Projects\my-project>mvn package
...
Caused by: java.lang.UnsupportedClassVersionError: mypackage.StupidTest : Unsup
ported major.minor version 51.0
...
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------

什么是UnsupportedClassVersionError?仔细看看告诉我们它的maven-surefire-plugin失败了。所以我尝试只需 mvn编译并确定我获得了成功,因为surefire插件永远不会启动。所以我运行 mvn -X package 并注意这个gem:

What the heck is UnsupportedClassVersionError? A closer look tells us its the maven-surefire-plugin that is failing. So I try just mvn compile and sure enough I get a success as the surefire plugin never fired up. So I run mvn -X package and notice this gem:

Forking command line: cmd.exe /X /C ""C:\Program Files\Java\jdk1.6.0_29\jre\bin\
java" -jar C:\Projects\my-project\target\surefire\surefirebooter2373372991878002
398.jar C:\Projects\my-project\target\surefire\surefire1861974777102399530tmp C:
\Projects\my-project\target\surefire\surefire4120025668267754796tmp"

好的,所以它的运行java 6.为什么? surefire的文档给出了:

Ok, so its running java 6. Why? The documentation for surefire gives this:

jvm:
Option to specify the jvm (or path to the java executable) to use with the forking 
options. For the default, the jvm will be a new instance of the same VM as the one 
used to run Maven. JVM settings are not inherited from MAVEN_OPTS.

由于我们使用java 6 VM运行mvn,因此需要使用java 6 VM进行单元测试。因此,适当地设置此选项:

Since we ran mvn with a java 6 VM its forking a java 6 VM for its unit tests. So setting this option appropriately:

  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.12</version>
    <configuration>
      <jvm>${JAVA_7_HOME}/bin/java</jvm>
    </configuration>
  </plugin>

并启动构建......

And firing up the build...

[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------

这篇关于Maven发布插件:指定java编译器版本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆