We target the Fantom classfiles to be 1.5 compatible. If you are using 1.6, you can still generate 1.5 classfiles. However it appears to be that 1.7 javac doesn't support that capability yet.
Since I haven't tried out anything with 1.7, I would suggest the safest is to install and use 1.6
StephenVilesWed 1 Feb 2012
I tried setting the javac source parameter, without success:
Yes, it looks like we'll need to stick with JDK 1.6.
dobesvThu 2 Feb 2012
Did you try
javac -source 1.5 -target 1.5 ? Based on the error message it seems to be complaining about a mistmatch between source and target. I have 1.6 here so I can't test that myself.
StephenVilesFri 17 Feb 2012
Did you try javac -source 1.5 -target 1.5 ?
I haven't tried to build Fantom using -source 1.5 as the Bootstrap doc page says:
NOTE: you need JDK 1.6 to recompile Fantom. However only 1.5 is required to run Fantom.
dobesvFri 9 Mar 2012
Ah now I am in the same boat. I'll see if I can figure out the solution, since I want to use the 1.7 Async I/O APIs.
dobesvFri 9 Mar 2012
Oh my solution is to not use the compileJava step at all, just remove javaDirs from the build.fan. I didn't need any .java files for my pod after all.
dobesvFri 9 Mar 2012
Well I thought I'd dig into this a bit more and after some experimentation my conclusion is that they've changed how they handle the -target option a bit; specifically, they used to automatically specify -source 1.5 if you specify -target 1.5 and they don't do that any more; instead they automatically specify -target 1.5 if you specify -source 1.5.
What-source 1.5 -target 1.5 actually do
When you do this kind of "cross-compiling" it will generate bytecode compatible with the target JVM, and it will restrict the source language to features supported in that version of Java. You can specify a source version earlier or equal to the target version; you cannot use 1.6 language features and output 1.5 compatible bytecode but you can restrict the code to 1.5 language features and output 1.6 style bytecode.
If you specify appropriate -bootclasspath and -extdirs options pointing to older versions of the rt.jar and friends in it you will get compile errors if you try to use classes or methods added after JDK 1.5. If you don't specify the -bootclasspath and -extdirs this way you'll get an error at runtime if you try to use classes or methods not available in JDK 1.5 AND you actually run the app in JRE 1.5.
If you intend to run your stuff on a 1.5 JRE then specifying the -bootclasspath and -extdirs is probably necessary. If not, you're probably wasting your time with cross-compiling anyway (what other reason do you have to cross-compile if not to run your code on a 1.5 JVM?).
Possible Solutions
Remove -target 1.5. Unless you have a very wonderful reason why you are targeting 1.5 this seems a good choice.
Put in -source 1.5 to match the target version. If you only wanted 1.5 bytecode for some reason but don't intend to run the code on JDK 1.5 this should be good enough. If you do intend to run the code on a 1.5 JDK then adding -bootclasspath and -extdirs options should be done to avoid mysterious errors on JRE 1.5.
brianFri 9 Mar 2012
Well that is interesting regarding how those flags work in JDK 7.
Here is the deal: Fantom needs to run on Java 5 runtimes, there is still a ton of that out there. However I do make use of some Java 6 APIs (such as MAC address access for UUIDs), but these APIs gracefully degrade when running on Java 5. So for simplicity I think we just need to stick with requiring JDK 6 to recompile Fantom from source.
That restriction only applies if recompiling Fantom from source. Fantom already runs just fine on Java 7 runtime. In fact that is the runtime I primarily use myself.
dobesvSat 10 Mar 2012
How about this: when building Fantom, specify -source 1.5 -target 1.5. For our own modules I think you should not pass this parameter (currently you're applying this to all java code built using Fantom).
I suppose you can detect NoSuchMethod and ClassNotFound problems when running on Java 5 systems by running your unit tests using JRE 5 to see if they are passing or if they are throwing those exceptions. However, another way to do it would be to actually build using the Java 5 runtime jars and replace uses of Java 6/7 APIs with reflection. This would give you a better compile-time check on your library usage.
tcolarFri 22 Jun 2012
FYI: The same issue seem to arise if there is any native java in the project (javaNative) .... compilation fails with the same error.
So t's not really unique to compiling the Fantom sources,
AkcelistoFri 21 Sep 2012
How to solve this problem? I cant compile Tales.
JonasLTue 25 Dec 2012
I spent some time getting this to work, hopefully it'll help someone else (tried to build tales with jdk 1.7 - failed on 1.5 target error):
The problem with the flag is that it's compiled to fcode in the build.pod. So to change it, you need to edit the CompileJava task and recompile the build.pod
Get the distribution, unpack it. In the src/build/fan/tasks/CompileJava.fan edit the Str[] params := ["-target", "1.5"]. I dropped the line completely but you can change it to the recommendations above too, whatever fits your needs.
Edit the <fantom-dist-home>/etc/build/config.props and Set the devHome to the full path of the same dist devHome=<fantom-dist-path>
Then rebuild the build pod: fan src/build/build.fan compile
Make sure the build.pod file goes into your main fan distribution lib/fan/build.pod so you're using it when building other project (e g tales)
Now you should be able to build other projects with native java code with a jdk 1.7
brianThu 27 Dec 2012
I think it might be nice to have a flag or something in build/config.props. It seems like this issue keeps biting a lot of people. I want to keep building distro with 1.5 compatibility, but I'm sure most people are now using 1.7
JonasLFri 28 Dec 2012
Yeah, that would be nice.. the default JDK installation on at least Ubuntu is 1.7 now, and having several JDKs side by side is a bit painful in getting the paths right.
brianWed 2 Jan 2013
Okay I pushed a change that defaults the javac parameters from a build config prop (which means you can also use an environment variable).
// JVM version compiler target, by default Fantom requires a JDK 1.6
// compiler that targets 1.5. To use JDK 1.7, this property needs to
// be cleared or set the env var FAN_BUILD_JAVACPARAMS to a space
javacParams=-target 1.5
JonasLFri 4 Jan 2013
Great, thanks a lot Brian
elyashivSun 27 Sep 2015
Can you please add this to the documentation for Bootstrap? I have been looking for the problem for some time...
brianMon 28 Sep 2015
I pushed a fix to the docs and also to reference the proper repo. Sorry about that, but thanks for pointing those details out to us
StephenViles Wed 1 Feb 2012
brian Wed 1 Feb 2012
We target the Fantom classfiles to be 1.5 compatible. If you are using 1.6, you can still generate 1.5 classfiles. However it appears to be that 1.7 javac doesn't support that capability yet.
Since I haven't tried out anything with 1.7, I would suggest the safest is to install and use 1.6
StephenViles Wed 1 Feb 2012
I tried setting the javac
source
parameter, without success:Yes, it looks like we'll need to stick with JDK 1.6.
dobesv Thu 2 Feb 2012
Did you try
javac -source 1.5 -target 1.5 ? Based on the error message it seems to be complaining about a mistmatch between source and target. I have 1.6 here so I can't test that myself.
StephenViles Fri 17 Feb 2012
I haven't tried to build Fantom using
-source 1.5
as the Bootstrap doc page says:dobesv Fri 9 Mar 2012
Ah now I am in the same boat. I'll see if I can figure out the solution, since I want to use the 1.7 Async I/O APIs.
dobesv Fri 9 Mar 2012
Oh my solution is to not use the compileJava step at all, just remove javaDirs from the build.fan. I didn't need any .java files for my pod after all.
dobesv Fri 9 Mar 2012
Well I thought I'd dig into this a bit more and after some experimentation my conclusion is that they've changed how they handle the
-target
option a bit; specifically, they used to automatically specify-source 1.5
if you specify-target 1.5
and they don't do that any more; instead they automatically specify-target 1.5
if you specify-source 1.5
.What
-source 1.5 -target 1.5
actually doWhen you do this kind of "cross-compiling" it will generate bytecode compatible with the target JVM, and it will restrict the source language to features supported in that version of Java. You can specify a source version earlier or equal to the target version; you cannot use 1.6 language features and output 1.5 compatible bytecode but you can restrict the code to 1.5 language features and output 1.6 style bytecode.
If you specify appropriate
-bootclasspath
and-extdirs
options pointing to older versions of the rt.jar and friends in it you will get compile errors if you try to use classes or methods added after JDK 1.5. If you don't specify the-bootclasspath
and-extdirs
this way you'll get an error at runtime if you try to use classes or methods not available in JDK 1.5 AND you actually run the app in JRE 1.5.If you intend to run your stuff on a 1.5 JRE then specifying the
-bootclasspath
and-extdirs
is probably necessary. If not, you're probably wasting your time with cross-compiling anyway (what other reason do you have to cross-compile if not to run your code on a 1.5 JVM?).Possible Solutions
-target 1.5
. Unless you have a very wonderful reason why you are targeting 1.5 this seems a good choice.-source 1.5
to match the target version. If you only wanted 1.5 bytecode for some reason but don't intend to run the code on JDK 1.5 this should be good enough. If you do intend to run the code on a 1.5 JDK then adding-bootclasspath
and-extdirs
options should be done to avoid mysterious errors on JRE 1.5.brian Fri 9 Mar 2012
Well that is interesting regarding how those flags work in JDK 7.
Here is the deal: Fantom needs to run on Java 5 runtimes, there is still a ton of that out there. However I do make use of some Java 6 APIs (such as MAC address access for UUIDs), but these APIs gracefully degrade when running on Java 5. So for simplicity I think we just need to stick with requiring JDK 6 to recompile Fantom from source.
That restriction only applies if recompiling Fantom from source. Fantom already runs just fine on Java 7 runtime. In fact that is the runtime I primarily use myself.
dobesv Sat 10 Mar 2012
How about this: when building Fantom, specify
-source 1.5 -target 1.5
. For our own modules I think you should not pass this parameter (currently you're applying this to all java code built using Fantom).I suppose you can detect NoSuchMethod and ClassNotFound problems when running on Java 5 systems by running your unit tests using JRE 5 to see if they are passing or if they are throwing those exceptions. However, another way to do it would be to actually build using the Java 5 runtime jars and replace uses of Java 6/7 APIs with reflection. This would give you a better compile-time check on your library usage.
tcolar Fri 22 Jun 2012
FYI: The same issue seem to arise if there is any native java in the project (javaNative) .... compilation fails with the same error.
So t's not really unique to compiling the Fantom sources,
Akcelisto Fri 21 Sep 2012
How to solve this problem? I cant compile
Tales
.JonasL Tue 25 Dec 2012
I spent some time getting this to work, hopefully it'll help someone else (tried to build tales with jdk 1.7 - failed on 1.5 target error):
The problem with the flag is that it's compiled to fcode in the build.pod. So to change it, you need to edit the CompileJava task and recompile the build.pod
Get the distribution, unpack it. In the src/build/fan/tasks/CompileJava.fan edit the
Str[] params := ["-target", "1.5"]
. I dropped the line completely but you can change it to the recommendations above too, whatever fits your needs.Edit the <fantom-dist-home>/etc/build/config.props and Set the devHome to the full path of the same dist
devHome=<fantom-dist-path>
Then rebuild the build pod:
fan src/build/build.fan compile
Make sure the build.pod file goes into your main fan distribution lib/fan/build.pod so you're using it when building other project (e g tales)
Now you should be able to build other projects with native java code with a jdk 1.7
brian Thu 27 Dec 2012
I think it might be nice to have a flag or something in build/config.props. It seems like this issue keeps biting a lot of people. I want to keep building distro with 1.5 compatibility, but I'm sure most people are now using 1.7
JonasL Fri 28 Dec 2012
Yeah, that would be nice.. the default JDK installation on at least Ubuntu is 1.7 now, and having several JDKs side by side is a bit painful in getting the paths right.
brian Wed 2 Jan 2013
Okay I pushed a change that defaults the javac parameters from a build config prop (which means you can also use an environment variable).
JonasL Fri 4 Jan 2013
Great, thanks a lot Brian
elyashiv Sun 27 Sep 2015
Can you please add this to the documentation for Bootstrap? I have been looking for the problem for some time...
brian Mon 28 Sep 2015
I pushed a fix to the docs and also to reference the proper repo. Sorry about that, but thanks for pointing those details out to us