views:

260

answers:

5

In the project properties, in the "Java Compiler" section, there are some settings for the "JDK Compliance". I wanted to set the source compatibility to 6 and the .class files' compatibility to 5. This is apparently not allowed: I get the message "Classfile compatibility must be greater or equal than source compatibility".

Is this a limitation of Eclipse or a fundamental issue of Java version compatibility? Are there workarounds?

I would like to use Java 6 in development and for most targets, but I want to produce Java 5 compatible artifacts for some targets such as Macs. I'm fine if this means having two builds, as long as it's the same source.

+5  A: 

As Eclipse says, you can't generate java5 class files from java6 source, it's just not an option. If you need to generate java5 builds, you need to use java5 source level.

Do you really need to use Java6 source level? If there are things in the Java6 API that you need to use, then generating builds for Java5 won't work when you try and run those builds. If you don't need to use Java6 API, then you don't need to use Java6 source compatibility either.

skaffman
So, these settings really only allow to support older source files than the current compliance level, right? Well, I don't absolutely need version 6 source, but version 5 is a little dated already, and I would prefer my code not to be stuck with the lowest version I support in the product. I'd probably rather create patched versions for a special Java 5 build. Are there good tools for this?
Hanno Fietz
If you need to support version X of Java, then so does your Source code, there's no real getting around that.
skaffman
Also, remember, that you can build against Java5 but run on java6. The Java5 JVM may be a little long in the tooth, but the API is absolutely fine. Build against against 5, and run against 6 where possible.
skaffman
+2  A: 

Part of the problem arises since not only has the class format changed, but also that Java 6 has added/different APIs from Java 5. So you may inadvertently use these APIs, and then the implementation will be missing as/when you deploy on Java 5.

If Java 5 is important to you, I would develop and build against a Java 5 SDK. That's the only sure way to know that everything will work as expected.

I have (once) designed a project that was cross-SDK compatible. It required two builds (one for each SDK) and the code had to conditionally load the required API classes depending on the SDK in use. I really don't advise it at all!

Note: You mention Macs. Java 6 is available for Macs (not sure if that's your reasoning for mentioning Macs)

Brian Agnew
+1  A: 

Cannot be done.
If no Java 6 is needed, use Java 5 source level.
If you need Java 6, you can't compile it with only Java 5.

Burkhard
+2  A: 

See also this thread pointing to a similar (older) issue:
"Java theory and practice: Using Java 5 language features in earlier JDKs":

Unless you are using some kind of external tool to transform Java 6 bytecode into Java 1.5-compatible bytecode, you can not indeed set the class compliance to 1.5 and the source compilance to 6.0.

VonC
Thanks, these links gave me a better understanding of the possible problems with SDK compatibility.
Hanno Fietz
A: 

I used to do this too but forgot how :(. I found this link below which appears to show a way to do it that is probably what I used to do in my own projects. You set your eclipse class & source ver to 1.6 then use the Ant build to get the right class version when you build it.

from: http://www.masutti.ch/eel/ (already linked in previous answer)

Update: in Eclipse 3.2 this has to look differently in the javac line of your ant script, set source and target like this

javac (...) source="1.5" target="jsr14" (...)

I tried it with a simple project and it worked for me in eclipse 3.4. You can autogen the build.xml for a simple project with File->export->General->Ant Buildfiles. Then I just tweaked this line:

'property name="target" value="jsr14"/>

and made it rebuild.

It is pretty error prone however. I had to change all my 'System.out.printf' to 'System.out.print' or it just throws exceptions. You can do a check on your source by setting source compliance down to 1.4 then fixing the obvious things (like the printfs) then change it back again.

I think what you are describing actually leads to Java 5 / 1.4 source code, doesn't it?
Hanno Fietz