Using Internal Sun Classes with Javac

Using internal sun classes with javac

I have found the answer myself.

When javac is compiling code it doesn't link against rt.jar by default.
Instead it uses special symbol file lib/ct.sym with class stubs.

Surprisingly this file contains many but not all of internal sun classes.
In my case one of those more-internal-than-usual classes was sun.awt.event.IgnorePaintEvent.

And the answer to my question is: javac -XDignore.symbol.file

That's what javac uses for compiling rt.jar.

How to access the internal sun.security class from an OSGI bundle?

All of these are non public API classes and cannot be relied upon to be present in all jre distributions. I believe that they are all present sun distributions, but not in IBM distributions etc. Try running against a Sun distribution, but this looks like a case of building against undocumented features, a big no no.

It is a bad practice to use Sun's proprietary Java classes?

Because they are internal APIs: they are subject to change in a undocumented or unsupported way and they are bound to a specific JRE/JDK (Sun in your case), limiting portability of your programs.

Try to avoid uses of such APIs, always prefer a public documented and specified class.

do not use com.sun.xml.internal.*?

Sun classes in the JDK are prefixed sun.* and are not part of the public supported interface so should be used with care. From the Sun FAQ:

The classes that Sun includes with the
Java 2 SDK, Standard Edition, fall
into package groups java., javax.,
org.* and sun.. All but the sun.
packages are a standard part of the
Java platform and will be supported
into the future. In general, packages
such as sun., that are outside of the
Java platform, can be different across
OS platforms (Solaris, Windows, Linux,
Macintosh, etc.) and can change at any
time without notice with SDK versions
(1.2, 1.2.1, 1.2.3, etc). Programs
that contain direct calls to the sun.
packages are not 100% Pure Java. In
other words:

The java., javax. and org.* packages
documented in the Java 2 Platform
Standard Edition API Specification
make up the official, supported,
public interface.

If a Java program directly calls only
API in these packages, it will operate
on all Java-compatible platforms,
regardless of the underlying OS
platform.

The sun.* packages are not part of the
supported, public interface.

A Java program that directly calls
into sun.* packages is not guaranteed
to work on all Java-compatible
platforms. In fact, such a program is
not guaranteed to work even in future
versions on the same platform.

Accessing com.sun.tools.javac.util from Java 9

In the longer run, the safe way to be dealing with such situation is to move away from using these internal APIs of the JDK.

One can make use of the jdk.compiler module's APIs as a replacement to the com.sun.tools.javac package.

Defines the implementation of the system Java compiler and its command
line equivalent, javac, as well as javah.

Specifically for com.sun.tools.javac.util.List, almost all of its non-overridden, self-defined methods could be derived from the implementation based on the interface java.util.List.


Migration guide's column about Removed java.* APIs state that -

The Java team is committed to backward compatibility. If an
application runs in JDK 8, then it will run on JDK 9 as long as it
uses APIs that are supported and intended for external use.

These include:

  • JCP standard, java.*, javax.*
  • JDK-specific APIs, some com.sun.*, some jdk.*

Supported APIs can be removed from the JDK, but only with notice. Find out if your code is using deprecated APIs by running
the static analysis tool jdeprscan.

Then to add to the highlighted risk above..

Compile Time

Internal APIs that are encapsulated in JDK 9 are not accessible at compile time, but can be made accessible at compile time via the --add-exports command-line option.

In your case :

--add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED

Run Time

At the runtime, they remain accessible if they were in JDK 8 but in a future release, they will become inaccessible, at which point the --add-exports or --add-opens options can be used to make them accessible at runtime as well.

Is com.sun.tools.javac.util available in openjdk 8?

You can find JDK sources here:

https://hg.openjdk.java.net/jdk/jdk13/

as far as I can tell, it's still there:

> find . -name "Pair.java" | grep javac
./src/jdk.compiler/share/classes/com/sun/tools/javac/util/Pair.java

It looks like your env related issue.

Sample Image

It also works perfectly fine with Java 1.8

adoptopenjdk

Default download from: https://adoptopenjdk.net

Sample Image

Amazon Corretto

Default download from: https://docs.aws.amazon.com/corretto/latest/corretto-8-ug/what-is-corretto-8.html

Sample Image

How does javac locate the Java API classes?

By default, classes are compiled against the bootstrap(the runtime classes in rt.jar, internationalization classes in i18n.jar, and others) and extension classes of the platform that javac shipped with.So Yes If You run 'javac.exe' from jdk1.6.0_17, will it load the Java API classes from 'rt.jar' in 1.6.0_17 not from 1.6.0_25.

But javac also supports cross-compiling, where classes are compiled against a bootstrap and extension classes of a different Java platform implementation.

See more at : Cross Compilation if you want to use



Related Topics



Leave a reply



Submit