tzssangglass commented on code in PR #158:
URL: 
https://github.com/apache/apisix-java-plugin-runner/pull/158#discussion_r913059769


##########
runner-starter/src/main/java/org/apache/apisix/plugin/runner/PluginRunnerApplication.java:
##########
@@ -17,17 +17,138 @@
 
 package org.apache.apisix.plugin.runner;
 
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.beans.factory.support.BeanDefinitionRegistry;
+import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.boot.WebApplicationType;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.boot.builder.SpringApplicationBuilder;
+import org.springframework.context.ApplicationContext;
+import org.springframework.scheduling.annotation.EnableScheduling;
+
+import javax.tools.JavaCompiler;
+import javax.tools.ToolProvider;
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.FileSystems;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.WatchEvent;
+import java.nio.file.WatchKey;
+import java.nio.file.WatchService;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+
+import static java.nio.file.StandardWatchEventKinds.ENTRY_CREATE;
+import static java.nio.file.StandardWatchEventKinds.ENTRY_DELETE;
+import static java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY;
 
 @SpringBootApplication
+@EnableScheduling
 public class PluginRunnerApplication {
-    
+
+    @Autowired
+    private YAMLConfig myConfig;
+    @Autowired
+    private ApplicationContext ctx;
+    private static ClassLoader PARENT_CLASS_LOADER;
+    private static DynamicClassLoader CLASS_LOADER;
+
     public static void main(String[] args) {
+        PARENT_CLASS_LOADER = DynamicClassLoader.class.getClassLoader();
+        CLASS_LOADER = new DynamicClassLoader(PARENT_CLASS_LOADER);
+        Thread.currentThread().setContextClassLoader(CLASS_LOADER);
         new SpringApplicationBuilder(PluginRunnerApplication.class)
                 .web(WebApplicationType.NONE)
                 .run(args);
     }
-    
+
+    @Scheduled(fixedDelay = Long.MAX_VALUE, initialDelay = 1000)
+    public void reload() throws ClassNotFoundException, IOException, 
InterruptedException {
+        BeanDefinitionRegistry registry = (BeanDefinitionRegistry) 
ctx.getAutowireCapableBeanFactory();
+        WatchService watchService = FileSystems.getDefault().newWatchService();
+
+        String pathToProject = System.getProperty("user.dir");
+
+        //get packagename and path to user's filters from YAML file
+        String packageName = myConfig.getPackageName();
+        String absolutePath = myConfig.getPath();
+        if (packageName.equals("")) {
+            packageName = "org.apache.apisix.plugin.runner.filter";
+        }
+        if (absolutePath.equals("")) {
+            absolutePath = pathToProject + 
"/runner-plugin/src/main/java/org/apache/apisix/plugin/runner/filter/";
+        }
+        Path path = Paths.get(absolutePath);
+
+        //make /target/classes directory if not already exists, compiled java 
files are output here
+        new File(pathToProject + "/target").mkdirs();
+        new File(pathToProject + "/target/classes").mkdirs();
+
+        //detect changes when files in the path are created, modified, or 
deleted
+        path.register(watchService, ENTRY_CREATE, ENTRY_MODIFY, ENTRY_DELETE);
+        boolean poll = true;
+        while (poll) {
+            WatchKey key = watchService.take();
+            for (WatchEvent<?> event : key.pollEvents()) {
+                String[] allFilters = new File(absolutePath).list();
+                HashSet<String> set = new HashSet<>();
+
+                for (int i = 0; i < allFilters.length; i++) {
+                    //strangely, watchservice creates a file that ends with 
".java~", we ignore this file
+                    if (!allFilters[i].equals("package-info.java") && 
allFilters[i].charAt(allFilters[i].length() - 1) != '~') {
+                        allFilters[i] = allFilters[i].substring(0, 
allFilters[i].length() - 5);
+                        set.add(allFilters[i]);
+                    }
+                }
+
+                for (String filterName : allFilters) {
+                    if ((!filterName.equals("package-info.java")) && 
filterName.charAt(filterName.length() - 1) != '~') {
+                        //Bean Filter Name necessary because beans always 
start with lower case letters
+                        String beanFilterName = 
Character.toLowerCase(filterName.charAt(0)) + filterName.substring(1);
+                        if (registry.containsBeanDefinition(beanFilterName)) {
+                            registry.removeBeanDefinition(beanFilterName);
+                        }
+                        JavaCompiler compiler = 
ToolProvider.getSystemJavaCompiler();
+                        String[] args = {"-d", pathToProject + 
"/target/classes", absolutePath + filterName + ".java"};
+                        compiler.run(null, null, null, args);
+
+                        CLASS_LOADER = new 
DynamicClassLoader(PARENT_CLASS_LOADER);
+                        CLASS_LOADER.setDir(pathToProject + "/target/classes");
+                        CLASS_LOADER.setFilters(set);
+                        CLASS_LOADER.setPackageName(packageName);
+                        Class myObjectClass = 
CLASS_LOADER.loadClass(filterName);

Review Comment:
   ```suggestion
                           Class<?> myObjectClass = 
CLASS_LOADER.loadClass(filterName);
   ```



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscr...@apisix.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org

Reply via email to