#1765 Building Fantom using Oracle JDK 7 fails with "javac: target release 1.5 conflicts with default source release 1.7"

StephenViles Wed 1 Feb 2012

$ rel/bin/fan `cygpath -w rel/adm/bootstrap.fan`

Bootstrap Environment:
  hgRepo:    http://hg.fantom.org/repos/fan-1.0
  hgVer:     Mercurial Distributed SCM (version 2.0.2)
  jdkVer:    javac 1.7.0_02 (need 1.6+)
  jdkHome:   file:/C:/jdk1.7.0_02/
  relVer:    1.0.61
  relHome:   file:/C:/cygwin/home/sviles/fantom/fantom-1.0.61/
  devHome:   file:/C:/cygwin/home/sviles/fantom/fan/

Continue with these settings? [y|n] y

hg pull -u http://hg.fantom.org/repos/fan-1.0
real URL is http://hg.fantom.org/fan-1.0
pulling from http://hg.fantom.org/repos/fan-1.0
searching for changes
no changes found

Config etcs:
  C:\cygwin\home\sviles\fantom\fantom-1.0.61\etc\build\config.props: devHome=`file:/C:/cygwin/home/sviles/fantom/fan/`
  C:\cygwin\home\sviles\fantom\fantom-1.0.61\etc\build\config.props: jdkHome=`file:/C:/jdk1.7.0_02/`
  C:\cygwin\home\sviles\fantom\fan\etc\build\config.props: jdkHome=`file:/C:/jdk1.7.0_02/`

C:\cygwin\home\sviles\fantom\fantom-1.0.61\bin\fan.exe C:\cygwin\home\sviles\fantom\fan\src\buildall.fan superclean
Delete [file:/C:/cygwin/home/sviles/fantom/fan/lib/fan/]
Delete [file:/C:/cygwin/home/sviles/fantom/fan/src/sys/java/temp/]
BUILD SUCCESS [19ms]!

C:\cygwin\home\sviles\fantom\fantom-1.0.61\bin\fan.exe C:\cygwin\home\sviles\fantom\fan\src\buildboot.fan compile
compile [sys]
  Compile [sys]
    FindSourceFiles [77 files]
    WritePod [file:/C:/cygwin/home/sviles/fantom/fan/lib/fan/sys.pod]
compile [java]
  CreateDir [file:/C:/cygwin/home/sviles/fantom/fan/src/sys/java/temp/]
  CompileJava
javac: target release 1.5 conflicts with default source release 1.7
ERR: CompileJava failed
BUILD FAILED [1588ms]!
##
## FATAL: src/buildboot.fan compile failed
##

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:

$ javac -version
javac 1.7.0_02
$ javac CompileTest.java
$ javac -target 1.5 CompileTest.java
javac: target release 1.5 conflicts with default source release 1.7
$ javac -target 1.6 CompileTest.java
javac: target release 1.6 conflicts with default source release 1.7
$ javac -source 1.7 -target 1.5 CompileTest.java
javac: source release 1.7 requires target release 1.7
$ javac -source 1.6 -target 1.5 CompileTest.java
javac: source release 1.6 requires target release 1.6

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

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.

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 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

  1. Remove -target 1.5. Unless you have a very wonderful reason why you are targeting 1.5 this seems a good choice.
  2. 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.

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).

// 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

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

Login or Signup to reply.