Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java: Is `sun.awt.image` package deprecated?

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.

like image 766
Mir-Ismaili Avatar asked Dec 16 '18 11:12

Mir-Ismaili


2 Answers

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
like image 141
Naman Avatar answered Nov 12 '22 05:11

Naman


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?

like image 4
Jesper Avatar answered Nov 12 '22 04:11

Jesper