我想在我的项目中使用一些使用sun.awt.image.PNGImageDecoder
的代码。问题是源代码是基于Java8和我的项目使用JDK9+(11(。所以我得到了这个错误:
包'
sun.awt.image
'在模块'java.desktop
'中声明,不会将其导出到未命名模块。
对于import sun.awt.image.*
,以及:
符号在模块"
java.desktop
"中声明,该模块不导出包"sun.awt.image
">
用于使用PNGImageDecoder
或ImageDecoder
等
在努力寻找解决方案后,我发现了一些类似的情况,建议将requires java.desktop;
添加到module-info.java
文件中(如本例和本例(。但正如我所意识到的,只有当你的项目已经有一个module-info.java
文件,并且你在其中缺少一个使用过的模块时,这个解决方案才会有用
我的项目还没有这个文件(请注意第一条错误消息中的">未命名模块"(。据我所知,这意味着所有模块都是自动导入的。因此,添加这个文件和添加那一行没有任何效果,只是(更改错误消息和(给我的代码的其他部分带来了一些类似的问题(当然,可以通过向module-info.java
文件添加所需的模块来解决这些问题(。
当然,我导入了(JDK11的(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。
它被封装了
包括JDK中的所有模块在内,这个问题肯定不会得到解决。
我知道这个包(sun.awt.image(存在于JDK 11(,但不知道如何访问它。
这里问题的实际症结在于,即使类PNGImageDecoder
及其所属的包sun.awt.image
是java.desktop
模块的一部分,该模块也选择不将其导出到任何使用它的外部库。
抽象此类(sun.*
(的选择是有意的,并在Java-9的发行说明中得到了很好的记录,其基本原理也在JEP-260#封装大多数内部API中提到。
话虽如此,临时相当棘手的解决方案是添加
--add-exports=java.desktop/sun.awt.image=<yourModuleName>
到您的命令行参数。最好,您应该寻找一种替代方法来实现使用类PNGImageDecoder
所要实现的目标。
它的最后一部分;未命名模块"是实际代码(无论是您的应用程序还是它的任何依赖项(试图访问此类PNGImageDecoder
的位置。因此,可以这样想,上面针对您的用例的命令行arg的结果是:
--add-exports=java.desktop/sun.awt.image=ALL-UNNAMED
您不应该在程序中使用sun.*
或com.sun.*
类;它们是JDK的未记录的内部类,可以在任何版本中更改。
使用它们可能会使您的程序与其他版本的Java不兼容。
看:使用Sun专有的Java类是一种糟糕的做法吗?