From a09357cd24066bbd1277423540de1c126b16ea41 Mon Sep 17 00:00:00 2001 From: Scott M Stark Date: Mon, 18 Nov 2024 01:28:47 -0600 Subject: [PATCH] Add ability to add ear lib to appclient classpath Signed-off-by: Scott M Stark --- .../protocol/appclient/AppClientCmd.java | 30 ++++++++++------ .../AppClientProtocolConfiguration.java | 34 ++++++++++++++++++- .../protocol/common/TsTestPropsBuilder.java | 2 +- glassfish-runner/assembly-tck/pom.xml | 6 ++-- .../test/resources/appclient-arquillian.xml | 2 +- 5 files changed, 58 insertions(+), 16 deletions(-) diff --git a/arquillian/appclient/src/main/java/tck/arquillian/protocol/appclient/AppClientCmd.java b/arquillian/appclient/src/main/java/tck/arquillian/protocol/appclient/AppClientCmd.java index a1a8d20cd8..cb286f8183 100644 --- a/arquillian/appclient/src/main/java/tck/arquillian/protocol/appclient/AppClientCmd.java +++ b/arquillian/appclient/src/main/java/tck/arquillian/protocol/appclient/AppClientCmd.java @@ -27,11 +27,9 @@ import java.util.logging.Logger; /** - * A base class that uses the {@link Runtime#exec(String[], String[], File)} method to launch a Jakarta EE appclient. - * Vendors override this class to provide implementations of: - * {@link #getAppClientCommand()} - the command line expected to invoke your Application Client main - * {@link #getAppClientEnv()} - optional environment variables that should be provided when running the Application client - * {@link #getAppClientDir()} - optional directory from which the appclient process should run + * A class that uses the {@link Runtime#exec(String[], String[], File)} method to launch a Jakarta EE appclient. + * Vendors configure the appclient via the {@link AppClientProtocolConfiguration} class using the + * protocol element of the arquillian.xml file. */ public class AppClientCmd { private static final Logger LOGGER = Logger.getLogger(AppClientCmd.class.getName()); @@ -47,6 +45,7 @@ public class AppClientCmd { private String[] clientEnvp = null; private File clientDir = null; private String clientEarDir; + private String clientEarLibClasspath; private CompletableFuture onExit; @@ -59,6 +58,7 @@ public AppClientCmd(AppClientProtocolConfiguration config) { clientEnvp = config.clientEnvAsArray(); clientDir = config.clientDirAsFile(); clientEarDir = config.getClientEarDir(); + clientEarLibClasspath = config.clientEarLibClasspath(); } public boolean waitForExit(long timeout, TimeUnit units) throws InterruptedException { @@ -114,7 +114,6 @@ public void run(String vehicleArchiveName, String clientAppArchive, String... ad ArrayList cmdList = new ArrayList(); - // Need to replace any property refs on command line File earDir = new File(clientEarDir); if(earDir.isAbsolute()) { @@ -135,21 +134,32 @@ public void run(String vehicleArchiveName, String clientAppArchive, String... ad arg = arg.replaceAll("\\$\\{clientAppArchive}", clientAppArchive); cmdLine[n] = arg; } - + if(arg.contains("${clientEarLibClasspath}")) { + arg = arg.replaceAll("\\$\\{clientEarLibClasspath}", clientEarLibClasspath); + cmdLine[n] = arg; + } + } + // Replace any ${clientEarLibClasspath} in the client ENV + for(int n = 0; n < clientEnvp.length; n++) { + String env = clientEnvp[n]; + if(env.contains("${clientEarLibClasspath}")) { + String env2 = env.replaceAll("\\$\\{clientEarLibClasspath}", clientEarLibClasspath); + LOGGER.info("Replaced clientEarLibClasspath in "+env2); + clientEnvp[n] = env2; + } } + // Split the command line into individual arguments based on spaces for (int n = 0; n < cmdLine.length; n ++) { - String arg = cmdLine[n]; cmdList.addAll(Arrays.asList(cmdLine[n].split(" "))); } + // Add any additional args if (additionalArgs != null) { String[] newCmdLine = new String[cmdLine.length + additionalArgs.length]; System.arraycopy(cmdLine, 0, newCmdLine, 0, cmdLine.length); System.arraycopy(additionalArgs, 0, newCmdLine, cmdLine.length, additionalArgs.length); - cmdLine = newCmdLine; cmdList.addAll(Arrays.asList(additionalArgs)); - } appClientProcess = Runtime.getRuntime().exec(cmdList.toArray(new String[0]), clientEnvp, clientDir); diff --git a/arquillian/appclient/src/main/java/tck/arquillian/protocol/appclient/AppClientProtocolConfiguration.java b/arquillian/appclient/src/main/java/tck/arquillian/protocol/appclient/AppClientProtocolConfiguration.java index e101026abb..dfd88a3c4d 100644 --- a/arquillian/appclient/src/main/java/tck/arquillian/protocol/appclient/AppClientProtocolConfiguration.java +++ b/arquillian/appclient/src/main/java/tck/arquillian/protocol/appclient/AppClientProtocolConfiguration.java @@ -1,5 +1,6 @@ package tck.arquillian.protocol.appclient; +import org.jboss.arquillian.container.spi.client.deployment.Deployment; import org.jboss.arquillian.container.test.spi.client.protocol.ProtocolConfiguration; import tck.arquillian.protocol.common.ProtocolCommonConfig; @@ -117,7 +118,12 @@ public String getClientCmdLineString() { * the parsed command line array elements are trimmed of leading and trailing whitespace. * The command line should be filtered against the ts.jte file if it contains any property references. In addition * to ts.jte property references, the command line can contain ${clientEarDir} which will be replaced with the - * #clientEarDir value. Any ${vehicleArchiveName} ref will be replaced with the vehicleArchiveName passed to the + * #clientEarDir value. Any ${vehicleArchiveName} ref will be replaced with the vehicle archive name extracted by + * {@link tck.arquillian.protocol.common.TsTestPropsBuilder#vehicleArchiveName(Deployment)}. + * Any ${clientAppArchive} ref will be replaced with the clientAppArchive extracted by the + * {@link AppClientDeploymentPackager} processing of the target appclient ear. + * Any ${clientEarLibClasspath} ref will be replaced with the classpath of the client ear lib directory if + * {@link #unpackClientEar} is true and the clientEarDir/lib directory exists. * @param clientCmdLineString */ public void setClientCmdLineString(String clientCmdLineString) { @@ -146,6 +152,12 @@ public void setClientDir(String clientDir) { public String getClientEarDir() { return clientEarDir; } + /** + * Set the directory to extract the final appclient ear test artifact. The default is "target/appclient". + * Any ${clientEarDir} ref in the {@link #clientCmdLineString} will be replaced with the clientEarDir + * value. + * @param clientEarDir + */ public void setClientEarDir(String clientEarDir) { this.clientEarDir = clientEarDir; } @@ -188,6 +200,26 @@ public File clientDirAsFile() { return dir; } + /** + * If #unpackClientEar is true, and clientEarDir/lib exists, then this method returns the contents + * of the clientEarDir/lib as a classpath string + * @return a classpath string for the client ear lib directory + */ + public String clientEarLibClasspath() { + StringBuilder cp = new StringBuilder(); + File libDir = new File(clientEarDir, "lib"); + if (unpackClientEar && libDir.exists()) { + File[] jars = libDir.listFiles(); + for (File jar : jars) { + if (!cp.isEmpty()) { + cp.append(File.pathSeparator); + } + cp.append(jar.getAbsolutePath()); + } + } + return cp.toString(); + } + /** * Parse the clientCmdLineString into an array of strings using the cmdLineArgSeparator. This calls String#split on the * clientCmdLineString and then trims each element of the resulting array. diff --git a/arquillian/common/src/main/java/tck/arquillian/protocol/common/TsTestPropsBuilder.java b/arquillian/common/src/main/java/tck/arquillian/protocol/common/TsTestPropsBuilder.java index f41f3ea94e..1f370090bc 100644 --- a/arquillian/common/src/main/java/tck/arquillian/protocol/common/TsTestPropsBuilder.java +++ b/arquillian/common/src/main/java/tck/arquillian/protocol/common/TsTestPropsBuilder.java @@ -104,7 +104,7 @@ public class TsTestPropsBuilder { /** * Get the deployment vehicle archive name from the deployment archive. This needs to be a vehicle deployment - * for the result to be value. + * for the result to be valid. * @param deployment - current test deployment * @return base vehicle archive name */ diff --git a/glassfish-runner/assembly-tck/pom.xml b/glassfish-runner/assembly-tck/pom.xml index 3fa2bc1bd4..27ae8bddcf 100644 --- a/glassfish-runner/assembly-tck/pom.xml +++ b/glassfish-runner/assembly-tck/pom.xml @@ -30,19 +30,19 @@ 1.9.1.Final ${project.build.directory}/${glassfish.toplevel.dir}/glassfish/bin/asadmin - - 8.0.0-JDK17-M7 ${project.build.directory}/${glassfish.toplevel.dir} glassfish8 + + 8.0.0-JDK17-M7 11.0.0-M2 5.10.2 assembly-tck 11.0.0-SNAPSHOT ./jakartaeetck 11.0.0-SNAPSHOT - 1.0.0-M17 + ${project.version} diff --git a/glassfish-runner/assembly-tck/src/test/resources/appclient-arquillian.xml b/glassfish-runner/assembly-tck/src/test/resources/appclient-arquillian.xml index 80a5f5f28f..f7eec6b54d 100644 --- a/glassfish-runner/assembly-tck/src/test/resources/appclient-arquillian.xml +++ b/glassfish-runner/assembly-tck/src/test/resources/appclient-arquillian.xml @@ -55,7 +55,7 @@ AS_JAVA=${env.JAVA_HOME};PATH=${env.PATH};LD_LIBRARY_PATH=${glassfish.home}/lib;AS_DEBUG=true; - APPCPATH=target/lib/libutil.jar:target/lib/arquillian-protocol-lib.jar:target/lib/tck-porting-lib.jar:target/appclient/lib/arquillian-core.jar:target/appclient/lib/arquillian-junit5.jar:${glassfish.home}/glassfish/modules/security.jar:${glassfish.home}/glassfish/lib/gf-client.jar + APPCPATH=${clientEarLibClasspath}:target/lib/libutil.jar:target/lib/arquillian-protocol-lib.jar:target/lib/tck-porting-lib.jar:target/appclient/lib/arquillian-core.jar:target/appclient/lib/arquillian-junit5.jar:${glassfish.home}/glassfish/modules/security.jar:${glassfish.home}/glassfish/lib/gf-client.jar ${project.basedir} /tmp jakartaeetck/bin/ts.jte