diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 0000000..3b062f8
--- /dev/null
+++ b/.github/dependabot.yml
@@ -0,0 +1,17 @@
+# To get started with Dependabot version updates, you'll need to specify which
+# package ecosystems to update and where the package manifests are located.
+# Please see the documentation for all configuration options:
+# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
+
+version: 2
+updates:
+ - package-ecosystem: 'maven'
+ directory: '/'
+ schedule:
+ interval: 'daily'
+ - package-ecosystem: 'github-actions'
+ # Workflow files stored in the
+ # default location of `.github/workflows`
+ directory: '/'
+ schedule:
+ interval: 'daily'
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 0000000..6b6c8c3
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,102 @@
+# This workflow will build a Java project with Maven
+# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven
+
+name: WildFly Launcher - CI
+
+on:
+ push:
+ branches-ignore:
+ - 'dependabot/**'
+ paths:
+ - '.github/workflows/ci.yml'
+ - '**/pom.xml'
+ - 'src/**'
+ pull_request:
+ paths:
+ - '.github/workflows/ci.yml'
+ - '**/pom.xml'
+ - 'src/**'
+ schedule:
+ - cron: '0 0 * * *' # Every day at 00:00 UTC
+
+# Only run the latest job
+concurrency:
+ group: '${{ github.workflow }} @ ${{ github.event.pull_request.head.label || github.head_ref || github.ref }}'
+ cancel-in-progress: true
+
+jobs:
+
+ build:
+ name: '${{ matrix.os }}-jdk${{ matrix.java }}'
+ runs-on: ${{ matrix.os }}
+ strategy:
+ fail-fast: false
+ matrix:
+ os: [ 'ubuntu-latest' , 'windows-latest', 'macos-latest' ]
+ java: ['17', '21']
+
+ steps:
+ - uses: actions/checkout@v4
+ - name: Set up JDK ${{ matrix.java }}
+ uses: actions/setup-java@v4
+ with:
+ java-version: ${{ matrix.java }}
+ cache: 'maven'
+ distribution: 'temurin'
+ - name: Build and Test on ${{ matrix.os }} - ${{ matrix.java }}
+ run: mvn clean install '-Dwildfly.feature.pack.version='
+ - name: Upload surefire logs for failed run
+ uses: actions/upload-artifact@v4
+ if: failure()
+ with:
+ name: surefire-reports-${{ matrix.os }}-${{ matrix.java }}
+ path: '**/surefire-reports/'
+ - name: Upload failsafe logs for failed run
+ uses: actions/upload-artifact@v4
+ if: failure()
+ with:
+ name: failsafe-reports-${{ matrix.os }}-${{ matrix.java }}
+ path: '**/failsafe-reports/'
+ - name: Upload logs for failed run
+ uses: actions/upload-artifact@v4
+ if: failure()
+ with:
+ name: server-logs-${{ matrix.os }}-${{ matrix.java }}
+ path: '**/*.log'
+
+ build-jdk-11:
+ name: '${{ matrix.os }}-jdk11'
+ runs-on: ${{ matrix.os }}
+ strategy:
+ fail-fast: false
+ matrix:
+ os: [ 'ubuntu-latest' , 'windows-latest', 'macos-latest' ]
+
+ steps:
+ - uses: actions/checkout@v4
+ - name: Set up JDK ${{ matrix.java }}
+ uses: actions/setup-java@v4
+ with:
+ java-version: 11
+ cache: 'maven'
+ distribution: 'temurin'
+ - name: Build and Test on ${{ matrix.os }} - 11
+ run: mvn -B clean install
+ - name: Upload surefire logs for failed run
+ uses: actions/upload-artifact@v4
+ if: failure()
+ with:
+ name: surefire-reports-${{ matrix.os }}-11
+ path: '**/surefire-reports/'
+ - name: Upload failsafe logs for failed run
+ uses: actions/upload-artifact@v4
+ if: failure()
+ with:
+ name: failsafe-reports-${{ matrix.os }}-11
+ path: '**/failsafe-reports/'
+ - name: Upload logs for failed run
+ uses: actions/upload-artifact@v4
+ if: failure()
+ with:
+ name: server-logs-${{ matrix.os }}-11
+ path: '**/*.log'
\ No newline at end of file
diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml
new file mode 100644
index 0000000..8c359f0
--- /dev/null
+++ b/.github/workflows/integration-tests.yml
@@ -0,0 +1,136 @@
+# This workflow will build a Java project with Maven
+# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven
+
+name: WildFly Luancher Integration Tests
+
+on:
+ push:
+ branches:
+ - '**'
+ paths:
+ - '.github/workflows/integration-tests.yml'
+ - '**/pom.xml'
+ - 'src/main/**'
+ - '!src/test/**'
+ pull_request:
+ branches:
+ - '**'
+ paths:
+ - '.github/workflows/integration-tests.yml'
+ - '**/pom.xml'
+ - 'src/**'
+ - '!src/test/**'
+ schedule:
+ - cron: '0 0 * * *' # Every day at 00:00 UTC
+
+# Only run the latest job
+concurrency:
+ group: '${{ github.workflow }} @ ${{ github.event.pull_request.head.label || github.head_ref || github.ref }}'
+ cancel-in-progress: true
+
+jobs:
+
+ arquillian-test:
+ name: WildFly Arquillian Integration Test
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout Project
+ uses: actions/checkout@v4
+ with:
+ path: wildfly-launcher
+ - name: Set up JDKs
+ uses: actions/setup-java@v4
+ with:
+ java-version: |
+ 11
+ 17
+ 21
+ distribution: 'temurin'
+ architecture: x64
+ cache: 'maven'
+
+ - name: Install SNAPSHOT
+ run: |
+ cd wildfly-launcher
+ mvn -B -ntp install -DskipTests
+ - name: Check out WildFly Arquillian
+ uses: actions/checkout@v4
+ with:
+ repository: wildfly/wildfly-arquillian
+ path: wildfly-arquillian
+ - name: Test WildFly Arquillian
+ run: |
+ cd wildfly-arquillian
+ mvn versions:use-latest-snapshots -DallowSnapshots -Dincludes=org.wildfly.launcher:wildfly-launcher versions:update-properties
+ git diff
+ mvn -B -ntp install -Djava11.home=${{env.JAVA_HOME_11_X64}} -Djava17.home=${{env.JAVA_HOME_17_X64}}
+
+ maven-plugin-test:
+ name: WildFly Maven Plugin Integration Test
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout Project
+ uses: actions/checkout@v4
+ with:
+ path: wildfly-launcher
+ - name: Set up JDKs
+ uses: actions/setup-java@v4
+ with:
+ java-version: |
+ 11
+ 17
+ 21
+ distribution: 'temurin'
+ architecture: x64
+ cache: 'maven'
+
+ - name: Install SNAPSHOT
+ run: |
+ cd wildfly-launcher
+ mvn -B -ntp install -DskipTests
+ - name: Check out WildFly Maven Plugin
+ uses: actions/checkout@v4
+ with:
+ repository: wildfly/wildfly-maven-plugin
+ path: wildfly-maven-plugin
+ - name: Test the WildFly Maven Plugin
+ run: |
+ cd wildfly-maven-plugin
+ mvn versions:use-latest-snapshots -DallowSnapshots -Dincludes=org.wildfly.launcher:wildfly-launcher versions:update-properties
+ git diff
+ mvn -B -ntp install -Djava11.home=${{env.JAVA_HOME_11_X64}} -Djava17.home=${{env.JAVA_HOME_17_X64}}
+
+ wildfly-plugin-tools-test:
+ name: WildFly Plugin Tools Integration Test
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout Project
+ uses: actions/checkout@v4
+ with:
+ path: wildfly-launcher
+ - name: Set up JDKs
+ uses: actions/setup-java@v4
+ with:
+ java-version: |
+ 11
+ 17
+ 21
+ distribution: 'temurin'
+ architecture: x64
+ cache: 'maven'
+
+ - name: Install SNAPSHOT
+ run: |
+ cd wildfly-launcher
+ mvn -B -ntp install -DskipTests
+ - name: Check out WildFly Plugin Tools
+ uses: actions/checkout@v4
+ with:
+ repository: wildfly/wildfly-plugin-tools
+ path: wildfly-plugin-tools
+ - name: Test the WildFly Plugin Tools
+ run: |
+ cd wildfly-plugin-tools
+ mvn versions:use-latest-snapshots -DallowSnapshots -Dincludes=org.wildfly.launcher:wildfly-launcher versions:update-properties
+ git diff
+ mvn -B -ntp install -Djava11.home=${{env.JAVA_HOME_11_X64}} -Djava17.home=${{env.JAVA_HOME_17_X64}}
diff --git a/.github/workflows/wildfly-ci.yml b/.github/workflows/wildfly-ci.yml
new file mode 100644
index 0000000..68f0adc
--- /dev/null
+++ b/.github/workflows/wildfly-ci.yml
@@ -0,0 +1,102 @@
+# This workflow will build a Java project with Maven
+# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven
+
+name: WildFly Launcher Integration - CI
+
+on:
+ push:
+ branches-ignore:
+ - 'dependabot/**'
+ pull_request:
+ branches:
+ - '**'
+ paths:
+ - '.github/workflows/wildfly-ci.yml'
+ schedule:
+ - cron: '0 0 * * *' # Every day at 00:00 UTC
+
+# Only run the latest job
+concurrency:
+ group: '${{ github.workflow }} @ ${{ github.event.pull_request.head.label || github.head_ref || github.ref }}'
+ cancel-in-progress: true
+
+jobs:
+
+ wildfly-test-and-build:
+ name: '${{ matrix.os }}-jdk${{ matrix.java }}'
+ runs-on: ${{ matrix.os }}
+ strategy:
+ fail-fast: false
+ matrix:
+ os: [ 'ubuntu-latest' , 'windows-latest' ]
+ java: ['17', '21', '24-ea']
+
+ steps:
+ - uses: actions/checkout@v4
+ - uses: wildfly-extras/wildfly-nightly-download@v1
+ id: wildfly-nightly
+ - name: Set up JDK ${{ matrix.java }}
+ uses: actions/setup-java@v4
+ with:
+ java-version: ${{ matrix.java }}
+ cache: 'maven'
+ distribution: 'temurin'
+ - name: Build and Test on ${{ matrix.os }} - ${{ matrix.java }} with WildFly ${{steps.wildfly-nightly.outputs.wildfly-version}}
+ run: mvn clean install '-Dwildfly.feature.pack.version=${{steps.wildfly-nightly.outputs.wildfly-version}}'
+ - name: Upload surefire logs for failed run
+ uses: actions/upload-artifact@v4
+ if: failure()
+ with:
+ name: surefire-reports-${{ matrix.os }}-${{ matrix.java }}
+ path: '**/surefire-reports/'
+ - name: Upload failsafe logs for failed run
+ uses: actions/upload-artifact@v4
+ if: failure()
+ with:
+ name: failsafe-reports-${{ matrix.os }}-${{ matrix.java }}
+ path: '**/failsafe-reports/'
+ - name: Upload logs for failed run
+ uses: actions/upload-artifact@v4
+ if: failure()
+ with:
+ name: server-logs-${{ matrix.os }}-${{ matrix.java }}
+ path: '**/*.log'
+
+ legacy-test-and-build:
+ name: 'legacy-${{ matrix.os }}-jdk${{ matrix.java }}'
+ runs-on: ${{ matrix.os }}
+ strategy:
+ fail-fast: false
+ matrix:
+ os: [ 'ubuntu-latest' , 'windows-latest' ]
+ java: ['11', '17', '21']
+
+ steps:
+ - uses: actions/checkout@v4
+ - name: Set up JDK ${{ matrix.java }}
+ uses: actions/setup-java@v4
+ with:
+ java-version: ${{ matrix.java }}
+ cache: 'maven'
+ distribution: 'temurin'
+ - name: Build and Test on ${{ matrix.os }} - ${{ matrix.java }} with WildFly 32.0.0.Final
+ # 32.0.0.Final was the first version which deployed channels
+ run: mvn clean install '-Dwildfly.feature.pack.version=32.0.0.Final'
+ - name: Upload surefire logs for failed run
+ uses: actions/upload-artifact@v4
+ if: failure()
+ with:
+ name: legacy-surefire-reports-${{ matrix.os }}-${{ matrix.java }}
+ path: '**/surefire-reports/'
+ - name: Upload failsafe logs for failed run
+ uses: actions/upload-artifact@v4
+ if: failure()
+ with:
+ name: legacy-failsafe-reports-${{ matrix.os }}-${{ matrix.java }}
+ path: '**/failsafe-reports/'
+ - name: Upload logs for failed run
+ uses: actions/upload-artifact@v4
+ if: failure()
+ with:
+ name: legacy-server-logs-${{ matrix.os }}-${{ matrix.java }}
+ path: '**/*.log'
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index b090c62..5a05324 100644
--- a/pom.xml
+++ b/pom.xml
@@ -40,8 +40,8 @@
git@github.com:wildfly/wildfly-launcher.git
https://github.com/wildfly/wildfly-launcher
- ${basedir}/target/fake-wildfly
- ${basedir}/target/fake-wildfly.jar
+ wildfly-bootable.jar
+ ${basedir}/target/${wildfly.bootable.jar.name}
11
@@ -52,6 +52,7 @@
1.0.8.Final
+ 5.1.0.Alpha1
3.6.1.Final
@@ -59,6 +60,20 @@
2.1.5.Final
5.11.3
+
+
+ true
+
+
+ ${project.build.directory}/server
+
+ org.wildfly
+ wildfly-ee-galleon-pack
+ 34.0.0.Final
+
+ org.wildfly.channels
+ wildfly-ee
+ ${wildfly.feature.pack.version}
@@ -113,6 +128,19 @@
${version.org.jboss.modules.jboss-modules}
test
+
+ org.wildfly.plugins
+ wildfly-plugin-tools
+ 1.2.0.Beta1
+ test
+
+
+
+ org.wildfly.core
+ wildfly-launcher
+
+
+
@@ -163,7 +191,6 @@
checkstyle-suppressions.xml
true
**/*$logger.java,**/*$bundle.java
-
@@ -225,11 +252,65 @@
maven-surefire-plugin
+ ${jboss.home}
${wildfly.launcher.home}
${wildfly.launcher.bootable.jar}
+
+ org.wildfly.plugins
+ wildfly-maven-plugin
+ ${version.org.wildfly.plugins.wildfly-maven-plugin}
+
+ ${jboss.home}
+ ${jboss.home}
+
+
+ ${wildfly.feature.pack.groupId}
+ ${wildfly.feature.pack.artifactId}
+ ${wildfly.feature.pack.version}
+
+
+
+
+
+
+ ${wildfly.channel.manifest.groupId}
+ ${wildfly.channel.manifest.artifactId}
+ ${wildfly.channel.manifest.version}
+
+
+
+
+
+
+
+
+
+ provision-test-server
+ process-test-classes
+
+ provision
+
+
+
+ provision-bootable-jar
+ process-test-classes
+
+ package
+
+
+ ${project.build.directory}/bootable-jar-working
+ true
+ ${wildfly.bootable.jar.name}
+ true
+
+
+
+
diff --git a/src/test/java/org/wildfly/core/launcher/CommandBuilderTest.java b/src/test/java/org/wildfly/core/launcher/CommandBuilderTest.java
index ff88ca9..6f13284 100644
--- a/src/test/java/org/wildfly/core/launcher/CommandBuilderTest.java
+++ b/src/test/java/org/wildfly/core/launcher/CommandBuilderTest.java
@@ -9,8 +9,6 @@
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
-import java.io.IOException;
-import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collection;
@@ -18,7 +16,6 @@
import java.util.List;
import org.junit.jupiter.api.Test;
-
import org.wildfly.core.launcher.Arguments.Argument;
/**
@@ -30,17 +27,8 @@ class CommandBuilderTest {
private static final Path WILDFLY_BOOTABLE_JAR;
static {
- WILDFLY_HOME = Paths.get(System.getProperty("wildfly.launcher.home")).toAbsolutePath().normalize();
+ WILDFLY_HOME = Paths.get(System.getProperty("jboss.home")).toAbsolutePath().normalize();
WILDFLY_BOOTABLE_JAR = Paths.get(System.getProperty("wildfly.launcher.bootable.jar")).toAbsolutePath().normalize();
-
- // Create some default directories and empty bootable fake jar file
- try {
- Files.createFile(WILDFLY_BOOTABLE_JAR);
- Files.createDirectories(WILDFLY_HOME.resolve("modules"));
- Files.createDirectories(WILDFLY_HOME.resolve("configuration"));
- Files.createDirectories(WILDFLY_HOME.resolve("data"));
- } catch (IOException ignore) {
- }
}
@Test
diff --git a/src/test/java/org/wildfly/core/launcher/ServerLauncherTest.java b/src/test/java/org/wildfly/core/launcher/ServerLauncherTest.java
new file mode 100644
index 0000000..95229af
--- /dev/null
+++ b/src/test/java/org/wildfly/core/launcher/ServerLauncherTest.java
@@ -0,0 +1,174 @@
+/*
+ * Copyright The WildFly Authors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package org.wildfly.core.launcher;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Path;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Stream;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.TestInfo;
+import org.junit.jupiter.api.TestTemplate;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.jupiter.api.extension.Extension;
+import org.junit.jupiter.api.extension.ExtensionContext;
+import org.junit.jupiter.api.extension.ParameterContext;
+import org.junit.jupiter.api.extension.ParameterResolutionException;
+import org.junit.jupiter.api.extension.ParameterResolver;
+import org.junit.jupiter.api.extension.TestTemplateInvocationContext;
+import org.junit.jupiter.api.extension.TestTemplateInvocationContextProvider;
+import org.wildfly.plugin.tools.ConsoleConsumer;
+import org.wildfly.plugin.tools.ContainerDescription;
+import org.wildfly.plugin.tools.server.ServerManager;
+
+/**
+ * @author James R. Perkins
+ */
+class ServerLauncherTest {
+ private static final Path JBOSS_HOME = Path.of(System.getProperty("jboss.home"));
+ private static final Path BOOTABLE_JAR = Path.of(System.getProperty("wildfly.launcher.bootable.jar"));
+
+
+ @TestTemplate
+ @ExtendWith(ServerLaunchTestTemplateInvocationContextProvider.class)
+ void launch(final CommandBuilder commandBuilder, final long timeout, final TestInfo testInfo) throws Exception {
+ final Launcher launcher = Launcher.of(commandBuilder);
+ Process process = null;
+ try {
+ process = launcher.launch();
+ final Process capturedProcess = process;
+ final CapturingOutputStream out = new CapturingOutputStream();
+ ConsoleConsumer.start(process, out);
+ Assertions.assertTrue(process.isAlive(), () -> String.format("The process has terminated: %d - %s", capturedProcess.exitValue(), out));
+ try (
+ ServerManager serverManager = ServerManager.builder()
+ .process(process)
+ .shutdownOnClose(true)
+ .build()
+ .get(timeout, TimeUnit.SECONDS)
+ ) {
+ ConsoleConsumer.start(process, out);
+ Assertions.assertTrue(serverManager.waitFor(timeout, TimeUnit.SECONDS), () -> String.format("Failed to start %s within %d seconds. Process: %s%n%s", testInfo.getDisplayName(), timeout, capturedProcess,
+ out));
+ Assertions.assertTrue(serverManager.isRunning(), () -> String.format("Server %s is not running. Process: %s%n%s", testInfo.getDisplayName(), capturedProcess,
+ out));
+ final ContainerDescription description = serverManager.containerDescription();
+ if (commandBuilder instanceof StandaloneCommandBuilder || commandBuilder instanceof BootableJarCommandBuilder) {
+ Assertions.assertFalse(description.isDomain(), () -> String.format("Expected the server to not be a domain server: " + description));
+ } else {
+ Assertions.assertTrue(description.isDomain(), () -> String.format("Expected the server to be a domain server: " + description));
+ }
+ } catch (Throwable e) {
+ Assertions.fail(String.format("Failed starting %s: %s", testInfo.getDisplayName(), out), e);
+ }
+ } finally {
+ if (process != null) {
+ process.destroyForcibly();
+ }
+ }
+ }
+
+ public static class ServerLaunchTestTemplateInvocationContextProvider implements TestTemplateInvocationContextProvider {
+
+ @Override
+ public boolean supportsTestTemplate(final ExtensionContext context) {
+ return true;
+ }
+
+ @Override
+ public Stream provideTestTemplateInvocationContexts(final ExtensionContext context) {
+ return Stream.of(createTestContext("Standalone", StandaloneCommandBuilder.of(JBOSS_HOME), 60L),
+ createTestContext("Domain", DomainCommandBuilder.of(JBOSS_HOME), 60L),
+ createTestContext("Bootable JAR", BootableJarCommandBuilder.of(BOOTABLE_JAR), 60L)
+ );
+ }
+
+ @SuppressWarnings("SameParameterValue")
+ private TestTemplateInvocationContext createTestContext(final String name, final CommandBuilder commandBuilder, final long timeout) {
+ return new TestTemplateInvocationContext() {
+ @Override
+ public String getDisplayName(final int invocationIndex) {
+ return name;
+ }
+
+ @Override
+ public List getAdditionalExtensions() {
+ return List.of(
+ new ParameterResolver() {
+ @Override
+ public boolean supportsParameter(final ParameterContext parameterContext, final ExtensionContext extensionContext) throws ParameterResolutionException {
+ return parameterContext.getParameter().getType() == CommandBuilder.class;
+ }
+
+ @Override
+ public Object resolveParameter(final ParameterContext parameterContext, final ExtensionContext extensionContext) throws ParameterResolutionException {
+ return commandBuilder;
+ }
+ },
+ new ParameterResolver() {
+ @Override
+ public boolean supportsParameter(final ParameterContext parameterContext, final ExtensionContext extensionContext) throws ParameterResolutionException {
+ return parameterContext.getParameter().getType() == long.class;
+ }
+
+ @Override
+ public Object resolveParameter(final ParameterContext parameterContext, final ExtensionContext extensionContext) throws ParameterResolutionException {
+ return timeout;
+ }
+ }
+ );
+ }
+ };
+ }
+ }
+
+ private static class CapturingOutputStream extends ByteArrayOutputStream {
+ @Override
+ public synchronized void write(final int b) {
+ try {
+ super.write(b);
+ } finally {
+ System.out.write(b);
+ }
+ }
+
+ @Override
+ public synchronized void write(final byte[] b, final int off, final int len) {
+ try {
+ super.write(b, off, len);
+ } finally {
+ System.out.write(b, off, len);
+ }
+ }
+
+ @Override
+ public synchronized void write(final byte[] b) throws IOException {
+ try {
+ super.write(b);
+ } finally {
+ System.out.write(b);
+ }
+ }
+
+ @Override
+ public void flush() throws IOException {
+ try {
+ super.flush();
+ } finally {
+ System.out.flush();
+ }
+ }
+
+ @Override
+ public synchronized String toString() {
+ return super.toString(StandardCharsets.UTF_8);
+ }
+ }
+}