问题
项目中原图片压缩方式为:
FileOutputStream newimage=new FileOutputStream(img_midname); //输出到文件流
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(newimage);
JPEGEncodeParam jep=JPEGCodec.getDefaultJPEGEncodeParam(tag);
/* 压缩质量 */
jep.setQuality(per, true);
encoder.encode(tag, jep);
使用maven进行打包时会报错(程序包com.sun.image.codec.jpeg不存在),如下:
原因
按照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。
javac在编译代码时,会尝试从rt.jar中找寻对应的类文件,他会默认从对应的符号表文件ct.sym (同样在jre/lib/下)中查找该类是否存在,由于ct.sym中删除了部分rt.jar中的类,包括com.sun.image.codec.jpeg,因此导致编译报错。
在Eclipse中利用maven进行编译时可以编译通过而IDEA不可以,是因为Eclipse采用的javac插件是Eclipse自己的,对上述jar进行访问时没有限制,可以进行访问。但是利用jdk中javac进行编译时,是不能访问上述jar包的。
解决方案
1. 配置maven-compiler-plugin插件指定rt.jar文件
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.5</version>
<configuration>
<source>${jdk.version}</source>
<target>${jdk.version}</target>
<encoding>UTF-8</encoding>
<compilerArguments>
<verbose />
<bootclasspath>${JAVA_HOME}/jre/lib/rt.jar${path.separator}${JAVA_HOME}/jre/lib/jce.jar</bootclasspath>
</compilerArguments>
</configuration>
</plugin>
<!-- 你项目中需要的其他插件本例忽略 -->
</plugins>
</build>
当我们需要指定多个 jar 的时候,中间的分隔符,要使用maven内置变量 ${path.separator} 来指定。因为在windows下,这个分隔符应该是“分号”,而在Linux 下这个分隔符必须是“冒号”,无论我们写死哪一种都是不兼容的,所以maven为我们提供了这样的变量,可以自动根据操作系统来使用对应的分隔符。
2. 使用公开api-ImageIO替代(推荐)
ImageIO.write(tag, suffix, new FileOutputStream(newFile));