Skip to content

Commit 403db26

Browse files
committed
Fix for WFCORE-7311, Bootable JAR, allows to load additional boot logic from JBoss Modules module.
1 parent 1019f22 commit 403db26

File tree

19 files changed

+737
-10
lines changed

19 files changed

+737
-10
lines changed

bootable-jar/boot/src/main/java/org/wildfly/core/jar/boot/Main.java

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import java.io.InputStream;
1111
import java.io.InputStreamReader;
1212
import java.lang.reflect.Method;
13+
import java.net.URL;
1314
import java.nio.charset.StandardCharsets;
1415
import java.nio.file.Files;
1516
import java.nio.file.Path;
@@ -18,10 +19,12 @@
1819
import java.nio.file.attribute.PosixFilePermission;
1920
import java.security.Policy;
2021
import java.util.ArrayList;
22+
import java.util.Collections;
2123
import java.util.HashSet;
2224
import java.util.Iterator;
2325
import java.util.List;
2426
import java.util.Locale;
27+
import java.util.Properties;
2528
import java.util.ServiceLoader;
2629
import java.util.Set;
2730
import java.util.concurrent.TimeUnit;
@@ -50,6 +53,11 @@ public final class Main {
5053

5154
private static final String BOOTABLE_JAR = "org.wildfly.core.jar.runtime.BootableJar";
5255
private static final String BOOTABLE_JAR_RUN_METHOD = "run";
56+
private static final String BOOTABLE_JAR_RUNTIME_CONFIGURATOR_CLASS = "org.wildfly.core.jar.runtime.BootableServerConfigurator";
57+
private static final String BOOTABLE_JAR_RUNTIME_CONFIGURATOR_CONFIGURATION_CLASS = "org.wildfly.core.jar.runtime.Configuration";
58+
private static final String BOOTABLE_JAR_RUNTIME_CONFIGURATOR_METHOD_NAME = "configure";
59+
private static final String BOOTABLE_JAR_RUNTIME_CONFIGURATOR_CLI_OPS_METHOD_NAME = "getCliOperations";
60+
private static final String BOOTABLE_JAR_RUNTIME_CONFIGURATOR_ARGS_METHOD_NAME = "getArguments";
5361

5462
private static final String INSTALL_DIR = "--install-dir";
5563
private static final String SECMGR = "-secmgr";
@@ -169,9 +177,44 @@ private static void runBootableJar(Path jbossHome, List<String> arguments, Long
169177
} catch (final ClassNotFoundException cnfe) {
170178
throw new Exception(cnfe);
171179
}
180+
URL url = bootableJarModule.getExportedResource("bootable-configurators.properties");
181+
Properties p = new Properties();
182+
try (InputStream in = url.openStream()) {
183+
p.load(in);
184+
}
185+
List<String> cliCmds = null;
186+
if (!p.isEmpty()) {
187+
cliCmds = new ArrayList<>();
188+
Class<?> configuratorClass = moduleCL.loadClass(BOOTABLE_JAR_RUNTIME_CONFIGURATOR_CLASS);
189+
Class<?> configurationClass = moduleCL.loadClass(BOOTABLE_JAR_RUNTIME_CONFIGURATOR_CONFIGURATION_CLASS);
190+
Method configure = configuratorClass.getMethod(BOOTABLE_JAR_RUNTIME_CONFIGURATOR_METHOD_NAME, List.class, Path.class);
191+
Method getCliOperations = configurationClass.getMethod(BOOTABLE_JAR_RUNTIME_CONFIGURATOR_CLI_OPS_METHOD_NAME);
192+
Method getArguments = configurationClass.getMethod(BOOTABLE_JAR_RUNTIME_CONFIGURATOR_ARGS_METHOD_NAME);
193+
List<String> args = Collections.unmodifiableList(arguments);
194+
for (String k : p.stringPropertyNames()) {
195+
String moduleName = p.getProperty(k);
196+
Module bootableConfiguratorModule = moduleLoader.loadModule(moduleName);
197+
ServiceLoader<?> loader = bootableConfiguratorModule.loadService(configuratorClass);
198+
for (Object configurator : loader) {
199+
Object config = configure.invoke(configurator, args, jbossHome);
200+
if (config != null) {
201+
@SuppressWarnings("unchecked")
202+
List<String> cliOps = (List<String>) getCliOperations.invoke(config);
203+
if (cliOps != null && !cliOps.isEmpty()) {
204+
cliCmds.addAll(cliOps);
205+
}
206+
@SuppressWarnings("unchecked")
207+
List<String> extraArguments = (List<String>) getArguments.invoke(config);
208+
if (extraArguments != null && !extraArguments.isEmpty()) {
209+
arguments.addAll(extraArguments);
210+
}
211+
}
212+
}
213+
}
214+
}
172215
Method runMethod;
173216
try {
174-
runMethod = bjFactoryClass.getMethod(BOOTABLE_JAR_RUN_METHOD, Path.class, List.class, ModuleLoader.class, ModuleClassLoader.class, Long.class);
217+
runMethod = bjFactoryClass.getMethod(BOOTABLE_JAR_RUN_METHOD, Path.class, List.class, ModuleLoader.class, ModuleClassLoader.class, Long.class, List.class);
175218
} catch (final NoSuchMethodException nsme) {
176219
throw new Exception(nsme);
177220
}
@@ -189,7 +232,7 @@ private static void runBootableJar(Path jbossHome, List<String> arguments, Long
189232
}
190233
}
191234

192-
runMethod.invoke(null, jbossHome, arguments, moduleLoader, moduleCL, unzipTime);
235+
runMethod.invoke(null, jbossHome, arguments, moduleLoader, moduleCL, unzipTime, cliCmds);
193236
}
194237

195238
private static void unzip(InputStream wf, Path dir) throws Exception {

bootable-jar/runtime/src/main/java/org/wildfly/core/jar/runtime/BootableJar.java

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,8 @@ public final class BootableJar implements ShutdownHandler {
106106
private final Arguments arguments;
107107
private final ModuleLoader loader;
108108
private final Path pidFile;
109-
110-
private BootableJar(BootableEnvironment environment, Arguments arguments, ModuleLoader loader, long unzipTime) throws Exception {
109+
private final Path cliScript;
110+
private BootableJar(BootableEnvironment environment, Arguments arguments, ModuleLoader loader, long unzipTime, List<String> cmds) throws Exception {
111111
this.environment = environment;
112112
this.arguments = arguments;
113113
this.loader = loader;
@@ -120,7 +120,18 @@ private BootableJar(BootableEnvironment environment, Arguments arguments, Module
120120
if (arguments.getDeployment() != null) {
121121
setupDeployment(arguments.getDeployment());
122122
}
123-
123+
if (cmds != null && !cmds.isEmpty()) {
124+
cliScript = Files.createTempFile("boot-config", null);
125+
cliScript.toFile().deleteOnExit();
126+
Files.write(cliScript, cmds);
127+
Path userScript = arguments.getCLIScript();
128+
if (userScript != null) {
129+
List<String> userCommands = Files.readAllLines(userScript);
130+
Files.write(cliScript, userCommands, StandardOpenOption.APPEND);
131+
}
132+
} else {
133+
cliScript = arguments.getCLIScript();
134+
}
124135
log.advertiseInstall(environment.getJBossHome(), unzipTime + (System.currentTimeMillis() - t));
125136
pidFile = environment.getPidFile();
126137
}
@@ -259,14 +270,13 @@ private LogContext configureLogContext() throws IOException {
259270
}
260271

261272
public void run() throws Exception {
262-
Path script = arguments.getCLIScript();
263-
if (script != null) {
273+
if (cliScript != null) {
264274
long id = System.currentTimeMillis();
265275
Path markerDir = environment.getTmpDir().resolve(id + "-cli-boot-hook-dir");
266276
Path outputFile = environment.getTmpDir().resolve(id + "-cli-boot-hook-output-file.txt");
267277
Files.createDirectories(markerDir);
268278
startServerArgs.add("--start-mode=admin-only");
269-
startServerArgs.add("-Dorg.wildfly.internal.cli.boot.hook.script=" + script.toAbsolutePath().toString());
279+
startServerArgs.add("-Dorg.wildfly.internal.cli.boot.hook.script=" + cliScript.toAbsolutePath().toString());
270280
startServerArgs.add("-Dorg.wildfly.internal.cli.boot.hook.marker.dir=" + markerDir.toAbsolutePath().toString());
271281
startServerArgs.add("-Dorg.wildfly.internal.cli.boot.hook.script.output.file=" + outputFile.toAbsolutePath().toString());
272282
}
@@ -312,9 +322,10 @@ private void loadBootConfigProperties() throws IOException {
312322
* @param moduleLoader JBoss modules loader.
313323
* @param moduleClassLoader Bootable jar module classloader
314324
* @param unzipTime Time spent to unzip the server.
325+
* @param cmds The list of CLI commands provided by configurators, can be null.
315326
* @throws Exception
316327
*/
317-
public static void run(Path jbossHome, List<String> args, ModuleLoader moduleLoader, ModuleClassLoader moduleClassLoader, Long unzipTime) throws Exception {
328+
public static void run(Path jbossHome, List<String> args, ModuleLoader moduleLoader, ModuleClassLoader moduleClassLoader, Long unzipTime, List<String> cmds) throws Exception {
318329
setTccl(moduleClassLoader);
319330
// Initialize the environment
320331
final BootableEnvironment environment = BootableEnvironment.of(jbossHome);
@@ -333,7 +344,7 @@ public static void run(Path jbossHome, List<String> args, ModuleLoader moduleLoa
333344
}
334345

335346
// Side effect is to initialise Log Manager
336-
BootableJar bootableJar = new BootableJar(environment, arguments, moduleLoader, unzipTime);
347+
BootableJar bootableJar = new BootableJar(environment, arguments, moduleLoader, unzipTime, cmds);
337348

338349
// First, activate the ModuleLoggerFinder
339350
configureModuleFinder(moduleClassLoader);
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/*
2+
* Copyright The WildFly Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
package org.wildfly.core.jar.runtime;
6+
7+
import java.nio.file.Path;
8+
import java.util.List;
9+
10+
/**
11+
* Interface called at boot time to tune bootable jar configuration.
12+
*/
13+
public interface BootableServerConfigurator {
14+
/**
15+
*
16+
* @param arguments The Bootable JAR startup arguments.
17+
* @param installDir The path where the server is installed.
18+
* @return A configuration instance.
19+
* @throws Exception
20+
*/
21+
public Configuration configure(List<String> arguments, Path installDir) throws Exception;
22+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
* Copyright The WildFly Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
package org.wildfly.core.jar.runtime;
6+
7+
import java.util.Collections;
8+
import java.util.List;
9+
10+
/**
11+
* An additional configuration to applies to the bootable JAR server.
12+
*
13+
*/
14+
public class Configuration {
15+
16+
private final List<String> arguments;
17+
private final List<String> cliOperations;
18+
19+
public Configuration(List<String> arguments, List<String> cliOperations) {
20+
this.arguments = arguments == null ? Collections.emptyList() : arguments;
21+
this.cliOperations = cliOperations == null ? Collections.emptyList() : cliOperations;
22+
}
23+
24+
/**
25+
* @return the additional server arguments.
26+
*/
27+
public List<String> getArguments() {
28+
return arguments;
29+
}
30+
31+
/**
32+
* @return the additional CLI operations.
33+
*/
34+
public List<String> getCliOperations() {
35+
return cliOperations;
36+
}
37+
}

core-feature-pack/common/src/main/resources/modules/system/layers/base/org/wildfly/bootable-jar/main/bootable-configurators/bootable-configurators.properties

Whitespace-only changes.

core-feature-pack/common/src/main/resources/modules/system/layers/base/org/wildfly/bootable-jar/main/module.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
<resources>
1414
<artifact name="${org.wildfly.core:wildfly-jar-runtime}"/>
15+
<resource-root path="bootable-configurators"/>
1516
</resources>
1617

1718
<exports>
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
~ Copyright The WildFly Authors
4+
~ SPDX-License-Identifier: Apache-2.0
5+
-->
6+
<project xmlns="http://maven.apache.org/POM/4.0.0"
7+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
8+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
9+
<modelVersion>4.0.0</modelVersion>
10+
11+
<parent>
12+
<groupId>org.wildfly.core</groupId>
13+
<artifactId>wildfly-core-testsuite-bootable-configurator-feature-pack-parent</artifactId>
14+
<version>31.0.0.Beta1-SNAPSHOT</version>
15+
</parent>
16+
17+
<artifactId>wildfly-core-testsuite-bootable-configurator-impl</artifactId>
18+
<packaging>jar</packaging>
19+
20+
<name>WildFly Core Test Suite: Bootable Configurator impl</name>
21+
22+
<dependencies>
23+
<dependency>
24+
<groupId>org.wildfly.core</groupId>
25+
<artifactId>wildfly-jar-runtime</artifactId>
26+
<scope>provided</scope>
27+
</dependency>
28+
</dependencies>
29+
30+
31+
32+
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* Copyright The WildFly Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
package org.wildfly.core.test.bootable.configurator;
6+
7+
import java.nio.file.Path;
8+
import java.util.ArrayList;
9+
import java.util.Arrays;
10+
import java.util.List;
11+
import org.wildfly.core.jar.runtime.BootableServerConfigurator;
12+
import org.wildfly.core.jar.runtime.Configuration;
13+
14+
/**
15+
*
16+
* @author jdenise
17+
*/
18+
public class TestConfigurator implements BootableServerConfigurator {
19+
20+
@Override
21+
public Configuration configure(List<String> args, Path installDir) throws Exception {
22+
System.out.println("Booting with the test configurator");
23+
List<String> arguments = new ArrayList<>();
24+
arguments.add("-Dorg.wildfly.core.test.bootable.configurator.value=foo");
25+
String[] lst = {"/system-property=org.wildfly.core.test.bootable.configurator.property:add(value=${org.wildfly.core.test.bootable.configurator.value})"};
26+
return new Configuration(arguments, Arrays.asList(lst));
27+
}
28+
}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
~ Copyright The WildFly Authors
4+
~ SPDX-License-Identifier: Apache-2.0
5+
-->
6+
<project xmlns="http://maven.apache.org/POM/4.0.0"
7+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
8+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
9+
<modelVersion>4.0.0</modelVersion>
10+
11+
<parent>
12+
<groupId>org.wildfly.core</groupId>
13+
<artifactId>wildfly-core-testsuite-bootable-configurator-feature-pack-parent</artifactId>
14+
<version>31.0.0.Beta1-SNAPSHOT</version>
15+
</parent>
16+
17+
<artifactId>wildfly-core-testsuite-bootable-configurator-feature-pack</artifactId>
18+
<packaging>pom</packaging>
19+
20+
<name>WildFly Core Test Suite: Bootable Configurator Feature Pack</name>
21+
22+
<properties>
23+
</properties>
24+
25+
<build>
26+
<finalName>${project.artifactId}-${project.version}</finalName>
27+
<plugins>
28+
<plugin>
29+
<!-- Feature pack generation is vulnerable to leftover files in the target
30+
folder from previous builds, so always clean even if the clean lifecycle is not invoked -->
31+
<artifactId>maven-clean-plugin</artifactId>
32+
<executions>
33+
<execution>
34+
<id>auto-clean</id>
35+
<phase>initialize</phase>
36+
<goals>
37+
<goal>clean</goal>
38+
</goals>
39+
</execution>
40+
</executions>
41+
</plugin>
42+
<plugin>
43+
<groupId>org.wildfly.galleon-plugins</groupId>
44+
<artifactId>wildfly-galleon-maven-plugin</artifactId>
45+
<version>${version.org.wildfly.galleon-plugins}</version>
46+
<executions>
47+
<execution>
48+
<id>wildfly-bootable-configurator-feature-pack-build</id>
49+
<goals>
50+
<goal>build-feature-pack</goal>
51+
</goals>
52+
<phase>prepare-package</phase>
53+
<configuration>
54+
<fork-embedded>${galleon.fork.embedded}</fork-embedded>
55+
</configuration>
56+
</execution>
57+
</executions>
58+
</plugin>
59+
</plugins>
60+
</build>
61+
62+
<dependencies>
63+
<!-- Other feature pack dependencies -->
64+
<dependency>
65+
<groupId>org.wildfly.core</groupId>
66+
<artifactId>wildfly-core-galleon-pack</artifactId>
67+
<type>zip</type>
68+
</dependency>
69+
70+
<dependency>
71+
<groupId>org.wildfly.galleon-plugins</groupId>
72+
<artifactId>wildfly-galleon-plugins</artifactId>
73+
<scope>provided</scope>
74+
</dependency>
75+
76+
<dependency>
77+
<groupId>${project.groupId}</groupId>
78+
<artifactId>wildfly-core-testsuite-bootable-configurator-impl</artifactId>
79+
</dependency>
80+
</dependencies>
81+
82+
83+
84+
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<!--
2+
~ Copyright The WildFly Authors
3+
~ SPDX-License-Identifier: Apache-2.0
4+
~
5+
-->
6+
<!-- TODO Rename this module to something matching your chosen subsystem name -->
7+
<module xmlns="urn:jboss:module:1.9" name="org.wildfly.core.test.bootable.configurator">
8+
<properties>
9+
<property name="jboss.api" value="private"/>
10+
</properties>
11+
12+
<resources>
13+
<artifact name="${org.wildfly.core:wildfly-core-testsuite-bootable-configurator-impl}"/>
14+
</resources>
15+
<dependencies>
16+
<module name="org.wildfly.bootable-jar"/>
17+
</dependencies>
18+
<provides>
19+
<service name="org.wildfly.core.jar.runtime.BootableServerConfigurator">
20+
<with-class name="org.wildfly.core.test.bootable.configurator.TestConfigurator"/>
21+
</service>
22+
</provides>
23+
</module>

0 commit comments

Comments
 (0)