17

So guys,

I'm trying to play a bit with Javac Cross compilation with Ant and on terminal. Locally and on an integration environment and i'm having the same problem on the very basic problem.

I run this in the linux terminal (and also on my cygwin on windows and the cmd):

 javac -target 1.6 -source 1.7 -bootclasspath /usr/java/jdk1.6.0_27/jre/lib/rt.jar Main.java

with Main.java with nothing other than a System.out.println.

javac -version ==> javac 1.7.0_11

I'm getting the error message:

javac: source release 1.7 requires target release 1.7

I have roughly the same configuration on my local windows machine with the exact same results.

It was my understanding that cross compilation is all about compiling some source code that is compatible with a higher version jdk using that higher version of jdk, but passing the rt.jar of the target version that is supposedly lower.

if target and source are the same, it worked.

target=1.7 and source=1.7 workd fine

target=1.6 and source=1.6 worked just fine

but i want cross-compilation, so what is it that i'm doing wrong?

I appreciate all the help I could get and thanks in advance.

Eyad Ebrahim
  • 971
  • 1
  • 8
  • 21

2 Answers2

13

You cannot have a newer version of source and lower version of target. For example, In Java 5, a number of new features were added to the language, such as generics, autoboxing and you cannot expect a JVM 1.4 to understand it. So, you must tell the compiler that your source code is Java 1.4 source code. This explains the results you have.

The default for -target depends on the value of -source:

  • If -source is not specified, the value of -target is 1.7
  • If -source is 1.2, the value of -target is 1.4
  • If -source is 1.3, the value of -target is 1.4
  • If -source is 1.5, the value of -target is 1.7
  • If -source is 1.6, the value of -target is 1.7
  • For all other values of -source, the value of -target is the value of -source.

For more info refer to http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javac.html

Matt Ball
  • 354,903
  • 100
  • 647
  • 710
vinay
  • 950
  • 1
  • 11
  • 27
  • 7
    that doesn't make sense though, why would I need to restrict my perfectly 1.6 compatible code, to run only with 1.7. I could only see the other way, which I would have a 1.7 code that a 1.7 JVM can understand perfectly fine and give me the 1.6 byte code. Generics are lost on Runtime and therefore their byte code might be made suitable for 1.4 if needed. What is cross compilation good for then? – Eyad Ebrahim Aug 19 '13 at 22:53
  • besides, there were lots of resource all over the internet saying it's possible: http://stackoverflow.com/questions/8970920/maven-javac-source-release-1-6-requires-target-release-1-6 http://fantom.org/sidewalk/topic/1765 this one suggests that it's possible to target 1.5 from 1.6 (totally) logical. which contradicts with the official documentation that you provided. I'm bedazzled here. – Eyad Ebrahim Aug 19 '13 at 23:11
  • Check this out, it will be helpful: http://stackoverflow.com/questions/1927594/is-is-possible-to-build-java-code-using-jdk-1-6-to-run-on-jre-1-5 – vinay Aug 20 '13 at 20:01
  • 3
    I still don't see the advantage of compiling a 1.6 source to a 1.7 bytecode. I see, and i need, the other way around. If oracle docs insisted on it, then who am I to judge that. Apparently other Java Compiler such as the Maven java compiler in the link I provide above, is capable of doing so for 1.6 to 1.5 (no proof of its capability of doing so for 1.7 to 1.6) but there is such a promise. – Eyad Ebrahim Aug 22 '13 at 11:04
  • @EyadEbrahim IDK if you ever made any other progress on this, but my understanding of the `-source` flag is that it tells the compiler to treat the source code as conforming to a certain version of Java. I wrote a basic hello world and used a 1.8 compiler to cross-compile for 1.7, then I ran it with 1.7. It worked: `javac -target 1.7 -source 1.7 -bootclasspath $HOME/programs/jdk1.8.0_202/jre/lib/rt.jar test.java`. – Ungeheuer Aug 21 '19 at 21:36
2

This is a limit in javac. Note that you could get away with just specifying "-target" (and not -source) in older versions of javac. You might still be able to.

You may want to consider using the Eclipse Java Compiler (ecj) which is available as a standalone compiler, as a maven plugin and which also can be used by the javac task in ant scripts.

See http://help.eclipse.org/indigo/topic/org.eclipse.jdt.doc.user/tasks/task-using_batch_compiler.htm for details.

Thorbjørn Ravn Andersen
  • 73,784
  • 33
  • 194
  • 347