my name is GYAN
my name is GYAN

Reputation: 1289

How is Java 9 running code compiled with Java 8 that is using a non-exported package

I compiled following code using Java-8 compiler:

package pack;
import sun.util.calendar.CalendarUtils;
public class A {
    public static void main(String[] args) {
        System.out.println(CalendarUtils.isGregorianLeapYear(2018));
    }
}

I compiled the above code using Java-8 compiler as:

gyan@gyan-pc:~/codes/java$ ~/Documents/softwares/Linux/jdk1.8.0_131/bin/javac -d . a.java
a.java:2: warning: CalendarUtils is internal proprietary API and may be removed in a future release
import sun.util.calendar.CalendarUtils;
                        ^
a.java:9: warning: CalendarUtils is internal proprietary API and may be removed in a future release
        System.out.println(CalendarUtils.isGregorianLeapYear(2018));
                           ^
2 warnings

Version of my default Java Interpreter:

gyan@gyan-pc:~/codes/java$ java -version
java version "9.0.1"
Java(TM) SE Runtime Environment (build 9.0.1+11)
Java HotSpot(TM) 64-Bit Server VM (build 9.0.1+11, mixed mode)

And I can run the compiled code using Java-9 interpreter without any error.

gyan@gyan-pc:~/codes/java$ java pack.a
false

According to my knowledge: At runtime the package "pack" will be contained inside a special module called "Unnamed module". The "Unnamed module" requires all the modules from Java platform module. But only that package can be used by the "Unnamed module" which are exported by the corresponding module.

My question is: Here the module java.base is not exporting the package "sun.util.calendar". Then how the "Unnamed module" is using it?

Upvotes: 5

Views: 592

Answers (1)

Naman
Naman

Reputation: 32046

As pointed by Alan, the section Relaxed strong encapsulation states the following in this respect :-

--illegal-access=permit opens each package in each module in the run-time image to code in all unnamed modules, i.e., to code on the class path, if that package existed in JDK 8. This enables both static access, i.e., by compiled bytecode, and deep reflective access, via the platform's various reflection APIs.

The first reflective-access operation to any such package causes a warning to be issued, but no warnings are issued after that point. This single warning describes how to enable further warnings. This warning cannot be suppressed.

This mode is the default in JDK 9. It will be phased out in a future release and, eventually, removed.

Also, if you try to execute the compiled code with

.../jdk-9.0.1.jdk/Contents/Home/bin/java --illegal-access=deny pack.Some

using the future default flag, you wouldn't be able to execute the code as expected with the following trace :

Exception in thread "main" java.lang.IllegalAccessError: class
pack.Some (in unnamed module @0x1055e4af) cannot access class
sun.util.calendar.CalendarUtils (in module java.base) because module
java.base does not export sun.util.calendar to unnamed module
@0x1055e4af    at pack.Some.main(Some.java:7)

Upvotes: 5

Related Questions