Which JDK's distributions can run `javac -source 1.6 -target 1.5`?
Asked Answered
M

2

4

NOTE: Please do not comment on all the perils of cross-compiling. Thank you.


I have a situation where we need to have Java 6 source compiled for a Java 5 JVM (to be sure that JAX-WS usage is correct). Previously we have done this with ant ant script (which apparently can), but after migrating to Maven we have found that it ends up with javac complaining:

$ javac -source 1.6 -target 1.5
javac: source release 1.6 requires target release 1.6

Is there any Java distribution for Linux (Ubuntu 11.10, x86) where the javac can do this?


EDIT: It appears not, as the limitation is in javac which is the same. The solution (which made this need go away) was to change from the default javac compiler to the eclipse compiler in maven-compiler-plugin.


EDIT: I've found that the Eclipse compiler generates byte code for anonymous inner classes that the javadoc utility disagrees with. I am preparing a bug report for this issue.

Mashe answered 13/2, 2012 at 12:23 Comment(11)
How is this question different from your other one regarding this: #8971420Relucent
Why do you need the source param? Are using any class not available in Java5?Maible
@Thorbjørn Ravn Andersen: if you compile with -target 1.5, then how would you know that, say, a ConcurrentSkipListSet doesn't exist on 1.5? Now we do need to support older OS X machines that do not (and will never) have Java 6, but we simply use a JDK1.5 compiler and this is convenient because we get: "cannot find symbol: class ConcurrentSkipListSet" (actually IntelliJ is set to 1.5 but whatever, it's just an example). If you need to target 1.5 JVMs, wouldn't compiling your source with a JDK1.5 compiler be an option? (oh, you want to keep Override, you commented that in your own dupe)Fayfayal
@PeterLiljenberg the other question is a maven question. See?Typewrite
@user988052 This is not a problem. Do you have any input on what I actually ask? (and, no, this is not a dupe)Typewrite
@ThorbjørnRavnAndersen I disagree, the problem is not maven it's the JDK (javac specifically). The question is basically the same since maven will just delegate to javac to do the compilation (unless you tell it otherwise). I think your only shoot at fixing this would be to write your own version of javac using the Java Compiler API. docs.oracle.com/javase/6/docs/api/javax/tools/JavaCompiler.htmlRelucent
@PeterLiljenberg the problem is triggered by Maven. This, however, is to see if I can fix our Jenkins instance running on Ubuntu, or if I must create a work around.Typewrite
@ThorbjørnRavnAndersen in your other post you references Ant, did it actually work there?Relucent
@PeterLiljenberg I am not interested in discussing ant or maven here, just if there is a Linux distribution where javac can do this. If you want to discuss ant or maven, please do it in the question where I ask about that. Thank you.Typewrite
Why do you need -source 1.6 and can't use -source 1.5? Java Programming Language Enhancements says No language changes were introduced in Java SE 6.Jiles
@PaŭloEbermann the ‘@Override‘ annotation changed semantics making programs more robust.Typewrite
K
6

According to the documentation (Java 5, Java 6), the Oracle SDK should be able to do this when you follow the instructions in the Cross-Compilation Example.

Java 6 should support any version between 1.3 to 1.6 as -target; it doesn't say anything what happens when you use generics and other "compatible" features in the source. The compiler should be able to strip them.

Another culprit in the game might be javac: The compiler might be able to handle this set of arguments but the command line tool might take offense.

In this case, write your own command line using the Java Compiler API. That might allow to pull of some tricks that you can't achieve otherwise.

You can also try the Eclipse compiler (see "Using the batch compiler").

This might fail because of how Java works: Java X code can run on Java Y as long as X <= Y. So while you can easily compile Java 1.4 code for a Java 6 VM, the reverse is not always true.

If everything else fails, write a preprocessor that reads the source and strips unsupported elements (like @Override on interfaces). As long as you compile the code with the annotations once in a while with Java 6, the converted code should be safe as well (unless your code stripper has a bug ...)

Katerinekates answered 13/2, 2012 at 13:23 Comment(20)
Alas, regardless of what it should, it doesn't, and yes, the culprit is javac. Do you have any suggestions on a Linux JDK distribution where javac does not report this error?Typewrite
I do a lot of strange things with Java and I haven't heard of a single SDK which can automatically "downgrade" source code. Hence my other suggestions. That said, if you want to invest the time, the Eclipse compiler is probably your best bet because it comes with full source. You could hack it to do what you want - if it can't already.Katerinekates
The javac task in ant can do it. It most likely does not invoke javac as an application but through some API in tools.jar, but I have not investigated it.Typewrite
That's the compiler API which I mentioned. You should get the same result in Maven if you set fork to false. If that doesn't work, have a look at the antrun plugin for Maven (maven.apache.org/plugins/maven-antrun-plugin) which allows you to run a single Ant task. Disable the standard compiler plugin and you should be good.Katerinekates
@ThorbjørnRavnAndersen how was the javactask configured? According to the docs the source parameter is ignored for most of the compilers: "Value of the -source command-line switch; will be ignored by all implementations prior to javac1.4 (or modern when Ant is not running in a 1.3 VM), gcj and jikes."Relucent
You can see that if you run ant with -debug (and maybe -verbose, too)Katerinekates
I would appreciate any "how can I fix Maven or ant" help (which is very appreciated) to go in that question (and commentary to be moved over there too). Here I would just like answers to what I actually ask go. Thank you.Typewrite
I've ended up with using the Eclipse batch compiler through the maven -compiler-plugin. This removes the need for an alternative javac.Typewrite
It appeared that the standard ecj bundled did not get line numbers correct in the debug information embedded in the classfile. We reverted to javac + pure java 5 until I have time to investigate details.Typewrite
The version of ecj in the maven-compiler-plugin is very old. Get a new copy from a recent Eclipse installation and use either ant to start it or "ant-run" and disable the maven-compiler-plugin. PS: One of the reasons why I didn't update my answer, yet, is that we haven't figured out the correct solution.Katerinekates
I found that there was a newer version of the nexus compiler plugin which worked better.Typewrite
@ThorbjørnRavnAndersen: Which version is that?Katerinekates
@AaronDigulla maven-compiler-plugin 3.0 with plexus-compiler-eclipse 2.1 - I have not yet looked into what ecj version they use, but it supports Java 1.7 source. On an unrelated note, I was wondering if you were interested in dusting off dsmp - it would be nice if it was easy to install directly through maven.Typewrite
@ThorbjørnRavnAndersen: dsmp is a stand-alone Java program. There is nothing to install. Just download the JAR, create the config file and start it. I don't see how the effort to turn it into a Maven plugin could make anything easier :-)Katerinekates
To answer my own question: plexus-compiler-eclipse 2.1 and 2.2 depend on org.eclipse.jdt.core 3.8.1 from 2012 (Juno, a.k.a e4 4.2.1)Katerinekates
@AaronDigulla not a maven plugin, just a maven artifact on Maven central.Typewrite
@ThorbjørnRavnAndersen: Sorry, I completely fail to see any advantage in doing that. You can't really use Maven to download it and you would still have to invoke it manually as a standalone Java application. I would have to go through the Central deployment process for no gain. Am I missing something?Katerinekates
This answer really should be updated. Oracle SDK or other SDKs cannot do this, Compiler API, ant task using that api or Eclipse compiler can do it. Those are really pretty much the only options AFAIK.Couch
@eis: I can't really try the different options. If you posted an answer with working code, I'd upvote that.Katerinekates
@AaronDigulla added now.Couch
C
1

This answer is an implementation of what @ThorbjørnRavnAndersen explained in the comments as a solution. Using the example code from here, and fixing a few typos, I was able to come up with an example using Eclipse Compiler.

Calculator.java

package example;

// there needs to be a package to avoid A "@WebService.targetNamespace must be specified on classes with no package"
// when running this

import javax.jws.WebService;
import javax.jws.WebMethod;
import javax.xml.ws.Endpoint;

@WebService
public class Calculator {
    @WebMethod
    public int add(int a, int b) {
        return a+b;
    }

    public static void main(String[] args){
        // create and publish an endpoint
        Calculator calculator = new Calculator();
        Endpoint endpoint = Endpoint.publish("http://localhost:8080/calculator", calculator);        
    }
}

pom.xml

<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>fi.eis.applications</groupId>
  <artifactId>ws-calculator</artifactId>
  <version>1.0-SNAPSHOT</version>
  <build>
    <plugins>
      <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.3</version>
        <configuration>
          <source>1.6</source>
          <target>1.5</target>
          <compilerId>eclipse</compilerId>
        </configuration>
        <dependencies>
          <dependency>
            <groupId>org.codehaus.plexus</groupId>
            <artifactId>plexus-compiler-eclipse</artifactId>
            <version>2.6</version>
          </dependency>
        </dependencies>
      </plugin>
    </plugins>
  </build>
</project>

That you can compile with mvn clean compile and then run with java Calculator on the target/classes/example folder. It will start up a web service on port 8080, which you can test with url http://localhost:8080/calculator?wsdl on your browser.

Couch answered 20/9, 2015 at 8:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.