How to modify the AST using Java 9+ [duplicate] - java

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

Related

Using Jsoup library on eclipse [duplicate]

I have just recently started using Eclipse and am running into problems trying to install external libraries. Following online tutorials, I add the .jar file to the classpath and I see it in the referenced libraries folder. Despite this, when trying to import, I get the error:
The package org.apache.commons is not accessible
For reference, I am trying to install the apache math commons library.
Your code probably has two issues.
First, the import statement is wrong since in Java you cannot add a package itself, but all classes of a package as follows (note .*; at the end):
import org.apache.commons.math4.linear.*;
or a specific class, e.g.
import org.apache.commons.math4.linear.FieldMatrix;
Second, you use the Java Platform Module System (JPMS) by having a module-info.java file in the default package probably without the required requires <module>; statement. JPMS was introduced in Java 9 and you have Java 12.
Do one of the following:
Delete the module-info.java file (if needed, you can recreate it via right-clicking the project folder and choosing Configure > Create module-info.java)
In module-info.java add the corresponding requires statement, e.g. by going to the line with the import statement and using the corresponding Quick Fix (Ctrl+1)

How to get Eclipse to stop asking to create a module-info java file on new Java project creation?

Everytime I try to create a new java project Eclipse keeps asking if I want to add a module-info java file to the source folder. It's getting pretty annoying as there's no immediately obvious option to opt out of this check.
IDE for Java Developers, Photon release 4.8.0
See while creating a new project, after you click>> next on the very first dialog "new java project." There is one another dialog box pops up when you click >> finish. It will lead you to the 3rd dialog box which asks for the creation of module-info java file?? & gives you two option create & don't create.
You should select "don't create."
Here are some advantages of the file
module-info.java contents:
To declare a jar file as a named module, one needs to provide a module-info.class file, which is, naturally, compiled from a module-info.java file. It declares the dependencies within the module system and allows the compiler and the runtime to police the boundaries/access violations between the modules in your application. Let’s look at the file syntax and the keywords you can use.
Module module.name – declares a module called module.name.
Requires module.name – specifies that our module depends on the module module.name, allows this module to access public types exported in the target module.
Requires transitive module.name – any modules that depend on this module automatically depend on module.name.
Exports pkg.name says that our module exports public members in package pkg.name for every module requiring this one.
Exports pkg.name to module.name the same as above, but limits which modules can use the public members from the package pkg.name.
Uses class.name makes the current module a consumer for service class.name.
Provides class.name with class.name.impl registers class.name.impl class a service that provides an implementation of the class.name service.
opens pkg.name allows other modules to use reflection to access the private members of package pkg.name.
Opens pkg.name to module.name does the same, but limits which modules can have reflection access to the private members in the pkg.name.
One great thing about the module-info.java syntax is that the modern IDEs would fully support your efforts of writing them. Perhaps all of them would work beautifully. I know that IntelliJ IDEA does content assist, quick fixes of the module files when you import classes from the module you haven’t required yet, and so on. I don’t doubt Eclipse IDE and NetBeans IDE offer the same.
Perhaps this is not a perfect solution, but it will stop asking if you choose to use Java version 8 compiler (JavaSE-1.8). If you need any newer Java version, I'm affraid don't have an answer.

Where has sun.misc.Perf moved now that tools.jar was decomposed in Java 9

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.

JavaLangAccess and SharedSecrets in Java 9

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

How to export all packages from Java 9 module? [duplicate]

This question already has an answer here:
Why is exporting the entire module not allowed?
(1 answer)
Closed 5 years ago.
Right now, for every module I have, I need to explicitly specify packages I want to export. For example:
module core {
exports cc.blynk.server.core;
exports cc.blynk.server.core.protocol.handlers.decoders;
exports cc.blynk.server.core.protocol.handlers.encoders;
}
However, it is not very convenient. I would like to do something like that:
module core {
exports cc.blynk.server.core.*;
}
Is there any way to do that? Where this limitation comes from?
No, you can not use a wildcard to export all packages within the module. You will have to export each package explicitly.
It is not allowed since this could majorly lead to conflicts in the different packages exported from different modules which defies the purpose of modularising the code.
Additionally quoting from one of the threads:
The packages exported by a module are meant to be a stable API that
consumers can rely on. For this reason, we make the module author
spell out the exported packages explicitly. This also dials down the
likelihood of multiple modules needlessly exporting the same package.
Additionally, it avoids the confusion that would occur if com.abs.*
was exported without qualification while com.abs.foo was exported with
qualification.

Categories