From f45fc73beda8acedc4c603d19c52ad3be2a0d745 Mon Sep 17 00:00:00 2001 From: otrack <0track@gmail.com> Date: Sat, 23 Jan 2021 10:38:45 +0100 Subject: [PATCH] [server] fix dynamic jar loading; [client] better force new; [all] better docker image generation --- .../java/org/crucial/dso/client/Client.java | 42 +++++++++------- client/src/test/bin/image.sh | 5 +- server/src/main/bin/image.sh | 5 +- server/src/main/bin/server.sh | 4 +- .../src/main/java/org/crucial/dso/Server.java | 49 ++++++++++++------- .../dso/server/StateMachineInterceptor.java | 2 +- 6 files changed, 68 insertions(+), 39 deletions(-) diff --git a/client/src/main/java/org/crucial/dso/client/Client.java b/client/src/main/java/org/crucial/dso/client/Client.java index 3664b3d..bf89632 100644 --- a/client/src/main/java/org/crucial/dso/client/Client.java +++ b/client/src/main/java/org/crucial/dso/client/Client.java @@ -2,11 +2,8 @@ import org.crucial.dso.*; -import java.io.IOException; -import java.io.InputStream; import java.util.List; import java.util.Map; -import java.util.Properties; /** * A client interface for DSO. @@ -15,8 +12,6 @@ */ public class Client { - // - private static Client client; @Deprecated @@ -43,9 +38,8 @@ public synchronized static Client getClient() { return client; } - // - private Factory factory; + private boolean forceNew; public Client(){ factory = Factory.get(); } @@ -53,6 +47,16 @@ public synchronized static Client getClient() { public Client(String server, long seed) { factory = Factory.get(server, seed); } + public Client(Client client) { + this.factory = client.factory; + } + + public Client withForceNew(){ + Client ret = new Client(this); + ret.forceNew = true; + return ret; + } + public Logger getLog(String name) { return factory.getInstanceOf(Logger.class, name); } @@ -61,13 +65,13 @@ public List getAtomicList(String name) { return factory.getInstanceOf(AtomicList.class, name); } - public Future getFuture(String name, boolean forceNew) { + public Future getFuture(String name) { return forceNew ? factory.getInstanceOf(Future.class, name) - : factory.getInstanceOf(Future.class, name, false, false, false); + : factory.getInstanceOf(Future.class, name, false, false, this.forceNew); } public MonitorCyclicBarrier getMonitorCyclicBarrier(String name, int parties) { - return factory.getInstanceOf(MonitorCyclicBarrier.class, name, false, false, false, name, parties); + return factory.getInstanceOf(MonitorCyclicBarrier.class, name, false, false, this.forceNew, name, parties); } public CyclicBarrier getCyclicBarrier(String name, int parties) { @@ -93,7 +97,7 @@ public Semaphore getSemaphore(String name) { } public Semaphore getSemaphore(String name, int permits) { - return factory.getInstanceOf(Semaphore.class, name, false, false, false, name, permits); + return factory.getInstanceOf(Semaphore.class, name, false, false, this.forceNew, name, permits); } public AtomicLong getAtomicLong(String name) { @@ -101,7 +105,7 @@ public AtomicLong getAtomicLong(String name) { } public AtomicLong getAtomicLong(String name, long initialValue) { - return factory.getInstanceOf(AtomicLong.class, name, false, false, false, name, initialValue); + return factory.getInstanceOf(AtomicLong.class, name, false, false, this.forceNew, name, initialValue); } public AtomicByteArray getAtomicByteArray(String name) { @@ -109,7 +113,7 @@ public AtomicByteArray getAtomicByteArray(String name) { } public AtomicBoolean getAtomicBoolean(String name, boolean initialValue) { - return factory.getInstanceOf(AtomicBoolean.class, name, false, false, false, name, initialValue); + return factory.getInstanceOf(AtomicBoolean.class, name, false, false, this.forceNew, name, initialValue); } public AtomicBoolean getAtomicBoolean(String name) { @@ -117,7 +121,7 @@ public AtomicBoolean getAtomicBoolean(String name) { } public AtomicCounter getAtomicCounter(String name, int initialValue) { - return factory.getInstanceOf(AtomicCounter.class, name, false, false, false, name, initialValue); + return factory.getInstanceOf(AtomicCounter.class, name, false, false, this.forceNew, name, initialValue); } public Map getMap(){ @@ -128,12 +132,16 @@ public AtomicMap getAtomicMap(String name) { return factory.getInstanceOf(AtomicMap.class, name); } - public AtomicMatrix getAtomicMatrix(String name, Class clazz, int n, int m) { - return factory.getInstanceOf(AtomicMatrix.class, name, false, false, false, name, clazz, n, m); + public AtomicMatrix getAtomicMatrix(String name, Class clazz, Object zero, int n, int m) { + return factory.getInstanceOf(AtomicMatrix.class, name, false, false, this.forceNew, name, clazz, zero, n, m); + } + + public AtomicMatrix getAtomicMatrix(String name) { + return factory.getInstanceOf(AtomicMatrix.class, name, false, false, this.forceNew); } public Blob getAtomicBlob(String name) { - return factory.getInstanceOf(Blob.class, name, false, false, false); + return factory.getInstanceOf(Blob.class, name, false, false, this.forceNew); } public CountDownLatch getCountDownLatch(String name, int parties) { diff --git a/client/src/test/bin/image.sh b/client/src/test/bin/image.sh index 7e957a1..08560ba 100755 --- a/client/src/test/bin/image.sh +++ b/client/src/test/bin/image.sh @@ -13,10 +13,12 @@ if [ -z "${DOCKER_USER}" ]; then DOCKER_USER=0track fi -DIR=$(dirname "$0") +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" IMAGE=${DOCKER_USER}/dso-client-tests:${TAG} DOCKERFILE=${DIR}/../docker/Dockerfile +pushd ${DIR}/../../../ + # package mvn clean package -DskipTests @@ -28,3 +30,4 @@ docker build \ # push image docker push "${IMAGE}" +popd diff --git a/server/src/main/bin/image.sh b/server/src/main/bin/image.sh index 7cc39f4..a1d6cec 100755 --- a/server/src/main/bin/image.sh +++ b/server/src/main/bin/image.sh @@ -13,10 +13,12 @@ if [ -z "${DOCKER_USER}" ]; then DOCKER_USER=0track fi -DIR=$(dirname "$0") +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" IMAGE=${DOCKER_USER}/dso-server:${TAG} DOCKERFILE=${DIR}/../docker/Dockerfile +pushd ${DIR}/../../../ + # package mvn clean package -DskipTests @@ -31,3 +33,4 @@ docker build \ # push image docker push "${IMAGE}" +popd diff --git a/server/src/main/bin/server.sh b/server/src/main/bin/server.sh index 202e90e..f813033 100755 --- a/server/src/main/bin/server.sh +++ b/server/src/main/bin/server.sh @@ -53,7 +53,7 @@ fi cp ${CONFIG} jgroups.xml -JVM="${JVM_EXTRA} -Djava.net.preferIPv4Stack=true -Djgroups.tcp.address=${IP}" +JVM="${JVM_EXTRA} -Djava.net.preferIPv4Stack=true -Djgroups.tcp.address=${IP} --add-opens java.base/jdk.internal.loader=ALL-UNNAMED" CMD="java -ea -cp \"${CLASSPATH}\" ${JVM} org.crucial.dso.Server -server ${IP}:${PORT} ${EXTRA}" echo ${CMD} -bash -c "$CMD" +bash -c "$CMD" \ No newline at end of file diff --git a/server/src/main/java/org/crucial/dso/Server.java b/server/src/main/java/org/crucial/dso/Server.java index 39342e9..9fc6791 100644 --- a/server/src/main/java/org/crucial/dso/Server.java +++ b/server/src/main/java/org/crucial/dso/Server.java @@ -12,6 +12,7 @@ import org.infinispan.test.AbstractCacheTest; import org.infinispan.util.logging.Log; import org.infinispan.util.logging.LogFactory; +import org.jboss.marshalling.serial.Serial; import org.kohsuke.args4j.CmdLineException; import org.kohsuke.args4j.CmdLineParser; import org.kohsuke.args4j.Option; @@ -19,6 +20,11 @@ import sun.misc.SignalHandler; import java.io.File; +import java.lang.reflect.Method; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.ArrayList; +import java.util.List; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; @@ -88,14 +94,23 @@ public void doMain(String[] args) { return; } + List jars = new ArrayList<>(); Runnable runnable = () -> { - File folder = new File(userLib); - File[] listOfFiles = folder.listFiles(); - for (File file : listOfFiles) { - if (file.isFile() && file.getName().matches(".*\\.jar")) { - loadLibrary(file); + try { + File folder = new File(userLib); + log.info("Looking for user jars in "+userLib); + File[] listOfFiles = folder.listFiles(); + for (File file : listOfFiles) { + if (file.isFile() && file.getName().matches(".*\\.jar") && !jars.contains(file.getName())) { + loadLibrary(file); + jars.add(file.getName()); // FIXME checksum for re-loading? + } } + } catch (Exception e) { + e.printStackTrace(); + return; } + }; try { @@ -105,7 +120,7 @@ public void doMain(String[] args) { } ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); - scheduler.scheduleAtFixedRate(runnable, 3, 3, TimeUnit.SECONDS); + scheduler.scheduleAtFixedRate(runnable, 10, 10, TimeUnit.SECONDS); String host = server.split(":")[0]; int port = Integer.valueOf( @@ -192,18 +207,18 @@ public void doMain(String[] args) { public static synchronized void loadLibrary(java.io.File jar) { try { - java.net.URLClassLoader loader = (java.net.URLClassLoader) ClassLoader.getSystemClassLoader(); - java.net.URL url = jar.toURI().toURL(); - for (java.net.URL it : loader.getURLs()) { - if (it.equals(url)) { - return; - } - } System.out.println("Loading " + jar.getName()); - java.lang.reflect.Method method = java.net.URLClassLoader.class. - getDeclaredMethod("addURL", java.net.URL.class); - method.setAccessible(true); /*promote the method to public access*/ - method.invoke(loader, url); + ClassLoader classLoader = ClassLoader.getSystemClassLoader(); + try { + Method method = classLoader.getClass().getDeclaredMethod("addURL", URL.class); + method.setAccessible(true); + method.invoke(classLoader, jar.toURI().toURL()); + } catch (NoSuchMethodException e) { + Method method = classLoader.getClass() + .getDeclaredMethod("appendToClassPathForInstrumentation", String.class); + method.setAccessible(true); + method.invoke(classLoader, jar.getPath()); + } } catch (final java.lang.NoSuchMethodException | java.lang.IllegalAccessException | java.net.MalformedURLException | diff --git a/server/src/main/java/org/crucial/dso/server/StateMachineInterceptor.java b/server/src/main/java/org/crucial/dso/server/StateMachineInterceptor.java index dbe7cb4..7ada9cb 100644 --- a/server/src/main/java/org/crucial/dso/server/StateMachineInterceptor.java +++ b/server/src/main/java/org/crucial/dso/server/StateMachineInterceptor.java @@ -30,7 +30,7 @@ public class StateMachineInterceptor extends ClusteringInterceptor { @Override public java.lang.Object visitClearCommand(InvocationContext ctx, ClearCommand command) throws Throwable { - log.trace(" Clearing all"); + log.info(" Clearing all objects"); responseCache.clearAll(); return super.visitClearCommand(ctx, command);