From 6dbaabd4f12a8d598f57594e4c3150564bda5a54 Mon Sep 17 00:00:00 2001 From: Manindra Moharana Date: Tue, 30 Jun 2015 00:12:09 -0700 Subject: [PATCH 1/4] reloading with java mode Signed-off-by: Manindra Moharana --- .../app/contrib/LocalContribution.java | 55 +++++++++++++++++++ .../app/contrib/ModeContribution.java | 45 ++++++++++++--- 2 files changed, 91 insertions(+), 9 deletions(-) diff --git a/app/src/processing/app/contrib/LocalContribution.java b/app/src/processing/app/contrib/LocalContribution.java index 6508bf87e..4738bbc95 100644 --- a/app/src/processing/app/contrib/LocalContribution.java +++ b/app/src/processing/app/contrib/LocalContribution.java @@ -174,6 +174,61 @@ public abstract class LocalContribution extends Contribution { } return className; } + + public String initLoader(String className, URL[] extraUrls) throws Exception { + File modeDirectory = new File(folder, getTypeName()); + if (modeDirectory.exists()) { + Base.log("checking mode folder regarding " + className); + // If no class name specified, search the main .jar for the + // full name package and mode name. + if (className == null) { + String shortName = folder.getName(); + File mainJar = new File(modeDirectory, shortName + ".jar"); + if (mainJar.exists()) { + className = findClassInZipFile(shortName, mainJar); + } else { + throw new IgnorableException(mainJar.getAbsolutePath() + " does not exist."); + } + + if (className == null) { + throw new IgnorableException("Could not find " + shortName + + " class inside " + mainJar.getAbsolutePath()); + } + } + + // Add .jar and .zip files from the "mode" folder into the classpath + File[] archives = Base.listJarFiles(modeDirectory); + if (archives != null && archives.length > 0) { + int arrLen = archives.length; + if (extraUrls != null) { + arrLen += extraUrls.length; + } + URL[] urlList = new URL[arrLen]; + int j = 0; + if (extraUrls != null) { + for (; j < extraUrls.length; j++) { + //Base.log("Found archive " + archives[j] + " for " + getName()); + urlList[j] = extraUrls[j]; + } + } + for (int k = 0; k < archives.length; k++,j++) { + Base.log("Found archive " + archives[k] + " for " + getName()); + urlList[j] = archives[k].toURI().toURL(); + } +// loader = new URLClassLoader(urlList, Thread.currentThread().getContextClassLoader()); + loader = new URLClassLoader(urlList); + Base.log("loading above JARs with loader " + loader); +// System.out.println("listing classes for loader " + loader); +// listClasses(loader); + } + } + + // If no archives were found, just use the regular ClassLoader + if (loader == null) { + loader = Thread.currentThread().getContextClassLoader(); + } + return className; + } /* diff --git a/app/src/processing/app/contrib/ModeContribution.java b/app/src/processing/app/contrib/ModeContribution.java index d9200572a..67523e308 100644 --- a/app/src/processing/app/contrib/ModeContribution.java +++ b/app/src/processing/app/contrib/ModeContribution.java @@ -24,8 +24,11 @@ package processing.app.contrib; import java.io.File; import java.io.IOException; import java.lang.reflect.Constructor; +import java.net.URL; import java.net.URLClassLoader; -import java.util.*; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import processing.app.Base; import processing.app.Mode; @@ -77,16 +80,37 @@ public class ModeContribution extends LocalContribution { private ModeContribution(Base base, File folder, String className) throws Exception { super(folder); - + System.err.println("OOOLALALA "); className = initLoader(className); + System.err.println("LALALA " + loader.toString()); if (className != null) { - Class modeClass = loader.loadClass(className); - Base.log("Got mode class " + modeClass); - Constructor con = modeClass.getConstructor(Base.class, File.class); - mode = (Mode) con.newInstance(base, folder); - mode.setClassLoader(loader); - if (base != null) { - mode.setupGUI(); + try { + Class modeClass = loader.loadClass(className); + Base.log("Got mode class " + modeClass); + Constructor con = modeClass.getConstructor(Base.class, File.class); + mode = (Mode) con.newInstance(base, folder); + mode.setClassLoader(loader); + if (base != null) { + mode.setupGUI(); + } + } catch (NoClassDefFoundError ncdfe) { + System.err.println("OOPS " + ncdfe.getMessage() + " :" + Base.getContentFile("modes/java/mode/JavaMode.jar").exists()); + if (ncdfe.getMessage().equals("processing/mode/java/JavaMode")) { + System.err.println("OOPS2 " + ncdfe.getMessage()); + className = initLoader(className, new URL[]{Base.getContentFile("modes/java/mode/JavaMode.jar").toURI().toURL()}); + Class modeClass = loader.loadClass(className); + System.err.println("Reloading mode class " + modeClass + " with JavaMode" + Base.getContentFile("modes/java/mode/JavaMode.jar").toURI().toURL()); + + Constructor con = modeClass.getConstructor(Base.class, File.class); + mode = (Mode) con.newInstance(base, folder); + mode.setClassLoader(loader); + if (base != null) { + mode.setupGUI(); + } + } else { + throw new NoClassDefFoundError(ncdfe.getMessage() + " no class definition found."); + } +// throw new NoClassDefFoundError(ncdfe.getMessage() + " no class definition found."); } } } @@ -131,10 +155,13 @@ public class ModeContribution extends LocalContribution { try { contribModes.add(new ModeContribution(base, folder, null)); } catch (NoSuchMethodError nsme) { + System.err.println("1" + nsme.getMessage()); System.err.println(folder.getName() + " contains an incompatible Mode"); System.err.println(nsme.getMessage()); } catch (NoClassDefFoundError ncdfe) { + System.err.println("2" + ncdfe.getMessage()); System.err.println(folder.getName() + " contains an incompatible Mode"); + ncdfe.printStackTrace(); System.err.println(ncdfe.getMessage()); } catch (IgnorableException ig) { Base.log(ig.getMessage()); From 0ff712c397a1a4f8a3a81f6b0d07a6f6a95703ee Mon Sep 17 00:00:00 2001 From: Manindra Moharana Date: Tue, 30 Jun 2015 22:48:13 -0700 Subject: [PATCH 2/4] clean up --- app/src/processing/app/contrib/LocalContribution.java | 3 +++ app/src/processing/app/contrib/ModeContribution.java | 10 +++------- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/app/src/processing/app/contrib/LocalContribution.java b/app/src/processing/app/contrib/LocalContribution.java index 4738bbc95..a0963d9a5 100644 --- a/app/src/processing/app/contrib/LocalContribution.java +++ b/app/src/processing/app/contrib/LocalContribution.java @@ -176,6 +176,9 @@ public abstract class LocalContribution extends Contribution { } public String initLoader(String className, URL[] extraUrls) throws Exception { + + // initLoader(String) can call this with a null URL array + File modeDirectory = new File(folder, getTypeName()); if (modeDirectory.exists()) { Base.log("checking mode folder regarding " + className); diff --git a/app/src/processing/app/contrib/ModeContribution.java b/app/src/processing/app/contrib/ModeContribution.java index 67523e308..1d09ac4af 100644 --- a/app/src/processing/app/contrib/ModeContribution.java +++ b/app/src/processing/app/contrib/ModeContribution.java @@ -80,9 +80,7 @@ public class ModeContribution extends LocalContribution { private ModeContribution(Base base, File folder, String className) throws Exception { super(folder); - System.err.println("OOOLALALA "); className = initLoader(className); - System.err.println("LALALA " + loader.toString()); if (className != null) { try { Class modeClass = loader.loadClass(className); @@ -94,13 +92,11 @@ public class ModeContribution extends LocalContribution { mode.setupGUI(); } } catch (NoClassDefFoundError ncdfe) { - System.err.println("OOPS " + ncdfe.getMessage() + " :" + Base.getContentFile("modes/java/mode/JavaMode.jar").exists()); + // Reinitialise loader with JaavMode if (ncdfe.getMessage().equals("processing/mode/java/JavaMode")) { - System.err.println("OOPS2 " + ncdfe.getMessage()); + Base.log(folder.getAbsolutePath() + " extends JavaMode, reloading with javamode."); className = initLoader(className, new URL[]{Base.getContentFile("modes/java/mode/JavaMode.jar").toURI().toURL()}); Class modeClass = loader.loadClass(className); - System.err.println("Reloading mode class " + modeClass + " with JavaMode" + Base.getContentFile("modes/java/mode/JavaMode.jar").toURI().toURL()); - Constructor con = modeClass.getConstructor(Base.class, File.class); mode = (Mode) con.newInstance(base, folder); mode.setClassLoader(loader); @@ -108,9 +104,9 @@ public class ModeContribution extends LocalContribution { mode.setupGUI(); } } else { + // Some other issue throw new NoClassDefFoundError(ncdfe.getMessage() + " no class definition found."); } -// throw new NoClassDefFoundError(ncdfe.getMessage() + " no class definition found."); } } } From 0e68b954ee43a33664e14a66b81c02c4291784d1 Mon Sep 17 00:00:00 2001 From: Manindra Moharana Date: Tue, 30 Jun 2015 22:49:38 -0700 Subject: [PATCH 3/4] clean up --- app/src/processing/app/contrib/ModeContribution.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/app/src/processing/app/contrib/ModeContribution.java b/app/src/processing/app/contrib/ModeContribution.java index 1d09ac4af..96f571a51 100644 --- a/app/src/processing/app/contrib/ModeContribution.java +++ b/app/src/processing/app/contrib/ModeContribution.java @@ -151,13 +151,10 @@ public class ModeContribution extends LocalContribution { try { contribModes.add(new ModeContribution(base, folder, null)); } catch (NoSuchMethodError nsme) { - System.err.println("1" + nsme.getMessage()); System.err.println(folder.getName() + " contains an incompatible Mode"); System.err.println(nsme.getMessage()); } catch (NoClassDefFoundError ncdfe) { - System.err.println("2" + ncdfe.getMessage()); System.err.println(folder.getName() + " contains an incompatible Mode"); - ncdfe.printStackTrace(); System.err.println(ncdfe.getMessage()); } catch (IgnorableException ig) { Base.log(ig.getMessage()); From 630fb7222bd829ac86243700f990746a0faf70d3 Mon Sep 17 00:00:00 2001 From: Manindra Moharana Date: Tue, 7 Jul 2015 00:30:55 -0700 Subject: [PATCH 4/4] better dependency handling --- .../app/contrib/LocalContribution.java | 58 --------- .../app/contrib/ModeContribution.java | 119 ++++++++++++++---- 2 files changed, 93 insertions(+), 84 deletions(-) diff --git a/app/src/processing/app/contrib/LocalContribution.java b/app/src/processing/app/contrib/LocalContribution.java index a0963d9a5..6508bf87e 100644 --- a/app/src/processing/app/contrib/LocalContribution.java +++ b/app/src/processing/app/contrib/LocalContribution.java @@ -174,64 +174,6 @@ public abstract class LocalContribution extends Contribution { } return className; } - - public String initLoader(String className, URL[] extraUrls) throws Exception { - - // initLoader(String) can call this with a null URL array - - File modeDirectory = new File(folder, getTypeName()); - if (modeDirectory.exists()) { - Base.log("checking mode folder regarding " + className); - // If no class name specified, search the main .jar for the - // full name package and mode name. - if (className == null) { - String shortName = folder.getName(); - File mainJar = new File(modeDirectory, shortName + ".jar"); - if (mainJar.exists()) { - className = findClassInZipFile(shortName, mainJar); - } else { - throw new IgnorableException(mainJar.getAbsolutePath() + " does not exist."); - } - - if (className == null) { - throw new IgnorableException("Could not find " + shortName + - " class inside " + mainJar.getAbsolutePath()); - } - } - - // Add .jar and .zip files from the "mode" folder into the classpath - File[] archives = Base.listJarFiles(modeDirectory); - if (archives != null && archives.length > 0) { - int arrLen = archives.length; - if (extraUrls != null) { - arrLen += extraUrls.length; - } - URL[] urlList = new URL[arrLen]; - int j = 0; - if (extraUrls != null) { - for (; j < extraUrls.length; j++) { - //Base.log("Found archive " + archives[j] + " for " + getName()); - urlList[j] = extraUrls[j]; - } - } - for (int k = 0; k < archives.length; k++,j++) { - Base.log("Found archive " + archives[k] + " for " + getName()); - urlList[j] = archives[k].toURI().toURL(); - } -// loader = new URLClassLoader(urlList, Thread.currentThread().getContextClassLoader()); - loader = new URLClassLoader(urlList); - Base.log("loading above JARs with loader " + loader); -// System.out.println("listing classes for loader " + loader); -// listClasses(loader); - } - } - - // If no archives were found, just use the regular ClassLoader - if (loader == null) { - loader = Thread.currentThread().getContextClassLoader(); - } - return className; - } /* diff --git a/app/src/processing/app/contrib/ModeContribution.java b/app/src/processing/app/contrib/ModeContribution.java index 96f571a51..62b2f560d 100644 --- a/app/src/processing/app/contrib/ModeContribution.java +++ b/app/src/processing/app/contrib/ModeContribution.java @@ -26,12 +26,15 @@ import java.io.IOException; import java.lang.reflect.Constructor; import java.net.URL; import java.net.URLClassLoader; +import java.util.ArrayList; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; import processing.app.Base; import processing.app.Mode; +import processing.app.contrib.LocalContribution.IgnorableException; public class ModeContribution extends LocalContribution { @@ -80,33 +83,15 @@ public class ModeContribution extends LocalContribution { private ModeContribution(Base base, File folder, String className) throws Exception { super(folder); - className = initLoader(className); + className = initLoader(base, className); if (className != null) { - try { - Class modeClass = loader.loadClass(className); - Base.log("Got mode class " + modeClass); - Constructor con = modeClass.getConstructor(Base.class, File.class); - mode = (Mode) con.newInstance(base, folder); - mode.setClassLoader(loader); - if (base != null) { - mode.setupGUI(); - } - } catch (NoClassDefFoundError ncdfe) { - // Reinitialise loader with JaavMode - if (ncdfe.getMessage().equals("processing/mode/java/JavaMode")) { - Base.log(folder.getAbsolutePath() + " extends JavaMode, reloading with javamode."); - className = initLoader(className, new URL[]{Base.getContentFile("modes/java/mode/JavaMode.jar").toURI().toURL()}); - Class modeClass = loader.loadClass(className); - Constructor con = modeClass.getConstructor(Base.class, File.class); - mode = (Mode) con.newInstance(base, folder); - mode.setClassLoader(loader); - if (base != null) { - mode.setupGUI(); - } - } else { - // Some other issue - throw new NoClassDefFoundError(ncdfe.getMessage() + " no class definition found."); - } + Class modeClass = loader.loadClass(className); + Base.log("Got mode class " + modeClass); + Constructor con = modeClass.getConstructor(Base.class, File.class); + mode = (Mode) con.newInstance(base, folder); + mode.setClassLoader(loader); + if (base != null) { + mode.setupGUI(); } } } @@ -195,6 +180,88 @@ public class ModeContribution extends LocalContribution { ModeContribution other = (ModeContribution) o; return loader.equals(other.loader) && mode.equals(other.getMode()); } + + public String initLoader(Base base, String className) throws Exception { + + File modeDirectory = new File(folder, getTypeName()); + if (modeDirectory.exists()) { + Base.log("checking mode folder regarding " + className); + // If no class name specified, search the main .jar for the + // full name package and mode name. + if (className == null) { + String shortName = folder.getName(); + File mainJar = new File(modeDirectory, shortName + ".jar"); + if (mainJar.exists()) { + className = findClassInZipFile(shortName, mainJar); + } else { + throw new IgnorableException(mainJar.getAbsolutePath() + " does not exist."); + } + + if (className == null) { + throw new IgnorableException("Could not find " + shortName + + " class inside " + mainJar.getAbsolutePath()); + } + } + + ArrayList extraUrls = new ArrayList<>(); + if (imports != null && imports.size() > 0) { + // if the mode has any dependencies (defined as imports in mode.properties), + // add the dependencies to the classloader + + HashMap installedModes = new HashMap<>(); + for(Mode m: base.getModeList()){ + // Base.log("Mode contrib: " + m.getClass().getName() + " : "+ m.getFolder()); + installedModes.put(m.getClass().getName(), m); + } + + for(String modeImport: imports){ + if (installedModes.containsKey(modeImport)) { + Base.log("Found mode dependency " + modeImport); + File[] archives = Base.listJarFiles(new File(installedModes.get(modeImport). + getFolder().getAbsolutePath() + File.separator + "mode")); + if (archives != null && archives.length > 0) { + for (int i = 0; i < archives.length; i++) { + // Base.log("Adding jar dependency: " + archives[i].getAbsolutePath()); + extraUrls.add(archives[i].toURI().toURL()); + } + } + } else { + throw new IgnorableException("Dependency mode "+ modeImport + " could not be" + + " found. Can't load " + className); + } + } + } + + // Add .jar and .zip files from the "mode" folder into the classpath + File[] archives = Base.listJarFiles(modeDirectory); + if (archives != null && archives.length > 0) { + int arrLen = archives.length + extraUrls.size(); + URL[] urlList = new URL[arrLen]; + + int j = 0; + for (; j < extraUrls.size(); j++) { + //Base.log("Found archive " + archives[j] + " for " + getName()); + urlList[j] = extraUrls.get(j); + } + + for (int k = 0; k < archives.length; k++,j++) { + Base.log("Found archive " + archives[k] + " for " + getName()); + urlList[j] = archives[k].toURI().toURL(); + } + + loader = new URLClassLoader(urlList); + Base.log("loading above JARs with loader " + loader); +// System.out.println("listing classes for loader " + loader); +// listClasses(loader); + } + } + + // If no archives were found, just use the regular ClassLoader + if (loader == null) { + loader = Thread.currentThread().getContextClassLoader(); + } + return className; + } // static protected List discover(File folder) {