Skip to content

Commit

Permalink
[MJLINK-83] Implement multiple launcher elements (#202)
Browse files Browse the repository at this point in the history
* [MJLINK-83] Implement multiple launcher elements

* Add tests
  • Loading branch information
pedro-w authored Jul 18, 2024
1 parent ff0ddd1 commit e554ca5
Show file tree
Hide file tree
Showing 2 changed files with 138 additions and 3 deletions.
27 changes: 24 additions & 3 deletions src/main/java/org/apache/maven/plugins/jlink/JLinkMojo.java
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,17 @@ public class JLinkMojo extends AbstractJLinkMojo {
@Parameter
private String launcher;

/**
* Specify one or more launchers for jlink.
* The command line equivalent is:
* <code>--launcher &lt;name&gt;=&lt;module&gt;[/&lt;mainclass&gt;]</code>.
* The valid values are a list of
* <code>&lt;name&gt;=&lt;module&gt;[/&lt;mainclass&gt;]</code> terms,
* separated by commas.
*/
@Parameter
private List<String> launchers;

/**
* These JVM arguments will be appended to the {@code lib/modules} file.<br>
* <strong>This parameter requires at least JDK 14.<br></strong>
Expand Down Expand Up @@ -633,7 +644,8 @@ private void ifOutputDirectoryExistsDelteIt() throws MojoExecutionException {
}
}

protected List<String> createJlinkArgs(Collection<String> pathsOfModules, Collection<String> modulesToAdd) {
protected List<String> createJlinkArgs(Collection<String> pathsOfModules, Collection<String> modulesToAdd)
throws MojoExecutionException {
List<String> jlinkArgs = new ArrayList<>();

if (stripDebug) {
Expand All @@ -656,8 +668,17 @@ protected List<String> createJlinkArgs(Collection<String> pathsOfModules, Collec
jlinkArgs.add(compress);
}
if (launcher != null) {
jlinkArgs.add("--launcher");
jlinkArgs.add(launcher);
if (launchers != null) {
throw new MojoExecutionException("Specify either single <launcher> or multiple <launchers>, not both.");
} else {
launchers = List.of(launcher);
}
}
if (launchers != null) {
for (String item : launchers) {
jlinkArgs.add("--launcher");
jlinkArgs.add(item);
}
}
if (addOptions != null && !addOptions.isEmpty()) {
jlinkArgs.add("--add-options");
Expand Down
114 changes: 114 additions & 0 deletions src/test/java/org/apache/maven/plugins/jlink/MultipleLauncherTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.maven.plugins.jlink;

import java.lang.reflect.Field;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.apache.maven.plugin.MojoExecutionException;
import org.junit.jupiter.api.Test;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;

public class MultipleLauncherTest {
@Test
void testSingleLauncher() throws Exception {
// It's OK to specify one launcher with "<launcher>"
// given
JLinkMojo mojo = new JLinkMojo();
Field launcher = mojo.getClass().getDeclaredField("launcher");
launcher.setAccessible(true);
launcher.set(mojo, "l=com.example.Launch");

// when
List<String> jlinkArgs = mojo.createJlinkArgs(List.of(), List.of());

// then
assertThat(launched(jlinkArgs)).contains("l=com.example.Launch");
}

@Test
void testOneMultipleLauncher() throws Exception {
// It's OK to specify one launcher with "<launchers>"
// given
JLinkMojo mojo = new JLinkMojo();
Field launchers = mojo.getClass().getDeclaredField("launchers");
launchers.setAccessible(true);
launchers.set(mojo, List.of("l=com.example.Launch"));

// when
List<String> jlinkArgs = mojo.createJlinkArgs(List.of(), List.of());

// then
assertThat(launched(jlinkArgs)).contains("l=com.example.Launch");
}

@Test
void testMultipleLaunchers() throws Exception {
// It's OK to specify multiple launchers with the "<launchers>" element
// given
JLinkMojo mojo = new JLinkMojo();
Field launcher = mojo.getClass().getDeclaredField("launchers");
launcher.setAccessible(true);
launcher.set(mojo, List.of("l1=com.example.Launch1", "l2=com.example.Launch2"));

// when
List<String> jlinkArgs = mojo.createJlinkArgs(List.of(), List.of());

// then
assertThat(launched(jlinkArgs)).contains("l1=com.example.Launch1", "l2=com.example.Launch2");
}

@Test
void testInvalidLauncherConfig() throws Exception {
// It's an error to specify both "<launcher>" and "<launchers>"
// given
JLinkMojo mojo = new JLinkMojo();
Field launcher = mojo.getClass().getDeclaredField("launcher");
launcher.setAccessible(true);
launcher.set(mojo, "l3=com.example.Launch3");
Field launchers = mojo.getClass().getDeclaredField("launchers");
launchers.setAccessible(true);
launchers.set(mojo, List.of("l1=com.example.Launch1", "l2=com.example.Launch2"));

// When
assertThatThrownBy(() -> mojo.createJlinkArgs(List.of(), List.of())).isInstanceOf(MojoExecutionException.class);
}

// Helper function - gather all the classes named by --launcher args
private static Set<String> launched(List<String> args) {
Set<String> classNames = new HashSet<>();
Iterator<String> iterator = args.iterator();
while (iterator.hasNext()) {
String arg = iterator.next();
if ("--launcher".equals(arg)) {
if (iterator.hasNext()) {
classNames.add(iterator.next());
} else {
throw new IllegalStateException("--launcher arg with no classname");
}
}
}
return classNames;
}
}

0 comments on commit e554ca5

Please sign in to comment.