Using internal sun classes with javac
Is there a way to disable restrictions of javac 1.6.0_22 that prevent me from using JRE internal classes like sun.awt.event.*
?
I'm not looking for:
- an explanation why it is forbidden.
- suggest开发者_如何学Goion to use different classes
- suggestion to use reflection
- suggestion to use ecj/eclipse
I just want to know if it is possible or not, and if it is then how.
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
.
In addition to the answer by @marcin-wisnicki if you're using Maven, note that the compiler plugin will silently drop any -XD flags, unless you also specify
<fork>true</fork>
: e.g.
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
<compilerArgs>
<arg>-XDignore.symbol.file</arg>
</compilerArgs>
<fork>true</fork>
</configuration>
...
There's a better solution. First add the option to javac -XDenableSunApiLintControl
and then use @SupressWarnings("sunapi")
in your code.
Normally, this only produces a Warning message; e.g.
[javac] /media/disk/opensso2/opensso/products/federation/openfm/source/com/sun/identity/wss/xmlsig/WSSSignatureProvider.java:46: warning: com.sun.org.apache.xpath.internal.XPathAPI is Sun proprietary API and may be removed in a future release
[javac] import com.sun.org.apache.xpath.internal.XPathAPI;
Perhaps you have told the Java compiler to treat warnings as errors.
If you are using Gradle, you need to use these options
compileJava {
// enable using internal libraries
options.fork = true
options.forkOptions.executable = 'javac'
options.compilerArgs << '-XDignore.symbol.file' }
Another way is change jdk.
In my case project java version 1.8. I used from jdk 11. Therefore This error has found in my project. So I changed my jdk from 11 to 1.8. It has worked for me.
Adding to the answer by @kamiel-ahmadpour: I had to set the javaHome
when running Gradle's compile tasks via IntelliJ. My config now looks like this written in Kotlin DSL:
tasks.withType<JavaCompile> {
options.isFork = true
options.forkOptions.executable = "javac"
options.forkOptions.javaHome = file(System.getProperty("java.home"))
options.compilerArgs.add("-XDignore.symbol.file")
}
Without the javaHome
the build would fail with errors like:
... error: package javax.xml.bind.annotation does not exist
import javax.xml.bind.annotation.XmlAccessType;
^
Running Gradle tasks from the terminal doesn't need the explicitly configured javaHome
and I didn't find the actual cause for the different behaviour, yet.
Environment:
- Java 8
- Gradle 7.5.1
- IntelliJ 2022.2.3
精彩评论