接手了一个项目,里面的代码依赖rt.jar包中的com.sun.image.codec.jpeg.JPEGCodec。
按照Sun的官方解释:类似的接口是Sun为实现JDK功能的私有API,非公开的。在JDK1.7之前的版本,利用sun自带的javac命令是可以编译有此引用的代码的。为了规范API使用,提供了公开的imageio类来代替JPEGCodec的功能,为了屏蔽开发人员继续使用私有API,在JDK1.7版本中用javac命令去编译代码会报类似的错误:com.sun.image.codec.jpeg.JPEGCodec does't exist,但是基于以前版本编译的代码在JDK1.7中还是可以运行的。在后续的JDK版本中肯能会彻底删除私有API。
现在我们常用的JDK都是1.7版本以上了,为了能够通过编译,我们在pom文件中添加了以下支持:
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.1</version>
<configuration>
<source>1.5</source>
<target>1.5</target>
<encoding>UTF-8</encoding>
<compilerArguments>
<verbose />
<bootclasspath>${env.JAVA_HOME}\jre\lib\rt.jar;${env.JAVA_HOME}\jre\lib\jce.jar</bootclasspath>
</compilerArguments>
</configuration>
<dependencies>
<dependency>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-compiler-javac</artifactId>
<version>1.8.1</version>
</dependency>
</dependencies>
</plugin>
在Eclipse中利用maven插件进行编译时通过,但是如果直接利用mvn clean install 进行打包还是会报,NoClassFound:com.sun.image.codec.jpeg.JPEGCodec 的错误。原来在Eclipse中利用maven进行编译时,采用的javac插件是Eclipse自己的,对上述jar进行访问时没有限制,可以进行访问。但是利用jdk中javac进行编译时,是不能访问上述jar包的。
思考了一下,jdk中的javac是否只对JAVA_HOME中上述jar包不能访问呢?将上述两个jar包拷贝到其他目录,增加本地依赖:
<dependency>
<groupId>com.sun</groupId>
<artifactId>rt</artifactId>
<scope>system</scope>
<systemPath>d:/rt.jar</systemPath>
</dependency>
编译通过,但是有个问题,当环境发生变化时,例如想在linux服务上直接编译代码时,需要修改systemPath的值,所以不具备可操作性。后来想到Eclipse中javac可以访问JAVA_HOME中的jar包,是否可以替换maven中compiler插件的javac依赖呢:
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.1</version>
<configuration>
<compilerId>eclipse</compilerId>
<source>1.5</source>
<target>1.5</target>
<encoding>UTF-8</encoding>
</configuration>
<dependencies>
<dependency>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-compiler-eclipse</artifactId>
<version>2.4</version>
</dependency>
</dependencies>
</plugin>
本地依赖换成:
<dependency>
<groupId>com.sun</groupId>
<artifactId>rt</artifactId>
<scope>system</scope>
<systemPath>${env.JAVA_HOME}\jre\lib\rt.jar;</systemPath>
</dependency>
编译通过,终于搞定。
但是最终的解决方案还是放弃使用sun的私有api,利用公开api进行替换