Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes java mode loading #3444

Merged
merged 4 commits into from
Jul 9, 2015
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 90 additions & 3 deletions app/src/processing/app/contrib/ModeContribution.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,17 @@
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.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 {
Expand Down Expand Up @@ -77,8 +83,7 @@ static public ModeContribution load(Base base, File folder,
private ModeContribution(Base base, File folder,
String className) throws Exception {
super(folder);

className = initLoader(className);
className = initLoader(base, className);
if (className != null) {
Class<?> modeClass = loader.loadClass(className);
Base.log("Got mode class " + modeClass);
Expand Down Expand Up @@ -175,6 +180,88 @@ public boolean equals(Object o) {
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 <modename>.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<URL> 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<String, Mode> 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<File> discover(File folder) {
Expand Down