问题
I was wanting to use some codes that using sun.awt.image.PNGImageDecoder
in my project. The problem is source code is based on Java 8 and my project using JDK 9+ (11). So I got this error:
Package '
sun.awt.image
' is declared in module 'java.desktop
', which does not export it to the unnamed module.
for import sun.awt.image.*
, and:
Symbol is declared in module '
java.desktop
' which does not export package 'sun.awt.image
'
for using PNGImageDecoder
or ImageDecoder
etc.
After some efforts to find a solution, I found some similar situations that suggest adding requires java.desktop;
to module-info.java
file (like this case and this case). But as I realized this solution can only be useful when your project already has a module-info.java
file and you missing one used module in it.
My project hadn't this file already (pay attention to "the unnamed module" in the first error message). As far as I know, this means all modules are imported automatically. So adding this file and adding that line hadn't any effect except (changing error message and) causing some similar issues for other parts of my codes (which were, of course, solvable by adding required modules to module-info.java
file).
To sure I imported all modules in jmods
folder (of JDK 11), but the problem didn't solve:
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;
I know this package (sun.awt.image
) exists in java.desktop
module (of JDK 11), but don't know how can access it.
I use IntelliJ IDEA as IDE.
回答1:
You should not use sun.*
or com.sun.*
classes in your program; they are undocumented, internal classes of the JDK and can change in any release.
Using them possibly makes your program incompatible with other versions of Java.
See: It is a bad practice to use Sun's proprietary Java classes?
回答2:
It's encapsulated!
The problem wouldn't certainly be solved including all the modules from the JDK.
I know this package (sun.awt.image) exists in java.desktop module (of JDK 11), but don't know how can access it.
The actual crux of the problem here lies in the fact, that even though the class PNGImageDecoder
and the package it belongs to sun.awt.image
are a part of the java.desktop
module, the module has chosen not to export it to any external library making use of it.
The choice of abstracting such classes(sun.*
) has been intentional and documented well with the release notes of Java-9 and the rationale is mentioned in JEP-260#Encapsulate Most Internal APIs as well.
Having said that, the temporary rather hacky solution to it would be adding
--add-exports=java.desktop/sun.awt.image=<yourModuleName>
to your command line arguments. Preferably, you should be looking for an alternate way to what you're trying to achieve using the class PNGImageDecoder
.
The last part of it, "the unnamed module" is where the actual code(be it your application or any dependencies of it) is trying to access this class PNGImageDecoder
. So think of it like, the command-line arg above for your use-case results in:
--add-exports=java.desktop/sun.awt.image=ALL-UNNAMED
来源:https://stackoverflow.com/questions/53801778/java-is-sun-awt-image-package-deprecated