MG2>quick comment below

________________________________
From: Russell Gold <russell.g...@oracle.com>
Sent: Thursday, April 12, 2018 2:43 PM
To: Maven Users List
Subject: Re: Building and unit-testing MR Jars, easily



> On Apr 12, 2018, at 1:58 PM, Martin Gainty <mgai...@hotmail.com> wrote:
>
>>        <plugin>
>>            <groupId>org.apache.maven.plugins</groupId>
>>            <artifactId>maven-antrun-plugin</artifactId>
>>            <executions>
>>                <execution>
>>                    <id>compile-java9</id>
>>                    <phase>compile</phase>
>>                    <configuration>
>>                        <tasks>
>>                            <mkdir dir="${java9.build.outputDirectory}" />
>>                            <javac srcdir="${java9.sourceDirectory}" 
>> destdir="${java9.build.outputDirectory}"
>>                                classpath="${project.build.outputDirectory}" 
>> includeantruntime="false" />
>>                        </tasks>
>>                    </configuration>
>>                    <goals>
>>                        <goal>run</goal>
>>                    </goals>
>>                </execution>
>>            </executions>
>>        </plugin>
> MG>looks similar to maven-compiler-plugin with srcdir / destdir /classpath 
> attrs..a bit more intuitive than maven-compiler-plugin
> <artifactId>maven-compiler-plugin</artifactId>
> <executions>
> <execution>
>  <id>default-compile</id>
>  <configuration>
>   <compilerArgs>
>    <srcdir>"${java9.sourceDirectory}</srcdir>
>    <destdir>"${java9.build.outputDirectory}"</destdir>
>    <classpath>${project.build.outputDirectory}</classpath>
>   </compilerArgs>


Part of that, I suspect, is ant’s use of attributes, which Maven generally 
shuns. If the Maven pom were recast to use attributes, and to infer groups, it 
could look something like:

        <plugin groupid="org.apache.maven.plugins" 
artifactid="maven-compiler-plugin" version="3.7.9">
            <execution id="java9" phase="compile" goals="compile">
                <configuration srcdir="${java9.sourceDirectory}" 
destdir="${java9.build.outputDirectory}" 
classpath="${java9.build.outputDirectory}"/>
            </execution>
        </plugin>

but that wasn’t the direction the designers took.

> ....
> MG>
>
>
> If you are actively working on adding MR capabilities to the compiler plugin, 
> is there something I can do to help?
>
> MG>initial evaluation would include what are advantages/disadvantages of MR

To a large extent, it is necessitated by the more rapid JDK changes which 
commenced with Jigsaw’s introduction in Java 9. Until then, while APIs were 
deprecated, they didn’t tend to go away a lot, and developers got used to using 
both deprecated APIs and internal ones. With Jigsaw, the JDK team started not 
only hiding the internal APIs, but also speeding up the pace of removal of 
features.

I’ve given an example at http://www.russgold.net/sw/2018/03/ch-ch-ch-changes/ 
<http://www.russgold.net/sw/2018/03/ch-ch-ch-changes/>

The basic problem is that some code that works in, say, Java 8, is no longer 
supported in Java 11, and the replacement isn’t available until Java 9. That 
means that you often cannot write one implementation that works for all JDK 
versions that mean to support. Nor can you use a conditional in your code, 
since the alternative implementations don’t even necessarily compile in the 
same JDK (the replacement feature just mentioned doesn’t compile in Java 8, and 
if you compile it for release 9, you cannot run it with Java 8. That means that 
you have to use some tricky reflection - or MR Jars.

I don’t know how common they will be. I maintainer nearly two dozen modules 
across several projects, and only two of them have needed this so far. It will 
really depend on how many more APIs get removed.

A related use case, of course, is that sometimes there are serious advantages 
in performance or resilience in using newer APIs, and MR Jars allow you to do 
that without dropping support for older JDK versions.

The main disadvantage, then, has been tool support. Maven doesn’t support them 
natively (nor does Gradle, and I cannot even imagine a clean way to add it 
there). Neither do any of the IDEs, which are almost certainly waiting on build 
tools to take the lead in defining the code layout. The workarounds have 
generally been partial solutions, counting on Maven to add support, but it has 
been painful to use them. That’s why I created this approach, which is mostly 
only painful when it comes to updating the parent POM.

MG2>from your website:
MG2>
"JEP-238<http://openjdk.java.net/jeps/238>. A problem, though, is that more 
than two years after this feature was announced, the tools still don’t actually 
provide much in the way of support. My next post will explore the current 
options"
MG2>
MG2>can you suggest current tools options which support JEP-238?

I should also note a disappointment with the JDK. Java 9 has a -release switch, 
which is intended to replace -source and -target, but it doesn’t quite match 
its intended use. If you run with -release 1.8, for example, you cannot compile 
against the Unsafe class, which is my approach needs to use toolchains. I 
expect that not everyone will have to do that, but it is a clear pain point for 
projects like Mockito, ByteBuddy, SimpleStub, and a number of others, which 
have been designed to do tricky code generation or field access.



>
>> On Apr 12, 2018, at 10:44 AM, Martin Gainty <mgai...@hotmail.com> wrote:
>>
>> MG>one-off request with ant only approach to compiling MR jars
>>
>> ________________________________
>> From: Russell Gold <russell.g...@oracle.com <mailto:russell.g...@oracle.com>>
>> Sent: Thursday, April 12, 2018 7:00 AM
>> To: Robert Scholte
>> Cc: Maven Users List
>> Subject: Re: Building and unit-testing MR Jars, easily
>>
>>
>>
>>> On Apr 11, 2018, at 12:36 PM, Robert Scholte <rfscho...@apache.org> wrote:
>>>
>>> On Wed, 11 Apr 2018 14:25:37 +0200, Russell Gold <russell.g...@oracle.com> 
>>> wrote:
>>>
>>>> Hi Robert,
>>>>
>>>> I used properties because I need to trigger multiple profiles, depending 
>>>> on whether we’re building the MR jar, and what JDK versions will be needed 
>>>> - and I can use them to turn profiles off, which I could not do by simply 
>>>> turning on a profile, as far as I know.
>>>
>>> Yes, you can turn off profiles by prefixing it with !,e.g. -P!someprofile
>>
>> That’s good to know. In this case, there are two profiles which are mutually 
>> exclusive. he multi-jar profile is activated when building an MR jar, and 
>> the test-toolchains-bypass profiles is run when NOT building an MR jar. I 
>> can do that with a single property. Is there a way to do that with a single 
>> -P switch?
>>>
>>>>
>>>> I didn’t consider test jars, and am not familiar with how they are used. 
>>>> Can you tell me more about them?
>>>
>>> https://maven.apache.org/plugins/maven-jar-plugin/examples/create-test-jar.html
>> How to create a jar containing test classes - Apache 
>> Maven<https://maven.apache.org/plugins/maven-jar-plugin/examples/create-test-jar.html
>>  
>> <https://maven.apache.org/plugins/maven-jar-plugin/examples/create-test-jar.html>>
>> maven.apache.org <http://maven.apache.org/>
>> When you want to create a jar containing test-classes, you would probably 
>> want to reuse those classes. There are two ways to solve this: Create an 
>> attached jar with the test-classes from the current project and loose its 
>> transitive test-scoped dependencies. Create a separate project with the test 
>> ...
>>
>>
>>
>>> The issue was exposed with 
>>> https://issues.apache.org/jira/browse/MCOMPILER-308 
>>> <https://issues.apache.org/jira/browse/MCOMPILER-308> 
>>> <https://issues.apache.org/jira/browse/MCOMPILER-308 
>>> <https://issues.apache.org/jira/browse/MCOMPILER-308>>
>>
>> That should be easy to fix. I just need to limit the configuration to the 
>> jar goal.
>>
>>>
>>>>
>>>> At present, the parent POM supports only up to JDK11, and doesn’t handle 
>>>> well cases where the main jar would be, say, JDK11. To some extent I see 
>>>> this as a stop gap. It is not clear to me if a better approach would start 
>>>> with an extension, or if there is any real long-term alternative to 
>>>> putting the changes into the compiler, surefire, and jar plugins.
>>>>
>>>> Unit testing is the default behavior. Toolchains are used to compile each 
>>>> version of the code with the correct compiler (since the source/target and 
>>>> release flags don’t quite duplicate doing so), and then surefire runs the 
>>>> tests with the jdk used to run Maven itself. Clearly, the documentation is 
>>>> lacking. But yes, you do need to run the build multiple times, since the 
>>>> code actually run can vary. If you are using Travis CI, that means that 
>>>> you need to configure the toolchains explicitly. I have not yet figured 
>>>> out how to do this with both oracle and open jdk options, since the 
>>>> toolchains seem to require you to make that choice in the pom, not just 
>>>> the JDK.
>>>
>>> Not sure if I understand. But you can add as much entries to both 
>>> <provides> in the toolchain.xml and inside the <jdk> element of the 
>>> maven-toolchains-plugin configuration. Only version has a special meaning.
>>> e.g. you can add <vendor>oracle</vendor> or <vendor>openjdk</vendor> to the 
>>> toolchain.xml and the plugin configuration. By adding it to the plugin you 
>>> say that at least version+vendor must be specified in the toolchain.xml 
>>> with matching values. The <provides> might have more elements, but these 
>>> are ignored.
>>
>> Thank you. There are some things I will experiment with, to see if I can 
>> handle more cases.
>>
>> BTW, I have posted a list of the other MR solutions that I know of at 
>> http://www.russgold.net/sw/2018/03/looking-for-mr-good-jar/ 
>> <http://www.russgold.net/sw/2018/03/looking-for-mr-good-jar/> 
>> <http://www.russgold.net/sw/2018/03/looking-for-mr-good-jar/ 
>> <http://www.russgold.net/sw/2018/03/looking-for-mr-good-jar/>>,
>> MG>With regards to "Use of the ant-plugin to compile the JDK 9 code"
>> MG>do you have a build.xml target we can use to backport features and 
>> functions of this target into maven-compiler-plugin
>> MG>possible trigger could be maven-compiler-plugin configuration of
>> MG><source>1.9</source> and/or
>> MG><target>1.9</target>
>>
>> along with my comments. As far as I know, mine is the only one that allows 
>> unit testing of the code for each JDK version.
>>
>>>
>>> thanks,
>>> Robert
>>>
>>>>
>>>> Thanks,
>>>> Russ
>>>>
>>>>> On Apr 4, 2018, at 3:11 PM, Robert Scholte <rfscho...@apache.org> wrote:
>>>>>
>>>>> Hi Russell, interesting approach.
>>>>>
>>>>> The difference between library developers and application developers 
>>>>> becomes more and more clear and this concept might be useful for library 
>>>>> builders.
>>>>> We should probably have a separate page for all the available solutions 
>>>>> and menion the pro's and cons.
>>>>>
>>>>> Just a few remarks: why are you using property enabled profiles instead 
>>>>> of -Pmulti-release?
>>>>> Be aware that you can also create test-jars, which should NOT have the 
>>>>> multi-release flag set in the MANIFEST.
>>>>>
>>>>> It will mean that you should provide a new version every every half year, 
>>>>> unless you already add all those versions right now ;)
>>>>>
>>>>> What I'm missing is a clear explanation how unit testing works. IIUC you 
>>>>> build the whole project with a specific JDK version and that's how the 
>>>>> matching unittests are executed. So you should run the build X times, 
>>>>> once for every multirelease version.
>>>>>
>>>>> thanks,
>>>>> Robert
>>>>>
>>>>>
>>>>> On Tue, 03 Apr 2018 21:42:39 +0200, Russell Gold 
>>>>> <russell.g...@oracle.com> wrote:
>>>>>
>>>>>> I have just developed a new and easier way for building MR Jars 
>>>>>> <https://github.com/meterware/multirelease-parent>, while waiting for 
>>>>>> the capability to be built into Maven.
>>>>>>
>>>>>> This approach is not only simple to set up (just use the designated 
>>>>>> parent POM, if you can), it lets you unit test for any supported JDK. 
>>>>>> For example:
>>>>>>
>>>>>> jdk7 && mvn -Dmulti_release clean test
>>>>>> jdk10 && mvn -Dmulti_release clean test
>>>>>>
>>>>>> where jdk7 and jdk10 set the appropriate versions for maven to use. 
>>>>>> Either will run against the appropriate additional code.
>>>>>>
>>>>>> To build an MR JAR you set a property on the command line
>>>>>>
>>>>>> mvn -Dmulti_release clean install
>>>>>>
>>>>>> which happens automatically when doing a release.
>>>>>>
>>>>>> I have also explained how it works at Easier Than It Looks 
>>>>>> <http://www.russgold.net/sw/2018/04/easier-than-it-looks/>
>>>>>>
>>>>
>>>>
>>>> ---------------------------------------------------------------------
>>>> To unsubscribe, e-mail: users-unsubscr...@maven.apache.org
>>>> For additional commands, e-mail: users-h...@maven.apache.org
>

Reply via email to