How to use sun.reflect package in jdk9 / java-9?

I am using jdk-9 and I want to use the sun.reflect.* Package in my code, but I get an exception below

 Exception in thread 'main' java.lang.IllegalAccessError : class Test (in moudle: Unnamed Module) cannot access class sun.reflect.Reflaction (in module:java.base), sun.reflect is not exported to Unnamed module 

when I run the sample code using JDK-9

 public static void main(String args[]){ System.out.println(Reflection.getCallerClass(3)); } 
+5
source share
5 answers

Works well with new versions of OpenJDK 9 EA. For instance:

 $ java -version java version "9-ea" Java(TM) SE Runtime Environment (build 9-ea+138) Java HotSpot(TM) 64-Bit Server VM (build 9-ea+138, mixed mode) $ javac Test.java Test.java:5: warning: Reflection is internal proprietary API and may be removed in a future release System.out.println(Reflection.getCallerClass(3)); ^ Note: Test.java uses or overrides a deprecated API. Note: Recompile with -Xlint:deprecation for details. 1 warning $ java Test null 

It seems that it was fixed in the 9-ea + 115 build as part of the JDK-8137058 . So you are probably using the old EA build. In general, @Holger is right: there is a good chance that this API will completely disappear in future versions of Java, so consider switching to the StackWalker API.

+6
source

ANSWER TO THIS ANSWER - CHECK IT ONE TOGETHER!

A feature of the modular system is that it allows library developers to strictly encapsulate implementation details due to new accessibility rules. In a nutshell, most types in the sun.* And com.sun.* will no longer be available. This is consistent with Sun and later by Oracle, stating that these packages are not intended for public consumption.

The workaround is to export these packages at compile time and run using the command line flag:

 --add-exports java.base/sun.reflect=ALL-UNNAMED 

This exports the sun.reflect package from the java.base module to all modules, including the unnamed module , which collects all classes on the class path.

+5
source

These sun.* Packages were never part of the official API and were not guaranteed to be present even in the JVM prior to Java 9. Be prepared for them to completely disappear in the future, and cannot even be restored using some options. Fortunately, there is an official API covering this functionality, eliminating the need for unofficial APIs.

Get an immediate caller class
 Class<?> c = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE) .getCallerClass(); 
Get the nth caller on the stack (for example, the third, as in your example):
 Class<?> c = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE).walk(s -> s.map(StackWalker.StackFrame::getDeclaringClass).skip(3).findFirst().orElse(null)); 
+4
source
 java -cp classes -XaddExports:java.base/sun.reflect Test 

Jigsaw (java-9) has a modular concept in which they developed the java.base package for compact-1 and encapsulated sun.reflect.* . therefore sun.reflect.* cannot be accessed from the outside. For this reason, it gives an exception.

 Exception in thread 'main' java.lang.IllegalAccessError : class Test (in moudle: Unnamed Module) cannot access class sun.reflect.Reflaction (in module:java.base), sun.reflect is not exported to Unnamed module 

To ensure backward compatibility, they provided the ability to use this package as shown below.

 java -cp classes -XaddExports:java.base/sun.reflect Test 
+3
source

Updating the stream with the latest version and the changes made as indicated in the Migration documentation . Right pointed @Holger already.

The APIs in sun.reflect packages that remain available in JDK 9:

  • sun.reflect.Reflection::getCallerClass(int) Use the stack API instead, see JEP 259: Stack-Walking API.
  • sun.reflect.ReflectionFactory.newConstructorForSerialization

These APIs are available by default at runtime. They have been moved to the jdk.unsupported module, which is present in JRE and JDK images. Modules that need these APIs must declare a dependency on the jdk.unsupported module.

The remaining internal APIs in sun.isc and sun.reflect packages have been moved because they should not be available. If you need to use one of these internal APIs, you can break encapsulation using the --add-exports command line option. (similar to which @NIrav responds ). Although, as suggested in the documents, this parameter should only be used as temporary assistance for migration.

+1
source

Source: https://habr.com/ru/post/1263233/


All Articles