From 2d53c43ee8ea2afa48bcfa5ce7f6b50346ba33c0 Mon Sep 17 00:00:00 2001 From: John Blum Date: Mon, 13 Sep 2021 15:34:05 -0700 Subject: [PATCH] Remove the deprecated org.springframework.data.gemfire.ForkUtil class. Resolves gh-296. --- .../data/gemfire/ForkUtil.java | 215 ------------------ .../gemfire/fork/CqCacheServerProcess.java | 7 +- .../fork/FunctionCacheServerProcess.java | 17 +- .../gemfire/fork/SpringContainerProcess.java | 8 +- 4 files changed, 11 insertions(+), 236 deletions(-) delete mode 100644 spring-data-geode/src/test/java/org/springframework/data/gemfire/ForkUtil.java diff --git a/spring-data-geode/src/test/java/org/springframework/data/gemfire/ForkUtil.java b/spring-data-geode/src/test/java/org/springframework/data/gemfire/ForkUtil.java deleted file mode 100644 index c6ddc58f..00000000 --- a/spring-data-geode/src/test/java/org/springframework/data/gemfire/ForkUtil.java +++ /dev/null @@ -1,215 +0,0 @@ -/* - * Copyright 2011-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.data.gemfire; - -import java.io.BufferedReader; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.concurrent.atomic.AtomicBoolean; - -import org.springframework.data.gemfire.fork.CqCacheServerProcess; -import org.springframework.data.gemfire.fork.FunctionCacheServerProcess; -import org.springframework.data.gemfire.tests.process.ProcessExecutor; -import org.springframework.data.gemfire.tests.util.IOUtils; -import org.springframework.data.gemfire.tests.util.ThreadUtils; -import org.springframework.util.StringUtils; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Utility class used to fork Java, JVM processes. - * - * @author Costin Leau - * @author John Blum - * @deprecated {@link ForkUtil} has serious design flaws; please use {@link ProcessExecutor} from STDG instead - */ -@Deprecated -public class ForkUtil { - - private static final long TIMEOUT = 30000L; - - private static final Logger logger = LoggerFactory.getLogger(ForkUtil.class); - - private static OutputStream processStandardInStream; - - private static final String JAVA_CLASSPATH = System.getProperty("java.class.path"); - private static final String JAVA_HOME = System.getProperty("java.home"); - private static final String JAVA_EXE = JAVA_HOME.concat(File.separator).concat("bin").concat(File.separator).concat("java"); - private static final String TEMP_DIRECTORY = System.getProperty("java.io.tmpdir"); - - private static List buildJavaCommand(String arguments) { - return buildJavaCommand(arguments.split("\\s+")); - } - - private static List buildJavaCommand(String[] args) { - List command = new ArrayList<>(args.length + 5); - - command.add(JAVA_EXE); - command.add("-server"); - command.add("-ea"); - command.add("-classpath"); - command.add(JAVA_CLASSPATH); - command.addAll(Arrays.asList(args)); - - return command; - } - - private static OutputStream cloneJVM(String arguments) { - AtomicBoolean runCondition = new AtomicBoolean(true); - - List command = buildJavaCommand(arguments); - - Process javaProcess; - - try { - javaProcess = Runtime.getRuntime().exec(command.toArray(new String[command.size()])); - - logger.debug("Started fork from command: {}", - StringUtils.arrayToDelimitedString(command.toArray()," ")); - - captureProcessStreams(runCondition, javaProcess); - registerShutdownHook(runCondition, javaProcess); - - processStandardInStream = javaProcess.getOutputStream(); - - return processStandardInStream; - } - catch (IOException e) { - throw new RuntimeException(String.format("Failed to fork JVM process using command [%s]", - StringUtils.arrayToDelimitedString(command.toArray(), " ")), e); - } - } - - private static void captureProcessStreams(AtomicBoolean runCondition, Process javaProcess) { - startNewThread(newProcessStreamReader(runCondition, javaProcess.getErrorStream(), "[FORK-ERR]")); - startNewThread(newProcessStreamReader(runCondition, javaProcess.getInputStream(), "[FORK-OUT]")); - } - - private static Thread startNewThread(Runnable runnable) { - Thread runnableThread = new Thread(runnable); - runnableThread.setDaemon(true); - runnableThread.setPriority(Thread.NORM_PRIORITY); - runnableThread.start(); - return runnableThread; - } - - private static Runnable newProcessStreamReader(AtomicBoolean runCondition, InputStream processStream, String label) { - return () -> { - BufferedReader processStreamReader = null; - - try { - processStreamReader = new BufferedReader(new InputStreamReader(processStream)); - - for (String line = "Reading..."; runCondition.get() && line != null; - line = processStreamReader.readLine()) { - - logger.debug("{} {}", label, line); - } - } - catch (Exception ignore) { - } - finally { - IOUtils.close(processStreamReader); - } - }; - } - - private static void registerShutdownHook(AtomicBoolean runCondition, Process javaProcess) { - - Runtime.getRuntime().addShutdownHook(new Thread(() -> { - - runCondition.set(false); - processStandardInStream = null; - - try { - javaProcess.destroyForcibly(); - javaProcess.waitFor(); - } - catch (InterruptedException ignore) { - Thread.currentThread().interrupt(); - } - })); - } - - public static OutputStream cacheServer(Class type) { - return startCacheServer(type.getName()); - } - - public static OutputStream cqCacheServer() { - return cacheServer(CqCacheServerProcess.class); - } - - public static OutputStream functionCacheServer() { - return cacheServer(FunctionCacheServerProcess.class); - } - - public static OutputStream startCacheServer(String args) { - return startGemFireProcess(args, "cache server"); - } - - protected static OutputStream startGemFireProcess(String args, String processName) { - - String className = args.split(" ")[0]; - - if (controlFileExists(className)) { - deleteControlFile(className); - } - - OutputStream outputStream = cloneJVM(args); - - long timeout = (System.currentTimeMillis() + TIMEOUT); - - while (!controlFileExists(className) && System.currentTimeMillis() < timeout) { - ThreadUtils.sleep(500L); - } - - if (!controlFileExists(className)) { - throw new RuntimeException(String.format("Failed to fork %s", processName)); - } - - return outputStream; - } - - public static void sendSignal() { - - try { - processStandardInStream.write("\n".getBytes()); - processStandardInStream.flush(); - } - catch (IOException e) { - logger.info("Cannot communicate with forked VM", e); - } - } - - public static boolean createControlFile( String name) throws IOException { - return new File(TEMP_DIRECTORY + File.separator + name).createNewFile(); - } - - public static boolean controlFileExists(String name) { - return new File(TEMP_DIRECTORY + File.separator + name).isFile(); - } - - public static boolean deleteControlFile(String name) { - return new File(TEMP_DIRECTORY + File.separator + name).delete(); - } -} diff --git a/spring-data-geode/src/test/java/org/springframework/data/gemfire/fork/CqCacheServerProcess.java b/spring-data-geode/src/test/java/org/springframework/data/gemfire/fork/CqCacheServerProcess.java index 63a03ad5..02bba73b 100644 --- a/spring-data-geode/src/test/java/org/springframework/data/gemfire/fork/CqCacheServerProcess.java +++ b/spring-data-geode/src/test/java/org/springframework/data/gemfire/fork/CqCacheServerProcess.java @@ -25,7 +25,6 @@ import org.apache.geode.cache.RegionFactory; import org.apache.geode.cache.RegionShortcut; import org.apache.geode.cache.server.CacheServer; -import org.springframework.data.gemfire.ForkUtil; import org.springframework.data.gemfire.util.SpringUtils; /** @@ -85,10 +84,8 @@ public class CqCacheServerProcess { return gemfireCache; } - @SuppressWarnings({ "deprecation", "unused" }) - private static void waitForShutdown(Cache gemfireCache) throws IOException { - - ForkUtil.createControlFile(CqCacheServerProcess.class.getName()); + @SuppressWarnings({ "unused" }) + private static void waitForShutdown(Cache gemfireCache) { Scanner scanner = new Scanner(System.in); diff --git a/spring-data-geode/src/test/java/org/springframework/data/gemfire/fork/FunctionCacheServerProcess.java b/spring-data-geode/src/test/java/org/springframework/data/gemfire/fork/FunctionCacheServerProcess.java index 5a170985..31b0fb45 100644 --- a/spring-data-geode/src/test/java/org/springframework/data/gemfire/fork/FunctionCacheServerProcess.java +++ b/spring-data-geode/src/test/java/org/springframework/data/gemfire/fork/FunctionCacheServerProcess.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.springframework.data.gemfire.fork; import java.io.IOException; @@ -31,8 +30,6 @@ import org.apache.geode.cache.execute.FunctionContext; import org.apache.geode.cache.execute.FunctionService; import org.apache.geode.cache.server.CacheServer; -import org.springframework.data.gemfire.ForkUtil; - /** * @author Costin Leau * @author David Turanski @@ -107,15 +104,13 @@ public class FunctionCacheServerProcess { return gemfireCache; } - @SuppressWarnings({ "deprecation", "unused" }) - private static void waitForShutdown(Cache gemfireCache) throws IOException { - ForkUtil.createControlFile(FunctionCacheServerProcess.class.getName()); + @SuppressWarnings({ "unused" }) + private static void waitForShutdown(Cache gemfireCache) { Scanner scanner = new Scanner(System.in); scanner.nextLine(); } - @SuppressWarnings("serial") - static class EchoFunction implements Function { + static class EchoFunction implements Function { @Override public String getId() { @@ -123,7 +118,9 @@ public class FunctionCacheServerProcess { } @Override + @SuppressWarnings("unchecked") public void execute(FunctionContext functionContext) { + Object[] arguments = (Object[]) functionContext.getArguments(); for (int index = 0; index < arguments.length; index++) { @@ -137,8 +134,8 @@ public class FunctionCacheServerProcess { } } - @SuppressWarnings("serial") - static class ServerFunction implements Function { + @SuppressWarnings("unchecked") + static class ServerFunction implements Function { @Override public String getId() { diff --git a/spring-data-geode/src/test/java/org/springframework/data/gemfire/fork/SpringContainerProcess.java b/spring-data-geode/src/test/java/org/springframework/data/gemfire/fork/SpringContainerProcess.java index 4a96facc..94f9f2b8 100644 --- a/spring-data-geode/src/test/java/org/springframework/data/gemfire/fork/SpringContainerProcess.java +++ b/spring-data-geode/src/test/java/org/springframework/data/gemfire/fork/SpringContainerProcess.java @@ -10,15 +10,12 @@ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * specific language governing permissions and limitations under the License. */ - package org.springframework.data.gemfire.fork; -import java.io.IOException; import java.util.Scanner; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; -import org.springframework.data.gemfire.ForkUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -63,9 +60,8 @@ public class SpringContainerProcess { } } - @SuppressWarnings({ "deprecation", "unused" }) - private static void waitForShutdown(ConfigurableApplicationContext applicationContext) throws IOException { - ForkUtil.createControlFile(SpringContainerProcess.class.getName()); + @SuppressWarnings({ "unused" }) + private static void waitForShutdown(ConfigurableApplicationContext applicationContext) { Scanner scanner = new Scanner(System.in); scanner.nextLine(); }