It seems like the SharedSecrets and JavaLangAccess classes from the sun.misc package were removed in Java 9.
Are there any replacements in Java 9 for the functionality provided by these classes?
Both the above classes are packaged in jdk.internal.misc package.
One way you can try and access them is by using the option
--add-exports <source-module>/<package>=<target-module>(,<target-module>)*
for your use case as :
--add-exports java.base/jdk.internal.misc=your.module
Note:- Disclaimer from JEP-261:Module System -
The --add-exports and --add-opens options must be used with great
care. You can use them to gain access to an internal API of a library
module, or even of the JDK itself, but you do so at your own risk: If
that internal API is changed or removed then your library or
application will fail.
According to Bug#JDK-8137056
In preparation for JEP 160, SharedSecrets and friend interfaces should
be moved out of 'sun.misc' and located in a truly private package
And they are now available at jdk.internal.misc
Move SharedSecrets and friends to jdk.internal.misc
Related
This question already has answers here:
Accessing com.sun.tools.javac.util from Java 9
(2 answers)
Closed 3 years ago.
I've been trying to modify the AST using annotation processors. I tried extending Lombok, but that seemed too hard, so I decided to use things from com.sun.source.* and com.sun.tools.javac.* However, I am using java 11, and the document I was learning from, "The Hacker's Guide to Javac" http://scg.unibe.ch/archive/projects/Erni08b.pdf, uses Java 6. The api they used is now internal and my module cannot read it.
In IntelliJ, it gave me a few errors, but I clicked on the suggestions (which said things like "Add --Xxx-xxx to xxx" without paying attention to them. When I tried compiling with Maven, it failed, since the module does not read the internals of jdk.compiler.
These are some of my imports:
import com.sun.source.util.Trees;
import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.TreeMaker;
import com.sun.tools.javac.tree.TreeTranslator;
import com.sun.tools.javac.util.Context;
My module-info file contains
requires jdk.compiler;
requires java.compiler;
I got messages like "[ERROR]package com.sun.tools.javac.util is declared in module jdk.compiler, which does not export it to module OtherAnnot" and "[ERROR] (package com.sun.tools.javac.tree is declared in module jdk.compiler, which does not export it to module OtherAnnot)"
Edit: I guess this is a duplicate, but I wanted to know if there was some alternative API for AST transformations in java 9.
With the introduction of Project Jigsaw, the JDK has been modularized, allowing users to create their own modules as well. These modules allows you to export packages of yours, allowing programs that require your module (in their module-info.java) to use the exported packages.
Ideally, you'd be prohibited from using classes that reside in packages that are not exported. However, to not break backwards compatibility, VM flags were introduced that allow you to forcefully export packages (that don't belong to you) to your module.
Given your error message, the respective VM flag to add is:
--add-exports jdk.compiler/com.sun.tools.javac.tree=OtherAnnot
The pattern here is:
--add-exports THEIR_MODULE/THEIR_PACKAGE=YOUR_MODULE
If the compiler complains that packages aren't exported to the unnamed module, then you can use the following:
--add-exports THEIR_MODULE/THEIR_PACKAGE=ALL-UNNAMED
sun.misc.Perf was in tools.jar and in Java 9 this was removed and restructured based on the modules concept, so the question is how do you access it in newer Java?
I need to know which module now contains this code.
The implementation has been moved under the jdk.internal.perf package within the java.base module.
As the name already suggests, the package has not been exported from the module and hence if you still want to explicitly make use of the classes within this package, you can make use of the VM option:
--add-exports java.base/jdk.internal.perf=<your-module-name>
Do note though, this is an unreliable way of making use of such classes and a better solution would always be to migrate for the specific use cases without depending on the (internal) sun.misc.* classes.
In my application that runs on java 8, I am using -bootclasspath:p to add a jar to the boot classpath. In java 9, the option is removed. What is the alternative to do the same in java 9?
You may use -Xbootclasspath/a. Please refer to the release notes which states:-
The boot class path has been mostly removed in this release. The java
-Xbootclasspath and -Xbootclasspath/p options have been removed.
The javac -bootclaspath option can only be used when compiling to JDK 8 or
older. The system property sun.boot.class.path has been removed.
Deployments that rely on overriding platform classes for testing
purposes with -Xbootclasspath/p will need to changed to use the
--patch-module option that is documented in JEP 261.
The -Xbootclasspath/a option is unchanged.
-bootclasspath:p add classes from jar to the begin of default bootstrap class path (prepended). It isn't longer supported in JVM 9 or greater.
-bootclasspath:a add classes from jar to the end of default bootstrap class path (appended). This option is supported in JVM 9 or greater.
https://docs.oracle.com/cd/E15289_01/JRCLR/optionx.htm#i1021218
In my case when I declare variables in this order:
JAVA_OPTS="$SOME_OPT"
JAVA_OPTS="-javaagent:../agent.jar -Xbootclasspath/a:../agent-boot.jar $JAVA_OPTS"
I catch classNotFoundException. And when I reverse order:
JAVA_OPTS="-javaagent:../agent.jar -Xbootclasspath/a:../agent-boot.jar $JAVA_OPTS"
JAVA_OPTS="$SOME_OPT"
ClassNotFound exception disappear.
I need to recompile java applicattion, written on Java 8. App use com.sun.javafx.collections.ObservableListWrapper class, but when compiling for java 9 error occurs:
Error:(3, 22) java: package com.sun.javafx.collections is not visible
(package com.sun.javafx.collections is declared in module javafx.base, which does not export it to the unnamed module)
Which class I can use instead of ObservableListWrapper? Or how to bypass this problem?
Since Java9, most of the com.sun.* APIs are unsupported, JDK-internal APIs and they might go away at any time. Also as described in the noteworthy column -
You should plan to move to using the javafx.collections.FXCollections instead.
Use exposed class since Java 8: ModifiableObservableListBase.
That should handle all your needs.
I am using jdk-9 and I want to use sun.reflect.* package in my code but I am getting the below 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
when I run below sample code using JDK-9
public static void main(String args[]){
System.out.println(Reflection.getCallerClass(3));
}
These sun.* packages were never part of the official API and not guaranteed to be present, even in JVMs before Java 9. Be prepared for them to vanish completely in the future, not even be recoverable via some options. Thankfully, there is an official API covering this functionality, eliminating the need for inofficial APIs.
Get the immediate caller class
Class<?> c = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE)
.getCallerClass();
Get the n’th caller on the stack (e.g. third, like in your example):
Class<?> c = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE).walk(s ->
s.map(StackWalker.StackFrame::getDeclaringClass).skip(3).findFirst().orElse(null));
Works fine with newer OpenJDK 9 EA builds. For example:
$ 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
Seems that it was fixed in 9-ea+115 build as a part of JDK-8137058. So probably you are using older EA build. In general #Holger is right: there are big chances that this API will disappear completely in future Java versions, so consider migrating to StackWalker API.
THIS ANSWER IS OUTDATED - CHECK THIS ONE INSTEAD!
A feature of the module system is that it allows library developers to strongly encapsulate implementation details due to the new accessibility rules. In a nutshell, most types in sun.* and com.sun.* packages will no longer be accessible. This is in line with Sun and later Oracle stating that these packages are not meant for public consumption.
A workaround is to export these packages at compile and launch time with a command line flag:
--add-exports java.base/sun.reflect=ALL-UNNAMED
This exports the package sun.reflect from the module java.base to all modules including the unnamed module, which is the one that collects all classes on the class path.
java -cp classes -XaddExports:java.base/sun.reflect Test
Jigsaw (java-9) has modularity concept in which they have designed java.base package for compact-1 and they have encapsulated sun.reflect.*. so sun.reflect.* can not be accessible outside.
Due to that reason it giving the 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
Still to provide backward compatibility, they have provided the way to use that package like below.
java -cp classes -XaddExports:java.base/sun.reflect Test
Updating the thread with the latest release and changes brought in as mentioned in the Migration documentation as well. Appropriately correctly pointed out by #Holger already though.
The APIs in sun.reflect packages that remain accessible in JDK 9 are:
sun.reflect.Reflection::getCallerClass(int) Instead, use the
stack-walking API, see JEP 259: Stack-Walking
API.
sun.reflect.ReflectionFactory.newConstructorForSerialization
These APIs are accessible by default at run time. They have been moved to the jdk.unsupported module, which is present in the JRE and JDK images. Modules that need these APIs must declare a dependency upon the jdk.unsupported module.
The remaining internal APIs in the sun.misc and sun.reflect packages
have been moved, since they should not be accessible. If you need to use one of these internal APIs, you can break encapsulation using the --add-exports command line option. (similar to as answered by
#NIrav).
Though as suggested in the docs, this option should only be used as a temporary aid to migration.