Java:不赞成使用sun.awt.image软件包吗?

时间:2018-12-16 11:43:14

标签: java java-9 java-module jigsaw module-info

我想在项目中使用一些使用sun.awt.image.PNGImageDecoder的代码。问题是源代码基于 Java 8 ,而我的项目使用的是 JDK 9 + (11)。所以我得到了这个错误:

  

包'sun.awt.image'在模块'java.desktop'中声明,该包不会将其导出到未命名模块

import sun.awt.image.*

  

在模块'java.desktop'中声明了符号,该模块不导出包'sun.awt.image'

用于使用PNGImageDecoderImageDecoder

在努力寻找解决方案之后,我发现了一些类似的情况,这些情况建议将requires java.desktop;添加到module-info.java文件中(例如this casethis case)。但是,正如我意识到的那样,只有当您的项目已经有一个module-info.java文件并且其中缺少一个二手模块时,此解决方案才有用。

我的项目还没有此文件(请注意第一条错误消息中的“ 未命名模块”)。据我所知,这意味着所有模块都是自动导入的。因此,添加此文件并添加该行没有任何影响,除了(更改错误消息并)对我的代码的其他部分造成了类似的问题(当然,可以通过将必需的模块添加到module-info.java文件中来解决)

确保我将所有模块都导入了(JDK 11的)jmods文件夹中,但是问题没有解决:

requires java.base;
requires java.compiler;
requires java.datatransfer;
requires java.desktop;
requires java.instrument;
requires java.logging;
requires java.management;
requires java.management.rmi;
requires java.naming;
requires java.net.http;
requires java.prefs;
requires java.rmi;
requires java.scripting;
requires java.se;
requires java.security.jgss;
requires java.security.sasl;
requires java.smartcardio;
requires java.sql;
requires java.sql.rowset;
requires java.transaction.xa;
requires java.xml.crypto;
requires java.xml;
requires jdk.accessibility;
requires jdk.aot;
requires jdk.attach;
requires jdk.charsets;
requires jdk.compiler;
requires jdk.crypto.cryptoki;
requires jdk.crypto.ec;
requires jdk.crypto.mscapi;
requires jdk.dynalink;
requires jdk.editpad;
requires jdk.hotspot.agent;
requires jdk.httpserver;
requires jdk.internal.ed;
requires jdk.internal.jvmstat;
requires jdk.internal.le;
requires jdk.internal.opt;
requires jdk.internal.vm.ci;
requires jdk.internal.vm.compiler;
requires jdk.internal.vm.compiler.management;
requires jdk.jartool;
requires jdk.javadoc;
requires jdk.jcmd;
requires jdk.jconsole;
requires jdk.jdeps;
requires jdk.jdi;
requires jdk.jdwp.agent;
requires jdk.jfr;
requires jdk.jlink;
requires jdk.jshell;
requires jdk.jsobject;
requires jdk.jstatd;
requires jdk.localedata;
requires jdk.management.agent;
requires jdk.management.jfr;
requires jdk.management;
requires jdk.naming.dns;
requires jdk.naming.rmi;
requires jdk.net;
requires jdk.pack;
requires jdk.rmic;
requires jdk.scripting.nashorn;
requires jdk.scripting.nashorn.shell;
requires jdk.sctp;
requires jdk.security.auth;
requires jdk.security.jgss;
requires jdk.unsupported.desktop;
requires jdk.unsupported;
requires jdk.xml.dom;
requires jdk.zipfs;

我知道此软件包(sun.awt.image)存在于(JDK 11的)java.desktop模块中,但是不知道如何访问它。

我将IntelliJ IDEA用作IDE。

2 个答案:

答案 0 :(得分:5)

已封装!

包括JDK的所有模块在内的问题肯定无法解决。

  

我知道此包(sun.awt.image)存在于java.desktop模块(的   JDK 11),但不知道如何访问它。

问题的真正症结在于,即使PNGImageDecoder类及其所属的软件包sun.awt.imagejava.desktop模块的一部分,该模块选择了不导出到使用它的任何外部库。

选择此类抽象类(sun.*)是有意的,并且在Java-9的发行说明中有很好的记录,并且在JEP-260#Encapsulate Most Internal APIs中也提到了基本原理。


话虽如此, 临时 的解决方法很笨拙,那就是添加

--add-exports=java.desktop/sun.awt.image=<yourModuleName>

您的命令行参数。最好,您应该寻找一种替代方法,以尝试使用类PNGImageDecoder来实现。


它的最后一部分"the unnamed module"是实际代码(无论是您的应用程序还是它的任何依赖项)试图访问此类PNGImageDecoder的地方。因此,请考虑一下,上面用例的命令行arg会导致:

--add-exports=java.desktop/sun.awt.image=ALL-UNNAMED

答案 1 :(得分:4)

您不应在程序中使用sun.*com.sun.*类;它们是JDK的未记录内部类,可以在任何发行版中更改。

使用它们可能会使您的程序与其他Java版本不兼容。

请参阅:It is a bad practice to use Sun's proprietary Java classes?