Op Mon, 01 Dec 2014 10:23:09 +0100 schreef Mark Struberg <strub...@yahoo.de>:

The issue is that there are classes which generate a different signature

when compiled with the Java 8 RT vs when compiled with the Java 7 RT.


+1


I think what we - as a community - are learning is that we no longer

have the luxury of compiling with a newer JDK against an older target...


+1



I don't fully agree with the other summary though.
I think we have a better option but we need to work it out a bit.

The ToolchainManager really looks like a nice way we could probably do that. Usually a project would not care much which JDK version is installed, but by using the toolchains.xml we have a way to declare the exact environment one likes to use. That way one can define that a certain Java7 and Java8 JDK should be used. Currently this needs an explicit configuration of the maven-toolchain-plugin, and there is also no way to 'enforce' a specific setup to be done. E.g. that someone needs to have the toolchains.xml and the 1.6 and 1.8 JDKs needs to be in there.

There are 2 things I like to improve:

1.) enhance enforcer rules to include toolchains.xml or make maven itself handle it 2.) enhance the ToolchainManager to let lookup configured Toolchains and use this in maven-compiler-plugin and maven-test-plugin to use a 'preferred' Toolchain version. E.g. if target=1.7 is defined it should try to resolve this Toolchain.

AFAIK, 2 is already implemented. However, I think that it based on first match, not on best match, so the user is responsible for the order. So that could be a good improvement. If you specify a version, it'll be handled like versions and versions ranges as can be done for dependencies.
So you probably want to lock the version as [1.7,1.8).

Robert



I also like to give you a sample usage what I like to be able.
In Apache OpenJPA we currently have an issue with Entities using Java8 Lambdas and Streaming API. The enhancement is broken for them. But I'm currently not able to define an additional module which uses Java8 and contains those Java8 feature tests. If I would add such a Java8 test module then I would today need to build the whole application with Java8. But then the aforementioned bytecode issues would appear.


Most of this is already possible today with Toolchains. Just explicitly use the maven-toolchains-plugin in your pom and make sure the toolchains.xml is setup correctly. Of course both of it should just be one or two lines in the poms in the future. And I would love to have a switch in my project to make the toolchains.xml and some well specified Toolchains mandatory for it. And ideally with a link to our page describing how to setup toolchains.xml...


LieGrue,
strub




On Sunday, 30 November 2014, 12:58, Stephen Connolly <stephen.alan.conno...@gmail.com> wrote:

Jochen,


I think you misunderstand the problem.


The issue is that there are classes which generate a different signature when compiled with the Java 8 RT vs when compiled with the Java 7 RT.


For example, you could have a method that takes a String parameter in Java 7 and was widened to take a CharSequence in Java 8.


If your code calls that method with a String, you'd think you'd be ok...


Compiling against Java 7 will embed the call to the String parameter method


Compiling against Java 8, even with -target 7 will embed a call to the CharSequence parameter method and you will get a method not found when running against Java 7.


Now this could be viewed a bug in the Java 8 runtime, as to retain strict support for compiling against 8 and running on 7 you would need to add the wider method, not widen the parameter of the existing method... but Java does not make such a promise... the -target is a convenience only.


Now animalsniffer would catch the kind of issue I describe above... but there are more subtle issues, e.g. where there are methods moved to default methods on an interface, etc.


These all affect the bytecode.


I think what we - as a community - are learning is that we no longer have the luxury of compiling with a newer JDK against an older target... we will have to stick to compiling with the oldest JDK that we support as a runtime... yes we can fall back to -target, animalsniffer and friends, but realistically we need to switch to either aggressively upping the minimum or we need to get better protections in place with regards to central and the java runtime that was used on the compile classpath.

We may need to push POM 5.0.0 sooner or risk Central becoming unusable with anything other than the latest JDK (as you have no way of knowing if you'll get bitten with your dependencies compiled using a newer JDK and an old -target and thus embedding the bad usage)


Or maybe we can improve animal sniffer to help us detect those issues


On 30 November 2014 at 11:33, Jochen Wiedmann <jochen.wiedm...@gmail.com> wrote:

I'd solve your problem like this, Mark:

- Create an interface for a component, which is internally using the
JDK code in question, (say IRTUser).
- Create three implementations, each of which are targeting a
particular JDK. In what follows, I'll assume that they throw an
exception when being instantiated on the wrong JDK.
- Ideally, these implementations must be compilable with different
JDK'S. (If required, use Java reflection internally to find the right
methods, etc. (The above method would be a MethodNotFoundException, or
the like.)
- Have a factory class, with code like the following:

   private static final IRTUser instance = newRTUser();

   private static IRTUser newInstance() {
     try {
       return new JDK18RTUser();
     } catch (Throwable t0) {
       try {
         return new JDK17RTUser();
       } catch (Throwable t1) {
         return new JDK16RTUser();
       }
    }

  public static IRTUser getInstance() { return instance; }

This approach has worked fine for me on multiple occasions.


Jochen




On Thu, Nov 27, 2014 at 9:39 PM, Mark Struberg <strub...@yahoo.de> wrote:
Hi!

Today I had a discussion with Robert about how we can solve a problem I had over at Apache OpenWebBeans:

https://issues.apache.org/jira/browse/OWB-952

As a short summary: the classes provided in rt.jar of Java8 are slightly different than the ones from Java7 and 6. Similar big differences have been seen in the Java4 to 5 transition. Thus if you compile your project with Java8 you might get different bytecode than when compiling with Java7 JDK. Even if you use target=1.7 in both cases.

There are 2 options: either use javac -bootclasspath and point it to the 'correct' rt.jar + other jdk libs, or just switch the whole environment.

Roberts suggestion was to use the Maven Toolchain system:http://maven.apache.org/plugins/maven-toolchains-plugin/
http://maven.apache.org/plugins/maven-toolchains-plugin/toolchains/jdk.html


We also elaborated about improving the Toolchain lookup in our maven-compiler-plugin:
http://maven.apache.org/plugins/maven-compiler-plugin/xref/org/apache/maven/plugin/compiler/AbstractCompilerMojo.html#427

This could get improved to first check if a toolchain is registered for the <target> version used in the m-compiler-p. And if there is no toolchain configured especially for this version then we fallback to the one if we don't specify a version.
The effective lookup path would then be
1.) toolchain configured via maven-toolchain-plugin
2.) toolchain with specified target version
3.) default toolchain


I think we would need to slightly enhance the ToolchainManager, but first would like to get some feedback.


LieGrue,
strub

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@maven.apache.org
For additional commands, e-mail: dev-h...@maven.apache.org




--
Our time is just a point along a line that runs forever with no end.
(Al Stewart, Lord Grenville)


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@maven.apache.org
For additional commands, e-mail: dev-h...@maven.apache.org






---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@maven.apache.org
For additional commands, e-mail: dev-h...@maven.apache.org

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@maven.apache.org
For additional commands, e-mail: dev-h...@maven.apache.org

Reply via email to