Skip to content

Commit

Permalink
First prototype without java -/7 compat
Browse files Browse the repository at this point in the history
  • Loading branch information
marcanpilami committed Feb 27, 2024
1 parent 737d7ed commit 8d69de6
Show file tree
Hide file tree
Showing 15 changed files with 485 additions and 152 deletions.
77 changes: 45 additions & 32 deletions jqm-all/jqm-api/pom.xml
Original file line number Diff line number Diff line change
@@ -1,36 +1,49 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.enioka.jqm</groupId>
<artifactId>jqm-all</artifactId>
<version>2.2.10-SNAPSHOT</version>
</parent>
<artifactId>jqm-api</artifactId>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.enioka.jqm</groupId>
<artifactId>jqm-all</artifactId>
<version>2.2.10-SNAPSHOT</version>
</parent>
<artifactId>jqm-api</artifactId>

<name>${project.groupId}:${project.artifactId}</name>
<url>http://jqm.readthedocs.org</url>
<description>JQM public API interfaces</description>
<name>${project.groupId}:${project.artifactId}</name>
<url>http://jqm.readthedocs.org</url>
<description>JQM public API interfaces</description>

<build>
<plugins>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<id>copy-xsd</id>
<goals>
<goal>run</goal>
</goals>
<phase>compile</phase>
<configuration>
<tasks>
<copy file="${project.build.directory}/../../jqm-xml/src/main/resources/res.xsd" tofile="${project.build.directory}/classes/res.xsd" />
</tasks>
</configuration>
</execution>
</executions>
</plugin>
<build>
<plugins>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<id>copy-xsd</id>
<goals>
<goal>run</goal>
</goals>
<phase>compile</phase>
<configuration>
<tasks>
<copy file="${project.build.directory}/../../jqm-xml/src/main/resources/res.xsd" tofile="${project.build.directory}/classes/res.xsd" />
</tasks>
</configuration>
</execution>
</executions>
</plugin>

</plugins>
</build>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifestEntries>
<Automatic-Module-Name>com.enioka.jqm.payload.api</Automatic-Module-Name>
</manifestEntries>
</archive>
</configuration>
</plugin>

</plugins>
</build>
</project>
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,25 @@

import java.io.File;
import java.lang.management.ManagementFactory;
import java.lang.module.Configuration;
import java.lang.module.ModuleDescriptor;
import java.lang.module.ModuleFinder;
import java.lang.module.ModuleReference;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.file.Path;
import java.rmi.Remote;
import java.rmi.registry.Registry;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import javax.management.MBeanServer;
import javax.management.ObjectName;
Expand All @@ -54,7 +59,7 @@

/**
* This class implements a basic JNDI context
*
*
*/
class JndiContext extends InitialContext implements InitialContextFactoryBuilder, InitialContextFactory, NameParser
{
Expand All @@ -64,13 +69,14 @@ class JndiContext extends InitialContext implements InitialContextFactoryBuilder
private List<ObjectName> jmxNames = new ArrayList<ObjectName>();
private Registry r = null;
private ClassLoader extResources;
private ModuleLayer extLayer;

/**
* Will create a JNDI Context and register it as the initial context factory builder
*
*
* @return the context
* @throws NamingException
* on any issue during initial context factory builder registration
* on any issue during initial context factory builder registration
*/
static JndiContext createJndiContext() throws NamingException
{
Expand Down Expand Up @@ -98,7 +104,7 @@ static JndiContext createJndiContext() throws NamingException

/**
* Create a new Context
*
*
* @throws NamingException
*/
private JndiContext() throws NamingException
Expand Down Expand Up @@ -128,18 +134,26 @@ private JndiContext() throws NamingException

// Create classloader
final URL[] aUrls = urls.toArray(new URL[0]);
final Path[] aPaths = new Path[aUrls.length];
for (URL u : aUrls)
{
aPaths[urls.indexOf(u)] = Path.of(u.getPath());
jqmlogger.trace(u.toString());
}
extResources = AccessController.doPrivileged(new PrivilegedAction<URLClassLoader>()
{
@Override
public URLClassLoader run()
{
return new URLClassLoader(aUrls, getParentCl());
}
});
// TODO: test if java >=9
/*
* extResources = AccessController.doPrivileged(new PrivilegedAction<URLClassLoader>() {
*
* @Override public URLClassLoader run() { return new URLClassLoader(aUrls, getParentCl()); } });
*/

ModuleFinder moduleFinder = ModuleFinder.of(aPaths);
Set<String> moduleNames = moduleFinder.findAll().stream().map(ModuleReference::descriptor).map(ModuleDescriptor::name)
.collect(Collectors.toUnmodifiableSet());
Configuration cf = ModuleLayer.boot().configuration().resolveAndBind(ModuleFinder.of(), moduleFinder, moduleNames);
extLayer = ModuleLayer.boot().defineModulesWithOneLoader(cf, getParentCl());
extResources = extLayer.modules().isEmpty() ? new URLClassLoader(new URL[0])
: extLayer.modules().iterator().next().getClassLoader();
}
else
{
Expand Down Expand Up @@ -356,7 +370,7 @@ public void bind(Name name, Object obj) throws NamingException

/**
* Will register the given Registry as a provider for the RMI: context. If there is already a registered Registry, the call is ignored.
*
*
* @param r
*/
void registerRmiContext(Registry r)
Expand All @@ -375,6 +389,11 @@ ClassLoader getExtCl()
return this.extResources;
}

public ModuleLayer getModuleLayer()
{
return this.extLayer;
}

@Override
public void unbind(Name name) throws NamingException
{
Expand Down Expand Up @@ -427,4 +446,4 @@ private static ClassLoader getParentCl()
throw new JqmInitError("Could not fetch Platform Class Loader", e);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,20 @@ public ClassLoader getExtensionClassloader()
return extLoader;
}

@Override
public ModuleLayer getExtensionModuleLayer()
{
try
{
return ((JndiContext) NamingManager.getInitialContext(null)).getModuleLayer();
}
catch (NamingException e)
{
jqmlogger.warn("could not find ext directory class loader. It will not be used", e);
return null;
}
}

@Override
public ClassLoader getEngineClassloader()
{
Expand Down
4 changes: 2 additions & 2 deletions jqm-all/jqm-integration-tests/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@
<artifactId>jqm-api</artifactId>
<version>${project.version}</version>
</artifactItem>
<dependency>
<!--<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
<version>${mail.version}</version>
Expand All @@ -113,7 +113,7 @@
<groupId>com.sun.mail</groupId>
<artifactId>smtp</artifactId>
<version>${mail.version}</version>
</dependency>
</dependency>-->

</artifactItems>
<outputDirectory>${project.basedir}/ext</outputDirectory>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package com.enioka.jqm.tools;

import org.junit.Assert;
import org.junit.Test;

import com.enioka.jqm.api.JobRequest;
import com.enioka.jqm.test.helpers.CreationTools;
import com.enioka.jqm.test.helpers.TestHelpers;

public class EngineJpmsTest extends JqmBaseTest
{
@Test
public void testJpmsModuleStartsWithApi()
{
addAndStartEngine();

CreationTools.createJobDef(null, true, "com.enioka.jqm.tests.jpms/com.enioka.jqm.tests.jpms.SimpleJpmsPayload", null,
"jqm-tests/jqm-test-jpms/target/test.jar", TestHelpers.qVip, -1, "SimpleJpmsPayload", null, null, null, null, null, false,
cnx, null, false);
JobRequest.create("SimpleJpmsPayload", null).submit();

TestHelpers.waitFor(1, 10000, cnx);

Assert.assertEquals(1, TestHelpers.getOkCount(cnx));
Assert.assertEquals(0, TestHelpers.getNonOkCount(cnx));
}

@Test
public void testNonJpmsStartInClassicMode()
{
addAndStartEngine();

CreationTools.createJobDef(null, true, "pyl.Nothing", null, "jqm-tests/jqm-test-pyl-nodep/target/test.jar", TestHelpers.qVip, -1,
"SimpleNonJpmsPayload", null, null, null, null, null, false, cnx, null, false);
JobRequest.create("SimpleNonJpmsPayload", null).submit();

TestHelpers.waitFor(1, 10000, cnx);

Assert.assertEquals(1, TestHelpers.getOkCount(cnx));
Assert.assertEquals(0, TestHelpers.getNonOkCount(cnx));
}

@Test
public void testNonJpmsStartInJpmsMode()
{
addAndStartEngine();

// Note we are using an automatic module name here.
CreationTools.createJobDef(null, true, "test/pyl.Nothing", null, "jqm-tests/jqm-test-pyl-nodep/target/test.jar", TestHelpers.qVip,
-1, "SimpleNonJpmsPayload", null, null, null, null, null, false, cnx, null, false);
JobRequest.create("SimpleNonJpmsPayload", null).submit();

TestHelpers.waitFor(1, 10000, cnx);

Assert.assertEquals(1, TestHelpers.getOkCount(cnx));
Assert.assertEquals(0, TestHelpers.getNonOkCount(cnx));
}

@Test
public void testJpmsWithJndiCall()
{
// This tests checks the JNDI provider located inside the ext layer is accessible to the payload.
CreationTools.createJndiFile(cnx, "fs/test", "test resource", "/tmp");

JqmSimpleTest.create(cnx, "test/pyl.JndiFile", "jqm-test-pyl-nodep").run(this);
}

@Test
public void testNonJpmsWithJndiCall()
{
// Sanity check.
CreationTools.createJndiFile(cnx, "fs/test", "test resource", "/tmp");

JqmSimpleTest.create(cnx, "pyl.JndiFile", "jqm-test-pyl-nodep").run(this);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@ public interface JobRunnerCallback
{
/**
* Should the runner use JMX?
*
*
* @return
*/
public boolean isJmxEnabled();

/**
* Generates the name the runner should use as a JMX bean if it registers a bean.
*
*
* @return
*/
public String getJmxBeanName();
Expand All @@ -30,21 +30,23 @@ public interface JobRunnerCallback

/**
* Fetches a more or less accurate current run time of the running JI.
*
*
* @return
*/
public Long getRunTimeSeconds();

/**
* This CL contains /ext and has the bootstrap CL as parent.
*
*
* @return
*/
public ClassLoader getExtensionClassloader();

public ModuleLayer getExtensionModuleLayer();

/**
* This is the normal CL of the engine. It should never be visible to payloads.
*
*
* @return
*/
public ClassLoader getEngineClassloader();
Expand All @@ -58,4 +60,4 @@ public interface JobRunnerCallback
* How to contact the WS.
*/
public String getWebApiLocalUrl(DbConn cnx);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ public State run()
// Go! (launches the main function in the startup class designated in the manifest)
try
{
jobClassLoader.launchJar(job, job.getPrms(), clm, handler);
jobClassLoader.launchJar(job, job.getPrms(), clm, handler, engineCallback.getExtensionModuleLayer());
return State.ENDED;
}
catch (JqmKillException e)
Expand Down
Loading

0 comments on commit 8d69de6

Please sign in to comment.