You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@maven.apache.org by "David M. Lloyd (Jira)" <ji...@apache.org> on 2023/11/08 19:53:00 UTC

[jira] [Commented] (SUREFIRE-1731) Unable to test Multi Release Jar with surefire or failsafe

    [ https://issues.apache.org/jira/browse/SUREFIRE-1731?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17784190#comment-17784190 ] 

David M. Lloyd commented on SUREFIRE-1731:
------------------------------------------

Just bumping this issue. There is a workaround, which is really ugly but *almost* does the job:

{code:xml}
        <!-- This profile is activated when Java 18 or later is used to test a project that supports Java 17 -->
        <profile>
            <id>java17-test</id>
            <activation>
                <jdk>[18,)</jdk>
                <property>
                    <name>java17.home</name>
                </property>
                <file>
                    <exists>${basedir}/build-test-java17</exists>
                </file>
            </activation>
            <build>
                <plugins>
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-surefire-plugin</artifactId>
                        <executions>
                            <execution>
                                <id>java17-test</id>
                                <phase>test</phase>
                                <goals>
                                    <goal>test</goal>
                                </goals>
                                <configuration>
                                    <jvm>${java17.home}/bin/java</jvm>
                                    <classesDirectory>${project.build.directory}/classes/META-INF/versions/17
                                    </classesDirectory>
                                    <additionalClasspathElements>
                                        <additionalClasspathElement>
                                            ${project.build.directory}/classes/META-INF/versions/16
                                        </additionalClasspathElement>
                                        <additionalClasspathElement>
                                            ${project.build.directory}/classes/META-INF/versions/15
                                        </additionalClasspathElement>
                                        <additionalClasspathElement>
                                            ${project.build.directory}/classes/META-INF/versions/14
                                        </additionalClasspathElement>
                                        <additionalClasspathElement>
                                            ${project.build.directory}/classes/META-INF/versions/13
                                        </additionalClasspathElement>
                                        <additionalClasspathElement>
                                            ${project.build.directory}/classes/META-INF/versions/12
                                        </additionalClasspathElement>
                                        <additionalClasspathElement>${project.build.outputDirectory}
                                        </additionalClasspathElement>
                                    </additionalClasspathElements>
                                </configuration>
                            </execution>
                        </executions>
                    </plugin>
                </plugins>
            </build>
        </profile>
{code}

The relevant part of this snippet is where we set up the class path. We "trick" surefire into prioritizing the highest layer by assigning it to the `classesDirectory`. Then, we add the remaining layers, plus the *original* project class path, as the final (lowest) layer.

This ugly trick works because the plugin just happens to support `additionalClassPathElement`. But, it has a major drawback: when you do this, the plugin can no longer find any `module-info.class` because it looks in the `classesDirectory` for it! So, any thusly configured executions will never run in module mode, making it impossible to test module mode execution and MR JAR output at the same time.

Back when I proposed (in MCOMPILER-320) that the compiler plugin get `additionalClassPathElements` support in order to support this use case, it was determined that this was not desirable, and instead the `multiReleaseOutput` switch was added to that plugin.

I propose that the solution to this issue is to add an analogous `multiReleaseOutput` switch which tells the Surefire plugin to correctly compose the class path and/or module path in such a way as to be multi-release aware.

> Unable to test Multi Release Jar with surefire or failsafe
> ----------------------------------------------------------
>
>                 Key: SUREFIRE-1731
>                 URL: https://issues.apache.org/jira/browse/SUREFIRE-1731
>             Project: Maven Surefire
>          Issue Type: Bug
>          Components: Maven Failsafe Plugin, Maven Surefire Plugin
>    Affects Versions: 2.22.2, 3.0.0-M4
>            Reporter: John Patrick
>            Priority: Major
>
> I'm creating a Multi Release jar, containing base Java 1.8 and Java 11 classes. But am not able to successful test the Java 11 part.
> In the following repo, I've got 3 tests.
>  * 1 test needs to be executed using Java 1.8 that are under src/test/java.
>  * 2 tests need to be executed using Java 11 that are under src/test/java11.
> If the src/test/java tests are executed using Java 11 I expect it to fail which is expected, because it would be picking up the classes under target/classes/META-INF/versions/11/ and not the Java 1.8 version under target/classes/. Because the tests have been written to prove the correct source file is used for execution so the Java 1.8 BaseClass returns a different string to the Java 11 BaseClass.
> [https://github.com/nhojpatrick/issue-maven-multi-release-jar-testing]
>  



--
This message was sent by Atlassian Jira
(v8.20.10#820010)