-Xpkginfo:always arguments causes javac 1.7.0_25 to crashes - java

My goal
We need to pass -Xpkginfo:always arguments to javac compiler. We are using javac 1.7.0_25. -Xpkginfo is available for this version says java doc.
Expected result: package-info.class files shall be generated
Actual result : javac compiler is crashing :
An exception has occurred in the compiler (1.7.0_25). Please file a bug at the Java Developer Connection (http://java.sun.com/webapps/bugreport) after checking the Bug Parade for duplicates. Include your program and the following diagnostic in your report. Thank you.
java.lang.NullPointerException
at com.sun.tools.javac.comp.Enter.visitTopLevel(Enter.java:291)
at com.sun.tools.javac.tree.JCTree$JCCompilationUnit.accept(JCTree.java:459)
at com.sun.tools.javac.comp.Enter.classEnter(Enter.java:258)
at com.sun.tools.javac.comp.Enter.classEnter(Enter.java:272)
at com.sun.tools.javac.comp.Enter.complete(Enter.java:484)
at com.sun.tools.javac.comp.Enter.main(Enter.java:469)
at com.sun.tools.javac.main.JavaCompiler.enterTrees(JavaCompiler.java:929)
at com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:824)
at com.sun.tools.javac.main.Main.compile(Main.java:439)
at com.sun.tools.javac.main.Main.compile(Main.java:353)
at com.sun.tools.javac.main.Main.compile(Main.java:342)
at com.sun.tools.javac.main.Main.compile(Main.java:333)
at com.sun.tools.javac.Main.compile(Main.java:76)
at com.sun.tools.javac.Main.main(Main.java:61)
What I've tried so far
It works with java 1.8, but unfortunately, we can't upgrade our java compiler because we still have old java code.
EDIT
Used javac -X to make sure 1.7.0_25 has -Xpkginfo argument available. Answer is yes :
PS C:\SVN\products\faa_mx\vs2017.install2> javac -X
-Xlint Enable recommended warnings
-Xlint:{all,cast,classfile,deprecation,dep-ann,divzero,empty,fallthrough,finally,options,overrides,path,processing,rawtypes,serial,static,try,unchecked,varargs,-cast,-classfile,-deprecation,-dep-ann,-divzero,-empty,-fallthrough,-finally,-options,-overrides,-path,-processing,-rawtypes,-serial,-static,-try,-unchecked,-varargs,none} Enable or disable specific warnings
-Xbootclasspath/p:<path> Prepend to the bootstrap class path
-Xbootclasspath/a:<path> Append to the bootstrap class path
-Xbootclasspath:<path> Override location of bootstrap class files
-Djava.ext.dirs=<dirs> Override location of installed extensions
-Djava.endorsed.dirs=<dirs> Override location of endorsed standards path
-Xmaxerrs <number> Set the maximum number of errors to print
-Xmaxwarns <number> Set the maximum number of warnings to print
-Xstdout <filename> Redirect standard output
-Xprint Print out a textual representation of specified types
-XprintRounds Print information about rounds of annotation processing
-XprintProcessorInfo Print information about which annotations a processor is asked to process
-Xprefer:{source,newer} Specify which file to read when both a source file and class file are found for an implicitly compiled class
-Xpkginfo:{always,legacy,nonempty} Specify handling of package-info files
Also tried with 1.7.0_80, same crash :
An exception has occurred in the compiler (1.7.0_80).
java.lang.NullPointerException
at com.sun.tools.javac.comp.Enter.visitTopLevel(Enter.java:291)
at com.sun.tools.javac.tree.JCTree$JCCompilationUnit.accept(JCTree.java:459)
at com.sun.tools.javac.comp.Enter.classEnter(Enter.java:258)
at com.sun.tools.javac.comp.Enter.classEnter(Enter.java:272)
at com.sun.tools.javac.comp.Enter.complete(Enter.java:484)
at com.sun.tools.javac.comp.Enter.main(Enter.java:469)
at com.sun.tools.javac.main.JavaCompiler.enterTrees(JavaCompiler.java:929)
at com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:824)
at com.sun.tools.javac.main.Main.compile(Main.java:439)
at com.sun.tools.javac.main.Main.compile(Main.java:353)
at com.sun.tools.javac.main.Main.compile(Main.java:342)
at com.sun.tools.javac.main.Main.compile(Main.java:333)
at com.sun.tools.javac.Main.compile(Main.java:76)
at com.sun.tools.javac.Main.main(Main.java:61)
Alternative solution
Would that make sense to use javac 1.8 and use the command line javac -source 1.7 -target 1.7 MyClass.java?

With java 1.7, it looks like that if you pass -Xpkginfo:always to javac, it only accepts package-info.java empty files. If you pass non-empty files, we get the crash.
With 1.8, javac is able to deal with empty and non empty files in one command line.
So, the workaround with 1.7 is to call javac multiple time, once with all empty package-info.java files, and another time with non-empty files.

Related

Java compilation through command prompt issue

I tried to compile my class file "checker.class" into "checker.java" through the use of the javac command, planning to run it with the java command, but javac either gave me the issue of "file not found" OR "invalid flag" (when I tried to put checker in quotations.)
I would also like to understand the issue itself better and not just know the solution. Thanks.
What I attempted:
C:\Users\jaede\Desktop\everything>javac checker.class
C:\Users\jaede\Desktop\everything>javac "checker.class"
Results with error messages:
error: file not found: Checker.java
Usage: javac
use --help for a list of possible options
error: invalid flag: Checker.class Usage: javac
use --help for a list of possible options
planned to do:
C:\Users\jaede\Desktop\everything>java checker.java
*Sidenote: I probably do not have an environment variable issue, since I could run this with another .java files with the java command
I got .class and .java mixed up. The comments to the original post have the full rundown.

calling a java program from CentOS 7 terminal

I am using the code from this tutorial to test the JDBC connection. I changed the name of the class to TestJDBC and I altered the database name and query, but otherwise it is identical. When I run the class as a Java application from within eclipse on my devbox, the program runs properly. However, when I copy the file to /home/username/ on a remote CentOS 7 server, typing java TestJDBC.java into the terminal produces the following error:
Error: Could not find or load main class TestJDBC.java
I also the same error when I try java TestJDBC and when I upload the .class file in addition to just the .java file. What else do I need to do in order to call the Java class from the CentOS 7 terminal?
Note that javac TestJDBC.java results in -bash: javac: command not found. And I did try java somepackage.TestJDBC with same results of Error: Could not find or load main class TestJDBC.java as above.
ANSWER NOTE: The answer required getting the development version of openJDK using yum. The PATH variable was not part of the solution. However, I am marking the answer below as accepted because the user who submitted it contributed substantially to the solution.
You should be able to run it after compiling it
javac TestJDBC.java
java TestJDBC
Note that you do not need to add .class when running it from the commandline.
If this still does not work, please paste your code.
EDIT after request
So you've now stated that you're missing javac from your PATH. I'll show you how to add it:
$> export JAVA_HOME=/path/to/jdk/jdk.1.8.0_20
$> export PATH=$PATH:$JAVA_HOME/bin
Verify by running
javac -version
It should print something like
javac 1.8.0_20

Javac vs Java within -classpath option

What is the difference in calling the -classpath option from javac and from java
for example:
javac -classpath MyJar.jar GetJar.java
java -classpath MyJar.jar:. GetJar
it works as well as:
javac -classpath MyJar.jar GetJar.java
java GetJar
So basically where the first -classpath related to javac needs to be there, on the other hand in the java command line it might be optional. Why? Do you know in which circumstance it would be mandatory. And more in general what is the effect of -classpath called by javac and what is the effect of -classpath called by java.
Thanks in advance.
One is the classpath used for compiling. The other is the classpath used for running. And they do not have to be the same thing. The set of classes needed for the compilation processes are all those referred to by every class being compiled. Whereas your runtime JAR could be invoking a standalone class with an empty main method and no dependencies.
Just remember that at runtime class dependencies are resolved dynamically, aka a class is only loaded when it is needed (this is a generalization, boot and system classes are always loaded).
This document contains answers for your questions
http://docs.oracle.com/javase/1.4.2/docs/tooldocs/windows/javac.html
using -classpath every time is a very time consuming work. Instead, use environment variables (if you are dealing with a package such as Java Mail)
classpath is used for compiling. Javac is the Java Compiler, where it converts your code into byte code.
When it comes to java it is used to run your Java source file/jar.

Java cannot find symbol error even though have verified classpath and .class file with javap

I'm building with Maven and getting a seemingly innocuous "symbol not found" error - problem is I've verified that the build is correct with all the lower level Java tools I know and it looks airtight. I have built with this command line:
javac -d /home/dan/EmailClient/Initial-Client/target/classes -classpath <many jars>:
/thepath/Common/1.0-SNAPSHOT/Common-1.0-SNAPSHOT.jar /* I need this one */
-sourcepath /thepath/src/main/java: <the files>
-s /thepath/target/generated-sources/annotations
-g -nowarn -target 1.7 -source 1.7 -encoding UTF-8
Get this error:
Launcher.java:119: error: cannot find symbol
return Promise.onPool(getterPool).continueWith(new Transformer<Void, Promise<List<Void>>>() {
(with error pointing on onPool)
And have run jar xf Common-1.0-SNAPSHOT.jar (cding by copying and pasting the directory in the command line), then
javap Promise.class
which shows
public static me.unroll.functional.Promise<java.lang.Void> onPool(java.util.concurrent.Executor);
So this looks airtight to me - what debug step am I missing?
Furthermore this builds fine on a separate machine and runs fine from Eclipse with all relevant source files opened, just not from my actual build machine.
I suggest you to inspect the <many jars> section in your classpath, you are likely to find an older version of your Maven-built jar in there, which is winning the classname resolution game.

Check if Java bytecode contains debug symbols

I would like to know how can I check if a compiled Java class contains debug symbols. The problem is that I compile an application from ant with debug="on", but a specific JVM throws an exception: it says that the debug symbols are missing.
Thanks.
If you run javap -v on the class file, you will see the debug information that is present in the file.
It is worth compiling a simple test class with different -g option settings and looking at the results with javap.
If, you need to know exactly how javap presents the information, it is it is best for you to try it out in your Java installation. The output from the javap command may vary between different Java versions.
The most important thing a class file with debug information will contain is the LineNumberTable which maps bytecode instructions to source line numbers and the LocalVariableTable which tells the debugger where your local variables, including arguments to a method reside inside the VM during execution.

Categories