On our hadoop cluster my Pig UDF fails complaining
[main] ERROR org.apache.pig.tools.grunt.Grunt - ERROR 1069: Problem resolving class version numbers for class <classname>
I read writing a udf in pig kind of like tutorial and the problem seams to be clear, but unfortunately I cant solve it. My manifest does not contain a version (is this necessary?) and javap reports major version 52, representing java 1.8, although I compiled it with 1.7. So how can I solve this?
My manifest does not contain a version (is this necessary?)
The version manifest entry is not relevant to this. The classloader pays no attention to the version manifest entry.
and javap reports major version 52, representing java 1.8,
That is the relevant fact.
although I compiled it with 1.7.
This all boils down to how you compiled your code, and I think you are incorrect when you say that you compiled with Java 1.7.
Why do I say that? Because the Java 1.7 java compiler is not capable of creating a ".class" file with the Java 1.8 version numbers. It simply doesn't understand the Java 8 syntax extensions, and the corresponding enhancements to the classfile format.
So how can I solve this?
The way to resolve this is to look carefully at your build process and figure out how and why the offending class got compiled using a Java 1.8 compiler. Because there can be no doubt that that is what has happened.
If you are building by hand (e.g. by running "javac" and "jar" from the command line, or by clicking buttons in your IDE) then now would be a good time to learn about build tools like Maven, Ant and Gradle.
FOLLOWUP
That not true. My setting proofs this, but I guess I found the issue: .settings/org.eclipse.jdt.core.prefs contain several 1.8. entries. This may be due to the fact that at the time of the project creation I had 1.8. installed.
Actually, it doesn't "prove" anything ...
What this is telling me is that you are probably compiling with the Eclipse Java compiler, not the Java compiler from your JDK.
In fact, your Eclipse compiler is (or was) compiling for a Java 1.8 target ... because that is what your Eclipse settings say that the Eclipse Java compiler should do. If you are using the Eclipse compiler to compile your code, the version of your JDK or JRE install doesn't determine the classfile version number.
Once again, I strongly recommend that you learn to use a Maven, Ant or Gradle so that you build process is more repeatable and less error prone.
I guess Stephen C's is the most general answer.
In my special case the problem was, that the project specific compiler compliance settings were wrong, because I used JDK 1.8 locally when I created the project and installed 1.7 later, when I got the error on the cluster.
The option is quite hidden and can be found here:
Window > Preferences > Java > Compiler > "Configure project specific settings" > [projectname] > "Compiler compliance level"
Related
We're using java 8 for most modules/projects, but for some of the modules, we use java 6 (customer requirements).
The developers have java 8 installed and we compile the java 6 projects using these flags:
compileJava {
sourceCompatibility = 1.6
targetCompatibility = 1.6
}
We thought we're all good until we upgraded guava from v20 to latest - 28.1-jre.
To our surprise, the build was successful but failed at runtime.
We have a workaround for building for java 6 using a specific javac found in JDK 6. See more info here. This workaround wields the error class file has wrong version 52.0, should be 50.0 in compile time. The downside is that it requires a download+config+usage of JDK 6 for developers.
Is there a way to validate the dependencies' java version at compile time when using a higher java version? (without installing lower version java) Thanks.
Setting -source and -target values to 1.6 is insufficient to ensure that the resulting output is compatible with 1.6. The program itself must not have any library API dependencies on later versions, and the -source and -target options don't do that. (GhostCat said pretty much the same thing.)
For example, in Java 8, ConcurrentHashMap added a covariant override for the keySet method that returns a new type ConcurrentHashMap.KeySetView. This type didn't exist in earlier versions of Java. However, in the class binary, the return type is encoded at the call site. Thus, even if the source code is compiled with -source 1.6 -target 1.6, the resulting class file contains a dependency on the Java 8 class library API.
The only solution to this is to ensure that only Java 1.6 compatible libraries are in the classpath at compile time. This can be done using the -Xbootclasspath option to point to a JDK 1.6 class library, or it might be simpler just to use a JDK 1.6 installation in the first place.
This applies to external libraries in addition to the JDK, as you've discovered with Guava. The Animal Sniffer project provides plugins for Ant and Maven that checks library dependencies for version problems. Offhand I don't know if there is something similar for Gradle. There might be a way to get Animal Sniffer to work with Gradle, but I have no experience with doing that.
Is there a way to validate the dependencies' java version at compile time when using a higher java version? (without installing lower version java).
You specify your dependencies. When you tell your built system to explicitly use some library X in version Y, then you made a very clear statement.
And you see, it is not only about the class file version number. What if some person doesn't pay attention, and compiles something with Java8 ... with Java6 target, but forgets that the code bases uses Java8-only API calls?!
In other words: you are looking in the wrong place.
The person who makes updates to the build description, and changes a library version from Y to Y+8, that person needs to carefully assess that change. For example by reading release letters.
I agree that a really clever build system could check if libraries you are using come in with a matching class file version. But as said, that is only one aspect of the problem. So instead of looking into a technical solution, I think the real answer is: don't step version numbers because you can, but because you have to. And that manual step of changing that version number, that is something that requires due diligence (on the side of the human doing it).
Thus: I think the most sane approach here is to compile the Java6 deliverables within their own specific build setup. Which you only touch after careful inspection of such details. And sure: convince your customer to move on, and give up a long dead version of Java.
I'm using java 1.8 with lots of pleasure.
One of my projects in my workspace needs to compile and be compatible with java 1.6, so i changed the appropriate eclipse options.
Now i get the famous message:
Build path specifies execution environment JavaSE-1.6. There are no JREs
installed in the workspace that are strictly compatible with this environment.
There are many questions and answers on how to solve this problem. So no problem there.
But what are theoretically the problems that may come up when this warning is ignored? (everything seem to be running nicely on 1.6)
One potential problem is that your 1.6-targeted code may accidentally use a class or interface that is introduced in JDK1.8. If the JRE that is associated with a 1.6 target in your workspace is actually a JRE1.8 or 1.7, the code may compile fine but you may end up with something like NoClassDefFoundError at runtime.
I seem to have solved the immediate compile errors, but would appreciate some deeper insight and have not found anything on StackExchange or Googling the error message that appears directly applicable.
Have been using Android Development Kit plugin for Eclipse for only a few weeks now. I understand that Android only uses syntax through Java 1.5 and suspect that may be a clue to my problem which only occurred after I added a Debug.startMethodTracing("filename.trace"); and added WRITE_EXTERNAL_STORAGE uses-permissions.
Successfully compiled and ran simple (hello world style) apps, then all of a sudden: bam!!
Brand new error message:
"Build path specifies execution environment JavaSE-1.6. There are no JREs installed in the workspace that are strictly compatible with this environment."
When I checked the Java Build path for my app:
Right click project name > Properties > Java Build Path > Libraries
There were only four items:
1) An imported jar file library (for an API)
2) Android 4.4.2
3) Android Dependencies
4) Android Private Libraries
I seem to have solved the problem by following these non-Android specific instructions:
Java Build Path
which essentially said to:
'Add Library" > 'JRE System Library" > "Workspace default JRE (jre7)
and now my code appears to be compiling again. However, I am somewhat uncomfortable with my level of understanding of why it was necessary to do this (I just checked and Jdk1.7 is still in my system path and seemed to work fine before). Is this usually necessary when developing for Android?
In other words, is it normal for a JRE to be explicitly listed in the libraries section with the ADK?
Is there any problem with using JRE 1.7 instead of an older version?
I also read these instructions, but again, the answer is not specific to Android:
Warning - Build path specifies execution environment J2SE-1.4
The warning is letting you know that you don't have any actual 1.6-version JDKs available, even though your code is set to a 1.6 compliance level. The practical pitfall is that since the only JRE runtime available is the 1.7 runtime, you might use some class or method that was added in 1.7: Your code would still compile just fine, but then you'd get a NoSuchMethodError or such if it was run on a 1.6 runtime.
In practical terms, since you're targeting Android, you probably don't need to worry; the ADK is going to recompile your code anyway, and any such errors should show up immediately. If you do want the warning gone, just install the 1.6 JDK alongside the 1.7.
I am trying to config my eclipse (Helios) use jdk 7 to compile my code. I didn't install jdk 7 on my Windows XP. But I include all of the jdk contents with my project. It seems the solution provided in this post doesn't work. Compile java code needs JDK. the JRE is enough for running the compiled code. I think we need a way to configure the JDK to be used not just JRE. I tested with a JDK 7 new feature, String in switch, I can compile it in my batch file compile system but cannot use eclipse to compile it.
any idea?
This is what I did to make Eclipse 3.x works with Java 7.
install Java 7 in another machine and then copy the JDK folder into my java application 3rdparty directory (so my machine still use Java 6);
download the Eclipse 3.7.1 from here: eclipse 3.7.1
configure Eclipse by following steps in this post (select 1.7 in Compiler compliance level under the Java Compiler entry);
At least I can use String in Switch now in Eclipse.
Good luck.
Compile java code needs JDK. the JRE is enough for running the
compiled code.
that is right
"But I include all of the jdk contents with my project"
Including those will not change eclipse's compiler behavior. Including files under project build path just makes those classes available for your application development/run-time (or as good as setting CLASSPATH)
Do these :
1 - Install required version of JDK
2 - Choose following menu - Window > Preferences > Java > Compiler - and you will see a drop down to choose the version you want to use.
3 - Read this and this as well.
Good luck for being DBA after 5 yrs. Please consider working on your English as well (no offense please)
I am working an application with JXL API and when i tried compiling using eclipse IDE, it's working fine and the same is not compiling when i am trying to compile in Command prompt and showing the below exception..
Extract.java:6: cannot access jxl.read.biff.BiffException bad class file: C:\Program Files\Java\jdk1.5.0_01\jre\lib\ext\jxl.jar(jxl/read/biff/BiffException.class)
class file has wrong version 50.0, should be 49.0
Please remove or make sure it appears in the correct subdirectory of the classpa
th.
import jxl.read.biff.BiffException;
^
1 error
EDIT:
I am able to executing using JDK 1.6. Since JDK 1.6 must also be compatible with lower versions, why doesn't it support the class files which were compiled in JDK 1.5.
The library you're using was compiled with Java 6
Your compiler is Java 5 that's why it doesn't understand that format.
To fix it you have to get a 1.5 version of the library or upgrade your compiler to 1.6 I suggest the later.
Per http://www.jnode.org/node/2140...
Submitted by Stephen Crawley on Fri, 11/30/2007 - 07:15.
I suspect that you are mixing code compiled with different versions of Java. Class file version 50.0 is used by Java 6.0, and 49.0 is used by Java 5.0.
Try doing a "build clean" to get rid of all existing class files, followed by a regular build.
JNode is being developed using Java 6.0 only. Last time I tried, it didn't build using Java 5.0 (aka 1.5). (It is a problem with the program that builds the JNode boot image.)
Try changing the builder in Eclipse. If you're using 3.4, it's Project - Properties - Java Compiler - Enable Project Specific Settings - Compiler Compliance Level = 1.6. You'll prolly also need to have JRE 1.6 installed, as well.
Check you class path in eclipse and make sure that its the same class path your compiling to in the command prompt, also check your library imports
It means that, you have compiled that class with Java 6 and trying to execute with Java 5.
Solution :
If your using ant, execute below steps on the project root directory
ant clean
ant deploy
If your using eclipse, just
clean the workspace(remove the class files which were compiled with Java6)
and build again
this could be that in you IDE you point to latest version of JDK but when you build your program outside the IDE(maybe with maven) your java_home is the older version to the one on your IDE.