mirror of
https://github.com/apache/maven-mvnd.git
synced 2025-09-28 00:22:03 +00:00
Non daemon option, fixes #43
This commit is contained in:
@@ -27,8 +27,10 @@ import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Properties;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.stream.Collectors;
|
||||
import org.jboss.fuse.mvnd.common.BuildProperties;
|
||||
import org.jboss.fuse.mvnd.common.DaemonCompatibilitySpec;
|
||||
@@ -84,6 +86,10 @@ public class DaemonConnector {
|
||||
}
|
||||
|
||||
public DaemonClientConnection connect(ClientOutput output) {
|
||||
if (parameters.noDaemon()) {
|
||||
return connectNoDaemon();
|
||||
}
|
||||
|
||||
final DaemonCompatibilitySpec constraint = new DaemonCompatibilitySpec(
|
||||
parameters.javaHome(), parameters.getDaemonOpts());
|
||||
output.accept(Message.buildStatus("Looking up daemon..."));
|
||||
@@ -110,6 +116,49 @@ public class DaemonConnector {
|
||||
return startDaemon();
|
||||
}
|
||||
|
||||
private DaemonClientConnection connectNoDaemon() {
|
||||
if (Environment.isNative()) {
|
||||
throw new UnsupportedOperationException(
|
||||
"The " + Environment.MVND_NO_DAEMON.getProperty() + " property is not supported in native mode.");
|
||||
}
|
||||
String daemon = ProcessHandle.current().pid() + "-" + System.currentTimeMillis();
|
||||
Properties properties = new Properties();
|
||||
properties.put(Environment.JAVA_HOME.getProperty(), parameters.javaHome().toString());
|
||||
properties.put(Environment.USER_DIR.getProperty(), parameters.userDir().toString());
|
||||
properties.put(Environment.USER_HOME.getProperty(), parameters.userHome().toString());
|
||||
properties.put(Environment.MVND_HOME.getProperty(), parameters.mvndHome().toString());
|
||||
properties.put(Environment.DAEMON_UID.getProperty(), daemon);
|
||||
properties.put(Environment.MVND_DAEMON_STORAGE.getProperty(), parameters.daemonStorage().toString());
|
||||
properties.put(Environment.DAEMON_REGISTRY.getProperty(), parameters.registry().toString());
|
||||
properties.putAll(parameters.getDaemonOptsMap());
|
||||
Environment.setProperties(properties);
|
||||
AtomicReference<Throwable> throwable = new AtomicReference<>();
|
||||
Thread serverThread = new Thread(() -> {
|
||||
try {
|
||||
Class<?> clazz = getClass().getClassLoader().loadClass("org.jboss.fuse.mvnd.daemon.Server");
|
||||
try (AutoCloseable server = (AutoCloseable) clazz.getConstructor().newInstance()) {
|
||||
((Runnable) server).run();
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
throwable.set(t);
|
||||
}
|
||||
});
|
||||
serverThread.start();
|
||||
long start = System.currentTimeMillis();
|
||||
do {
|
||||
DaemonClientConnection daemonConnection = connectToDaemonWithId(daemon, true);
|
||||
if (daemonConnection != null) {
|
||||
return daemonConnection;
|
||||
}
|
||||
try {
|
||||
sleep(50L);
|
||||
} catch (InterruptedException e) {
|
||||
throw new DaemonException.InterruptedException(e);
|
||||
}
|
||||
} while (serverThread.isAlive() && System.currentTimeMillis() - start < DEFAULT_CONNECT_TIMEOUT);
|
||||
throw new RuntimeException("Unable to connect to internal daemon", throwable.get());
|
||||
}
|
||||
|
||||
private String handleStopEvents(Collection<DaemonInfo> idleDaemons, Collection<DaemonInfo> busyDaemons) {
|
||||
final List<DaemonStopEvent> stopEvents = registry.getStopEvents();
|
||||
|
||||
|
@@ -73,6 +73,13 @@ public class DaemonParameters {
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public Map<String, String> getDaemonOptsMap() {
|
||||
return Arrays.stream(Environment.values())
|
||||
.filter(Environment::isDiscriminating)
|
||||
.collect(Collectors.toMap(Environment::getProperty,
|
||||
v -> property(v).orFail().asString()));
|
||||
}
|
||||
|
||||
public List<String> getDaemonCommandLineProperties() {
|
||||
return Arrays.stream(Environment.values())
|
||||
.filter(Environment::isDiscriminating)
|
||||
@@ -239,6 +246,17 @@ public class DaemonParameters {
|
||||
return property(Environment.MAVEN_REPO_LOCAL).asPath();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return <code>true</code> if maven should be executed within this process instead of spawning a daemon.
|
||||
*/
|
||||
public boolean noDaemon() {
|
||||
return value(Environment.MVND_NO_DAEMON)
|
||||
.orSystemProperty()
|
||||
.orEnvironmentVariable()
|
||||
.orDefault()
|
||||
.asBoolean();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param newUserDir where to change the current directory to
|
||||
* @return a new {@link DaemonParameters} with {@code userDir} set to the given {@code newUserDir}
|
||||
|
@@ -68,6 +68,7 @@ public enum Environment {
|
||||
* The path to the daemon registry
|
||||
*/
|
||||
DAEMON_REGISTRY("daemon.registry", null, null, false),
|
||||
MVND_NO_DAEMON("mvnd.noDaemon", "MVND_NO_DAEMON", "false", true),
|
||||
DAEMON_DEBUG("daemon.debug", null, false, true),
|
||||
DAEMON_IDLE_TIMEOUT_MS("daemon.idleTimeoutMs", null, TimeUnit.HOURS.toMillis(3), true),
|
||||
DAEMON_KEEP_ALIVE_MS("daemon.keepAliveMs", null, TimeUnit.SECONDS.toMillis(1), true),
|
||||
|
@@ -72,6 +72,7 @@ public class Server implements AutoCloseable, Runnable {
|
||||
public static final int CANCEL_TIMEOUT = 10 * 1000;
|
||||
|
||||
private final String uid;
|
||||
private final boolean noDaemon;
|
||||
private final ServerSocketChannel socket;
|
||||
private final DaemonMavenCli cli;
|
||||
private volatile DaemonInfo info;
|
||||
@@ -86,6 +87,7 @@ public class Server implements AutoCloseable, Runnable {
|
||||
|
||||
public Server() throws IOException {
|
||||
this.uid = Environment.DAEMON_UID.asString();
|
||||
this.noDaemon = Environment.MVND_NO_DAEMON.asBoolean();
|
||||
try {
|
||||
cli = new DaemonMavenCli();
|
||||
registry = new DaemonRegistry(Environment.DAEMON_REGISTRY.asPath());
|
||||
@@ -136,12 +138,14 @@ public class Server implements AutoCloseable, Runnable {
|
||||
try {
|
||||
socket.close();
|
||||
} finally {
|
||||
if (!noDaemon) {
|
||||
clearCache("sun.net.www.protocol.jar.JarFileFactory", "urlCache");
|
||||
clearCache("sun.net.www.protocol.jar.JarFileFactory", "fileCache");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
LOGGER.error("Error closing daemon", t);
|
||||
}
|
||||
@@ -165,8 +169,14 @@ public class Server implements AutoCloseable, Runnable {
|
||||
executor.scheduleAtFixedRate(this::expirationCheck,
|
||||
expirationCheckDelayMs, expirationCheckDelayMs, TimeUnit.MILLISECONDS);
|
||||
LOGGER.info("Daemon started");
|
||||
if (noDaemon) {
|
||||
try (SocketChannel socket = this.socket.accept()) {
|
||||
client(socket);
|
||||
}
|
||||
} else {
|
||||
new DaemonThread(this::accept).start();
|
||||
awaitStop();
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
LOGGER.error("Error running daemon loop", t);
|
||||
} finally {
|
||||
@@ -516,11 +526,13 @@ public class Server implements AutoCloseable, Runnable {
|
||||
} catch (Throwable t) {
|
||||
LOGGER.error("Error while building project", t);
|
||||
} finally {
|
||||
if (!noDaemon) {
|
||||
LOGGER.info("Daemon back to idle");
|
||||
updateState(DaemonState.Idle);
|
||||
System.gc();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int getClassOrder(Message m) {
|
||||
switch (m.getType()) {
|
||||
|
206
dist/src/main/distro/bin/mvnd.cmd
vendored
Normal file
206
dist/src/main/distro/bin/mvnd.cmd
vendored
Normal file
@@ -0,0 +1,206 @@
|
||||
@REM Licensed to the Apache Software Foundation (ASF) under one
|
||||
@REM or more contributor license agreements. See the NOTICE file
|
||||
@REM distributed with this work for additional information
|
||||
@REM regarding copyright ownership. The ASF licenses this file
|
||||
@REM to you under the Apache License, Version 2.0 (the
|
||||
@REM "License"); you may not use this file except in compliance
|
||||
@REM with the License. You may obtain a copy of the License at
|
||||
@REM
|
||||
@REM http://www.apache.org/licenses/LICENSE-2.0
|
||||
@REM
|
||||
@REM Unless required by applicable law or agreed to in writing,
|
||||
@REM software distributed under the License is distributed on an
|
||||
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
@REM KIND, either express or implied. See the License for the
|
||||
@REM specific language governing permissions and limitations
|
||||
@REM under the License.
|
||||
|
||||
@REM -----------------------------------------------------------------------------
|
||||
@REM Apache Maven Startup Script
|
||||
@REM
|
||||
@REM Environment Variable Prerequisites
|
||||
@REM
|
||||
@REM JAVA_HOME Must point at your Java Development Kit installation.
|
||||
@REM MAVEN_BATCH_ECHO (Optional) Set to 'on' to enable the echoing of the batch commands.
|
||||
@REM MAVEN_BATCH_PAUSE (Optional) set to 'on' to wait for a key stroke before ending.
|
||||
@REM MAVEN_OPTS (Optional) Java runtime options used when Maven is executed.
|
||||
@REM MAVEN_SKIP_RC (Optional) Flag to disable loading of mavenrc files.
|
||||
@REM -----------------------------------------------------------------------------
|
||||
|
||||
@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
|
||||
@echo off
|
||||
@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on'
|
||||
@if "%MAVEN_BATCH_ECHO%"=="on" echo %MAVEN_BATCH_ECHO%
|
||||
|
||||
@REM Execute a user defined script before this one
|
||||
if not "%MAVEN_SKIP_RC%"=="" goto skipRcPre
|
||||
@REM check for pre script, once with legacy .bat ending and once with .cmd ending
|
||||
if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat"
|
||||
if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd"
|
||||
:skipRcPre
|
||||
|
||||
@setlocal
|
||||
|
||||
set ERROR_CODE=0
|
||||
|
||||
@REM ==== START VALIDATION ====
|
||||
if not "%JAVA_HOME%"=="" goto OkJHome
|
||||
for %%i in (java.exe) do set "JAVACMD=%%~$PATH:i"
|
||||
goto checkJCmd
|
||||
|
||||
:OkJHome
|
||||
set "JAVACMD=%JAVA_HOME%\bin\java.exe"
|
||||
|
||||
:checkJCmd
|
||||
if exist "%JAVACMD%" goto chkMHome
|
||||
|
||||
echo The JAVA_HOME environment variable is not defined correctly >&2
|
||||
echo This environment variable is needed to run this program >&2
|
||||
echo NB: JAVA_HOME should point to a JDK not a JRE >&2
|
||||
goto error
|
||||
|
||||
:chkMHome
|
||||
set "MVND_HOME=%~dp0.."
|
||||
if not "%MVND_HOME%"=="" goto stripMHome
|
||||
goto error
|
||||
|
||||
:stripMHome
|
||||
if not "_%MVND_HOME:~-1%"=="_\" goto checkMCmd
|
||||
set "MVND_HOME=%MVND_HOME:~0,-1%"
|
||||
goto stripMHome
|
||||
|
||||
:checkMCmd
|
||||
if exist "%MVND_HOME%\bin\mvnd.cmd" goto init
|
||||
goto error
|
||||
@REM ==== END VALIDATION ====
|
||||
|
||||
:init
|
||||
|
||||
set MAVEN_CMD_LINE_ARGS=%*
|
||||
|
||||
@REM Find the project basedir, i.e., the directory that contains the folder ".mvn".
|
||||
@REM Fallback to current working directory if not found.
|
||||
|
||||
set "MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%"
|
||||
if not "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
|
||||
|
||||
set "EXEC_DIR=%CD%"
|
||||
set "WDIR=%EXEC_DIR%"
|
||||
|
||||
@REM Look for the --file switch and start the search for the .mvn directory from the specified
|
||||
@REM POM location, if supplied.
|
||||
|
||||
set FILE_ARG=
|
||||
:arg_loop
|
||||
if "%~1" == "-f" (
|
||||
set "FILE_ARG=%~2"
|
||||
shift
|
||||
goto process_file_arg
|
||||
)
|
||||
if "%~1" == "--file" (
|
||||
set "FILE_ARG=%~2"
|
||||
shift
|
||||
goto process_file_arg
|
||||
)
|
||||
@REM If none of the above, skip the argument
|
||||
shift
|
||||
if not "%~1" == "" (
|
||||
goto arg_loop
|
||||
) else (
|
||||
goto findBaseDir
|
||||
)
|
||||
|
||||
:process_file_arg
|
||||
if "%FILE_ARG%" == "" (
|
||||
goto findBaseDir
|
||||
)
|
||||
if not exist "%FILE_ARG%" (
|
||||
echo POM file "%FILE_ARG%" specified the -f/--file command-line argument does not exist >&2
|
||||
goto error
|
||||
)
|
||||
if exist "%FILE_ARG%\*" (
|
||||
set "POM_DIR=%FILE_ARG%"
|
||||
) else (
|
||||
call :get_directory_from_file "%FILE_ARG%"
|
||||
)
|
||||
if not exist "%POM_DIR%" (
|
||||
echo Directory "%POM_DIR%" extracted from the -f/--file command-line argument "%FILE_ARG%" does not exist >&2
|
||||
goto error
|
||||
)
|
||||
set "WDIR=%POM_DIR%"
|
||||
goto findBaseDir
|
||||
|
||||
:get_directory_from_file
|
||||
set "POM_DIR=%~dp1"
|
||||
:stripPomDir
|
||||
if not "_%POM_DIR:~-1%"=="_\" goto pomDirStripped
|
||||
set "POM_DIR=%POM_DIR:~0,-1%"
|
||||
goto stripPomDir
|
||||
:pomDirStripped
|
||||
exit /b
|
||||
|
||||
:findBaseDir
|
||||
cd /d "%WDIR%"
|
||||
:findBaseDirLoop
|
||||
if exist "%WDIR%\.mvn" goto baseDirFound
|
||||
cd ..
|
||||
IF "%WDIR%"=="%CD%" goto baseDirNotFound
|
||||
set "WDIR=%CD%"
|
||||
goto findBaseDirLoop
|
||||
|
||||
:baseDirFound
|
||||
set "MAVEN_PROJECTBASEDIR=%WDIR%"
|
||||
cd /d "%EXEC_DIR%"
|
||||
goto endDetectBaseDir
|
||||
|
||||
:baseDirNotFound
|
||||
if "_%EXEC_DIR:~-1%"=="_\" set "EXEC_DIR=%EXEC_DIR:~0,-1%"
|
||||
set "MAVEN_PROJECTBASEDIR=%EXEC_DIR%"
|
||||
cd "%EXEC_DIR%"
|
||||
|
||||
:endDetectBaseDir
|
||||
|
||||
set "jvmConfig=\.mvn\jvm.config"
|
||||
if not exist "%MAVEN_PROJECTBASEDIR%%jvmConfig%" goto endReadAdditionalConfig
|
||||
|
||||
@setlocal EnableExtensions EnableDelayedExpansion
|
||||
for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
|
||||
@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
|
||||
|
||||
:endReadAdditionalConfig
|
||||
|
||||
for %%i in ("%MVND_HOME%"\boot\*.jar "%MVND_HOME%"\lib\ext\*.jar "%MVND_HOME%"\lib\*.jar) do set DAEMON_JAR="%%i"
|
||||
set DAEMON_LAUNCHER=org.jboss.fuse.mvnd.client.DefaultClient
|
||||
|
||||
"%JAVACMD%" ^
|
||||
%JVM_CONFIG_MAVEN_PROPS% ^
|
||||
%MAVEN_OPTS% ^
|
||||
%MAVEN_DEBUG_OPTS% ^
|
||||
-classpath %DAEMON_JAR% ^
|
||||
"-Dlogback.configurationFile=%MVND_HOME%\conf\logging\logback.xml" ^
|
||||
"-Dmvnd.home=%MAVEN_HOME%" ^
|
||||
"-Dmaven.home=%MAVEN_HOME%" ^
|
||||
"-Dlibrary.jansi.path=%MAVEN_HOME%\lib\jansi-native" ^
|
||||
"-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^
|
||||
%DAEMON_LAUNCHER% %MAVEN_CMD_LINE_ARGS%
|
||||
if ERRORLEVEL 1 goto error
|
||||
goto end
|
||||
|
||||
:error
|
||||
set ERROR_CODE=1
|
||||
|
||||
:end
|
||||
@endlocal & set ERROR_CODE=%ERROR_CODE%
|
||||
|
||||
if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost
|
||||
@REM check for post script, once with legacy .bat ending and once with .cmd ending
|
||||
if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat"
|
||||
if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd"
|
||||
:skipRcPost
|
||||
|
||||
@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
|
||||
if "%MAVEN_BATCH_PAUSE%"=="on" pause
|
||||
|
||||
if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE%
|
||||
|
||||
cmd /C exit /B %ERROR_CODE%
|
2
dist/src/main/distro/bin/mvnd.sh
vendored
2
dist/src/main/distro/bin/mvnd.sh
vendored
@@ -102,7 +102,7 @@ if [ ! -x "$JAVACMD" ] ; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
DAEMON_JAR=`echo "${MVND_HOME}"/mvn/lib/ext/*.jar "${MVND_HOME}"/mvn/lib/*.jar`
|
||||
DAEMON_JAR=`echo "${MVND_HOME}"/mvn/boot/*.jar "${MVND_HOME}"/mvn/lib/ext/*.jar "${MVND_HOME}"/mvn/lib/*.jar`
|
||||
DAEMON_JAR=$(echo $DAEMON_JAR | sed -e 's/ /:/g')
|
||||
DAEMON_LAUNCHER=org.jboss.fuse.mvnd.client.DefaultClient
|
||||
|
||||
|
Reference in New Issue
Block a user