Ice*_*ras 15 java maven-2 maven-release-plugin
我有这个项目由多个罐子和战争组成的耳朵.我在快照中构建了所有内容,效果很好.然后我为每个项目发布了一个版本,发现罐子和战争的大小与快照略有不同.
比较文件到文件我意识到.class文件都在那里,但略大或稍大,一般不超过40个字节.
我强制编译在Maven中使用此标记使用java 1.5:
<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>
Run Code Online (Sandbox Code Playgroud)
我将此标记用于发布插件:
<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>
Run Code Online (Sandbox Code Playgroud)
可能是发布插件正在1.6或其他编译,解释类大小差异?如果是这样,我可以在1.5中编译发布插件吗?
感谢您的输入.
Luc*_*cas 19
--- SPOILER ALERT ---
简短的回答是,为了将源代码编译为旧版本,您需要同时提供-source选项以及-bootclasspath.看到这篇文章.如果你想编译源到新的版本,你需要设置<source>,<target>,<compilerVersion>,<fork>,和<executable>编译器插件,并设置<jvm>在万无一失的插件...
而现在的故事......
我遇到了同样的问题.事实证明,编译以前的版本可能不如设置<source>和<target>.我的具体情况是我有一个Java 1.7 JDK,我的类与1.7不兼容(他们为我正在实现的接口添加了一个新方法).当我尝试编译它时,编译器给了我一条错误消息,指出我没有实现接口方法.无论如何,我尝试设置编译器插件:
<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>
Run Code Online (Sandbox Code Playgroud)
但是当我运行构建时,我得到了同样的错误.所以我在调试中运行maven并看到了这个:
[INFO] [DEBUG] Command line options:
[INFO] [DEBUG] -d C:\... -nowarn -target 1.6 -source 1.6 -encoding UTF-8
Run Code Online (Sandbox Code Playgroud)
请注意,为简洁起见,...代替实际参数
在输出中.以...开头的消息-d是实际的完整编译参数列表.因此,如果删除-nowarn标志并javac在命令行后粘贴其余标志,则可以看到编译器的实际输出:
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
Run Code Online (Sandbox Code Playgroud)
这将打印出与-source 1.6无法一起设置的方便花花公子警告引导类路径.有点谷歌搜索引发了这篇文章,其中指出:
要使用JDK N中的javac交叉编译到较旧的平台版本,正确的做法是:
- 使用较旧的-source设置.
- 将bootclasspath设置为针对旧平台的rt.jar(或等效项)进行编译.
如果不采取第二步,javac将尽职尽责地使用旧语言规则与新库相结合,这可能导致类文件无法在旧平台上运行,因为可以包含对不存在的方法的引用.
现在引用编译器插件的maven文档给出:
<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>
Run Code Online (Sandbox Code Playgroud)
然后,您可以将其与早期配置结合使用以获得:
<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>
Run Code Online (Sandbox Code Playgroud)
而现在你只需要使${java.home}变量提供给您MVN(通过-D系统属性,或通过普通的旧的环境变量,或者你可以得到真正看中的东西和它在Java 6的个人资料的用户设置).
现在只需运行你的构建,然后去拿一杯冰镇啤酒吧......
----编辑----
最后一件事...... 总是需要在你的bootclasspath中包含rt.jar ,但是,我发现根据具体情况可能需要更多.我必须包含jce.jar(与rt.jar在同一目录中)因为我的应用程序正在进行加密工作.
----编辑2 ----
为了笑容,我尝试了另一个方向.我没有使用Java 7编译为java 6运行maven,而是使用java 6编译java for maven.第一次尝试非常简单:
<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>
Run Code Online (Sandbox Code Playgroud)
基本上,我设置我的<source>和<target>1.7,但这显然是不够的,因为6不能编译7代码.回到编译器插件,实际上有一个示例页面描述了需要做什么.也就是说,您需要<fork>使用java 7关闭新进程<executable>.所以现在我觉得我已经准备好了.是时候开始构建......
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] ------------------------------------------------------------------------
Run Code Online (Sandbox Code Playgroud)
什么是UnsupportedClassVersionError?仔细看看告诉我们它的maven-surefire-plugin失败了.所以我尽力mvn compile而且确定我获得了成功,因为surefire插件从未激发过.所以我跑去mvn -X package注意这个宝石:
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"
Run Code Online (Sandbox Code Playgroud)
好吧,所以它运行java 6.为什么?surefire的文档给出了这样的:
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.
Run Code Online (Sandbox Code Playgroud)
由于我们使用java 6 VM运行mvn,因此需要使用java 6 VM进行单元测试.因此,适当地设置此选项:
<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>
Run Code Online (Sandbox Code Playgroud)
并启动构建......
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
Run Code Online (Sandbox Code Playgroud)
您可以使用 JDK 附带的 javap 实用程序来验证编译类的版本。从命令行:
javap -verbose MyClass
Run Code Online (Sandbox Code Playgroud)
在 javap 的输出中查找大约十行以下的“次要版本”和“主要版本”。
然后使用这个表:
主要次要 Java 平台版本 45 3 1.0 45 3 1.1 46 0 1.2 47 0 1.3 48 0 1.4 49 0 1.5 50 0 1.6
.class 大小差异可能是由于编译版本造成的,也可能是由于其他编译选项造成的,例如使用调试信息进行编译(堆栈跟踪中的行号)。
| 归档时间: |
|
| 查看次数: |
15354 次 |
| 最近记录: |