new class loader and additional jni fixes

This commit is contained in:
benfry
2005-02-01 04:10:22 +00:00
parent 0182bc6fce
commit 944e39a9d3
9 changed files with 450 additions and 72 deletions
+90 -15
View File
@@ -48,6 +48,8 @@ public class PdeBase {
static String openedAtStartup;
static ClassLoader loader;
PdeEditor editor;
static final int WINDOWS = 1;
@@ -139,6 +141,10 @@ public class PdeBase {
// show the window
editor.show();
// maybe?
loader = new PdeClassLoader();
}
@@ -157,7 +163,11 @@ public class PdeBase {
static public File getProcessingDataFolder() {
File dataFolder = null;
if (platform == MACOSX) {
String pref = PdePreferences.get("settings.path");
if (pref != null) {
dataFolder = new File(pref);
} else if (platform == MACOSX) {
// carbon folder constants
// http://developer.apple.com/documentation/Carbon/Reference
// /Folder_Manager/folder_manager_ref/constant_6.html#/
@@ -212,8 +222,8 @@ public class PdeBase {
String appDataPath = localKey.getStringValue("AppData");
//System.out.println("app data path is " + appDataPath);
//System.exit(0);
topKey.closeKey(); // necessary?
localKey.closeKey();
//topKey.closeKey(); // necessary?
//localKey.closeKey();
dataFolder = new File(appDataPath, "Processing");
@@ -230,7 +240,25 @@ public class PdeBase {
}
// create the folder if it doesn't exist already
if (!dataFolder.exists()) dataFolder.mkdirs();
boolean result = true;
if (!dataFolder.exists()) {
result = dataFolder.mkdirs();
}
if (!result) {
// try the fallback location
String fallback = PdePreferences.get("settings.path.fallback");
dataFolder = new File(fallback);
if (!dataFolder.exists()) {
result = dataFolder.mkdirs();
}
}
if (!result) {
showError("Settings issues",
"Processing cannot run because it could not\n" +
"create a folder to store your settings.", null);
}
return dataFolder;
}
@@ -241,6 +269,27 @@ public class PdeBase {
}
static public File getBuildFolder() {
File folder = new File(getProcessingDataFolder(), "build");
if (!folder.exists()) folder.mkdirs();
return folder;
}
/*
static public void addBuildFolderToClassPath() {
String path = getBuildFolder().getAbsolutePath();
String jcp = System.getProperty("java.class.path");
if (jcp.indexOf(path) == -1) {
System.setProperty("java.class.path", path + File.pathSeparator + jcp);
//return new File(getProcessingDataFolder(), "build");
System.out.println("jcp is now " +
System.getProperty("java.class.path"));
}
}
*/
static public File getDefaultSketchbookFolder() {
File sketchbookFolder = null;
@@ -291,8 +340,8 @@ public class PdeBase {
"\\Explorer\\Shell Folders";
RegistryKey localKey = topKey.openSubKey(localKeyPath);
String personalPath = localKey.getStringValue("Personal");
topKey.closeKey(); // necessary?
localKey.closeKey();
//topKey.closeKey(); // necessary?
//localKey.closeKey();
sketchbookFolder = new File(personalPath, "Processing");
@@ -300,18 +349,44 @@ public class PdeBase {
showError("Problem getting documents folder",
"Error getting the Processing sketchbook folder.", e);
}
} else {
// on linux (or elsewhere?) prompt the user for the location
JFileChooser fc = new JFileChooser();
//fc.setSelectedFile(new File(sketchbookLocationField.getText()));
fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
int returned = fc.showOpenDialog(new JDialog());
if (returned == JFileChooser.APPROVE_OPTION) {
//File file = fc.getSelectedFile();
//sketchbookLocationField.setText(file.getAbsolutePath());
sketchbookFolder = fc.getSelectedFile();
} else {
System.exit(0);
}
}
// if it failed, or if on linux, prompt the user or quit
/*
File home = new File(System.getProperty("user.home"));
File phome = new File(home, ".processing");
if (!phome.exists()) phome.mkdirs();
return phome;
*/
// create the folder if it doesn't exist already
if (!sketchbookFolder.exists()) sketchbookFolder.mkdirs();
boolean result = true;
if (!sketchbookFolder.exists()) {
result = sketchbookFolder.mkdirs();
}
if (!result) {
// try the fallback location
String fallback = PdePreferences.get("sketchbook.path.fallback");
sketchbookFolder = new File(fallback);
if (!sketchbookFolder.exists()) {
result = sketchbookFolder.mkdirs();
}
}
if (!result) {
showError("error",
"Processing cannot run because it could not\n" +
"create a folder to store your sketchbook.", null);
}
return sketchbookFolder;
}
+225
View File
@@ -0,0 +1,225 @@
/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */
/**
* Based on Simple1.2ClassLoader.java - simple Java 1.2 class loader
* Copyright (c) 1999 Ken McCrary, All Rights Reserved.
*
* Permission to use, copy, modify, and distribute this software
* and its documentation for NON-COMMERCIAL purposes and without
* fee is hereby granted provided that this copyright notice
* appears in all copies.
*
* KEN MCCRARY MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE
* SUITABILITY OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING
* BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. KEN MCCRARY
* SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT
* OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
*/
import java.io.*;
import java.net.*;
import java.util.*;
import java.util.jar.*;
/**
* Simple class loader to illustrate custom Class
* loading with new delegation model in Java 1.2.
*
*/
public class PdeClassLoader extends ClassLoader {
String buildFolderPath;
/*
PdeClassLoader(ClassLoader parent) {
super(parent);
init();
}
*/
PdeClassLoader() {
//super(); // uses system class loader
//init();
//}
//private void init() {
buildFolderPath = PdeBase.getBuildFolder().getAbsolutePath();
/*
FileInputStream fi = null;
// Check for a manifest in the store directory
try
{
fi = new FileInputStream("store\\MANIFEST.MF");
manifest = new Manifest(fi);
}
catch (Exception e)
{
// No manifest
}
finally
{
if ( null != fi )
{
try
{
fi.close();
}
catch (Exception e){}
}
}
*/
}
/**
* This is the method where the task of class loading
* is delegated to our custom loader.
*
* @param name the name of the class
* @return the resulting <code>Class</code> object
* @exception ClassNotFoundException if the class could not be found
*/
protected Class findClass(String name) throws ClassNotFoundException
{
FileInputStream fi = null;
try {
//System.out.println("PCL finding class: " + name);
String path =
buildFolderPath + File.separator + name.replace('.', '/');
//System.out.println("(from " + path + ")");
fi = new FileInputStream(path + ".class");
byte[] classBytes = new byte[fi.available()];
fi.read(classBytes);
//definePackage(name);
return defineClass(name, classBytes, 0, classBytes.length);
} catch (Exception e) {
// We could not find the class, so indicate the problem with an exception
throw new ClassNotFoundException(name);
} finally {
if (fi != null) {
try {
fi.close();
} catch (Exception e) { }
}
}
}
/**
* Identify where to load a resource from, resources for
* this simple ClassLoader are in a directory name "store"
*
* @param name the resource name
* @return URL for resource or null if not found
*/
protected URL findResource(String name) {
String path =
buildFolderPath + File.separator + name.replace('.', '/');
File searchResource = new File(path, name);
//URL result = null;
if (searchResource.exists()) {
try {
return searchResource.toURL();
} catch (MalformedURLException mfe) { }
}
//return result;
return null;
}
/**
* Used for identifying resources from multiple URLS
* Since our simple Classloader only has one repository
* the returned Enumeration contains 0 to 1 items
*
* @param name the resource name
* @return Enumeration of one URL
*/
protected Enumeration findResources(final String name) throws IOException {
// Since we only have a single repository we will only have one
// resource of a particular name, the Enumeration will just return
// this single URL
return new Enumeration() {
URL resource = findResource(name);
public boolean hasMoreElements() {
return ( resource != null ? true : false);
}
public Object nextElement() {
if (!hasMoreElements()) {
throw new NoSuchElementException();
} else {
URL result = resource;
resource = null;
return result;
}
}
};
}
/**
* Minimal package definition
*
*/
/*
private void definePackage(String className)
{
// Extract the package name from the class name,
String pkgName = className;
int index = className.lastIndexOf('.');
if (-1 != index)
{
pkgName = className.substring(0, index);
}
// Pre-conditions - need a manifest and the package
// is not previously defined
if ( null == manifest ||
getPackage(pkgName) != null)
{
return;
}
String specTitle,
specVersion,
specVendor,
implTitle,
implVersion,
implVendor;
// Look up the versioning information
// This should really look for a named attribute
Attributes attr = manifest.getMainAttributes();
if ( null != attr)
{
specTitle = attr.getValue(Name.SPECIFICATION_TITLE);
specVersion = attr.getValue(Name.SPECIFICATION_VERSION);
specVendor = attr.getValue(Name.SPECIFICATION_VENDOR);
implTitle = attr.getValue(Name.IMPLEMENTATION_TITLE);
implVersion = attr.getValue(Name.IMPLEMENTATION_VERSION);
implVendor = attr.getValue(Name.IMPLEMENTATION_VENDOR);
definePackage(pkgName,
specTitle,
specVersion,
specVendor,
implTitle,
implVersion,
implVendor,
null); // no sealing for simplicity
}
}
private Manifest manifest;
*/
}
+17
View File
@@ -1039,6 +1039,22 @@ public class PdeEditor extends JFrame
presentationWindow.toFront();
}
try {
if (!sketch.handleRun()) return;
runtime = new PdeRuntime(sketch, PdeEditor.this);
runtime.start(presenting ? presentLocation : appletLocation);
watcher = new RunButtonWatcher();
} catch (PdeException e) {
error(e);
} catch (Exception e) {
e.printStackTrace();
}
// this doesn't seem to help much or at all
/*
final SwingWorker worker = new SwingWorker() {
public Object construct() {
try {
@@ -1058,6 +1074,7 @@ public class PdeEditor extends JFrame
}
};
worker.start();
*/
//sketch.cleanup(); // where does this go?
}
+5 -2
View File
@@ -128,7 +128,8 @@ public class PdeRuntime implements PdeMessageConsumer {
} else { // !externalRuntime
//Class c = Class.forName(className);
Class c = Class.forName(sketch.mainClassName);
//Class c = Class.forName(sketch.mainClassName);
Class c = PdeBase.loader.loadClass(sketch.mainClassName);
applet = (PApplet) c.newInstance();
// replaces setRuntime with PApplet having leechErr [fry]
@@ -569,7 +570,9 @@ java.lang.NullPointerException
// unless this is set to min, it seems to hork the app
// since it's in charge of stuffing the editor console with strings
// maybe it's time to get rid of/fix that friggin console
thread.setPriority(Thread.MIN_PRIORITY);
// ...disabled for 0075, with 0074's fix for code folder hanging
// this only seems to make the console unresponsive
//thread.setPriority(Thread.MIN_PRIORITY);
thread.start();
}
+19 -5
View File
@@ -35,7 +35,7 @@ import com.oroinc.text.regex.*;
public class PdeSketch {
static String TEMP_BUILD_PATH = "lib" + File.separator + "build";
//static String TEMP_BUILD_PATH = "lib" + File.separator + "build";
static File tempBuildFolder;
PdeEditor editor;
@@ -100,6 +100,7 @@ public class PdeSketch {
// exist when the application is started, then java will remove
// the entry from the CLASSPATH, causing PdeRuntime to fail.
//
/*
tempBuildFolder = new File(TEMP_BUILD_PATH);
if (!tempBuildFolder.exists()) {
tempBuildFolder.mkdirs();
@@ -109,6 +110,9 @@ public class PdeSketch {
"It has now been replaced, please restart \n" +
"the application to complete the repair.", null);
}
*/
tempBuildFolder = PdeBase.getBuildFolder();
//PdeBase.addBuildFolderToClassPath();
folder = new File(new File(path).getParent());
//System.out.println("sketch dir is " + folder);
@@ -912,7 +916,9 @@ public class PdeSketch {
"_" + String.valueOf((int) (Math.random() * 10000)));
// handle preprocessing the main file's code
mainClassName = build(TEMP_BUILD_PATH, suggestedClassName);
//mainClassName = build(TEMP_BUILD_PATH, suggestedClassName);
mainClassName =
build(tempBuildFolder.getAbsolutePath(), suggestedClassName);
// externalPaths is magically set by build()
if (!externalRuntime) { // only if not running externally already
@@ -1048,12 +1054,16 @@ public class PdeSketch {
//PApplet.printarr(codeFolderPackages);
} else {
/*
// check to see if multiple files that include a .java file
externalRuntime = false;
for (int i = 0; i < codeCount; i++) {
if (code[i].flavor == JAVA) externalRuntime = true;
}
//externalRuntime = (codeCount > 1); // may still be set true later
*/
// since using the special classloader,
// run externally whenever there are extra classes defined
externalRuntime = (codeCount > 1);
//codeFolderPackages = null;
libraryPath = "";
}
@@ -1081,6 +1091,12 @@ public class PdeSketch {
}
}
// since using the special classloader,
// run externally whenever there are extra classes defined
if ((bigCode.indexOf(" class ") != -1) ||
(bigCode.indexOf("\nclass ") != -1)) {
externalRuntime = true;
}
// 2. run preproc on that code using the sugg class name
// to create a single .java file and write to buildpath
@@ -1092,8 +1108,6 @@ public class PdeSketch {
// if (i != 0) preproc will fail if a pde file is not
// java mode, since that's required
String className =
// preprocessor.write(bigCode.toString(), buildPath,
// suggestedClassName);
preprocessor.write(bigCode.toString(), buildPath,
suggestedClassName, codeFolderPackages);
if (className == null) {
+37 -9
View File
@@ -1,15 +1,46 @@
# !!!!!!!! UNLIKE PREVIOUS VERSIONS OF PROCESSING !!!!!!!!!!
# DO NOT MODIFY THIS FILE, OR DELETE SETTINGS FROM THIS FILE
# These are the default preferences. They will be copied to:
# My Documents -> Processing -> preferences.txt (on windows)
# Documents -> Processing -> preferences.txt (on macosx)
# ~/.processing/preferences.txt (on linux)
# where you can make changes for your machine.
# These are the default preferences. If you want to modify
# them directly, use the per-user local version of the file:
# Documents and Settings -> Application Data ->
# Processing -> preferences.txt (on windows)
# ~/Library -> Processing -> preferences.txt (on macosx)
# ~/.processing -> preferences.txt (on linux)
# You'll have problems running Processing if you incorrectly
# modify lines in this file.
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# DEFAULT PATHS FOR SKETCHBOOK AND SETTINGS
# relative paths will be relative to processing.exe or procesing.app.
# absolute paths may also be used.
# note that this path should use forward slashes (like unix)
# instead of \ on windows or : on macos or whatever else
# the .fallback locations are used in case the default location
# cannot be written (and the line above it is not customized)
# if you don't want users to have their sketchbook default to
# "my documents/processing" on windows and "documents/processing" on osx,
# set this to another path that will be used by default
#sketchbook.path=sketchbook
sketchbook.path.fallback=sketchbook
# if you don't want settings to go into "application data" on windows
# and "library" on macosx, set this to the alternate location.
#settings.path=data
settings.path.fallback=data
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
@@ -159,11 +190,8 @@ sketchbook.prompt = false
# true if empty sketches should be removed automatically
sketchbook.auto_clean = true
sketchbook.name.default = sketchbook
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# note that this path should use forward slashes (like unix)
# instead of \ on windows or : on windows or whatever else
#sketchbook.path =
history.recording = true
+1
View File
@@ -4029,6 +4029,7 @@ public class PApplet extends Applet
}
try {
Thread.sleep(250);
//Thread.sleep(100); // kick up latency for 0075?
} catch (InterruptedException e) { }
}
}
+4
View File
@@ -32,6 +32,10 @@ _ or maybe need to get better at size() inside of draw() ?
_ make this consistent with the regular PApplet
_ otherwise things are going to be weird/difficult for debugging
_ still threading issues with running opengl
_ first run hangs until quit
_ though doesn't seem to replicate when p5 is restarted
_ fix non-bound textures from mangling everything else
_ fix enable/disable textures for some objects
_ fix endian ordering issues so that things work properly
+52 -41
View File
@@ -17,42 +17,60 @@ X is PdeEditorHeader one pixel too tall
X move the tabs over just slightly
X resize box intrudes on the scroller for the console area
X need to set grow boxes intruding to false
X 1.3 version (deprecated): -Dcom.apple.mrj.application.growbox.intrudes=false
X 1.4 version: -Dapple.awt.showGrowBox=false
X 1.3 version (deprecated):
X -Dcom.apple.mrj.application.growbox.intrudes=false
X 1.4 version (much nicer): -Dapple.awt.showGrowBox=false
X add mkdmg script to macosx build process
X could significantly speed things up
X put 'play' on a SwingWorker thread
_ test this on a pc to see how it goes, especially with opengl
sketchbook/prefs location
_ read from registry key to get the proper name for these folders
_ also find some way to do this on the mac
_ on non-english windows (or at the broad) these will be named differently
_ http://support.microsoft.com/?kbid=221837&sd=RMVP
_ or is there a proper way to do this with java params?
_ move to ~/Application Data/Processing for windows
_ and ~/Library/Processing for macosx
_ and ~/.processing for linux
_ if it can't write prefs here, try creating a subfolder inside p5
_ and if that fails, then tell the user that they suck
_ prompt for sketchbook location on linux
_ or on mac/pc if it can't write anywhere else
_ creating sketchbook / lab situations
_ test to see if it's possible to write to "My Documents"
_ if not, should bring up a prompt asking where to put sketchbook
_ also put something in lib/preferences.txt for default location
_ this way a course admin can change the default location
_ need to check if volume is read-only, notify and quit if it is
_ people are trying to run off the disk image
_ actually that should be fine..
_ but make sure the prefs location can be written
_ need to pay attention to when running from read-only drive
_ reported by brandenberg
_ "p5 will launch from the disk image, but will
_ not draw the sketch name bar doesn't appear"
_ includes preferences.txt option to write to p5 folder first
_ this can be altered by instructors and re-packaged
X read from registry key to get the proper name for these folders
X also find some way to do this on the mac
X on non-english windows (or at the broad) these will be named differently
X http://support.microsoft.com/?kbid=221837&sd=RMVP
X or is there a proper way to do this with java params?
X move to ~/Application Data/Processing for windows
X and ~/Library/Processing for macosx
X and ~/.processing for linux
X if it can't write prefs here, try creating a subfolder inside p5
X and if that fails, then tell the user that they suck
X prompt for sketchbook location on linux
X or on mac/pc if it can't write anywhere else
X creating sketchbook / lab situations
X test to see if it's possible to write to "My Documents"
X if not, should bring up a prompt asking where to put sketchbook
X also put something in lib/preferences.txt for default location
X this way a course admin can change the default location
o need to check if volume is read-only, notify and quit if it is
o people are trying to run off the disk image
o actually that should be fine..
o but make sure the prefs location can be written
o need to pay attention to when running from read-only drive
o reported by brandenberg
o "p5 will launch from the disk image, but will
o not draw the sketch name bar doesn't appear"
X include preferences.txt option to write to p5 folder first
X this can be altered by instructors and re-packaged
X fixed a couple bugs causing the jnilib stuff to crash
X put 'play' on a SwingWorker thread
X test this on a pc to see how it goes, especially with opengl
X doesn't seem to help anything
X PdeRuntime -> SystemOutSiphon, removed MIN_PRIORITY setting
o hack to not use console on the code folder
o no errors will propogate, but it should run fine
X lib/build should not be a subfolder of p5
X p5 environment installed to /Applications on lab machines
X instead use a temp folder
X maybe when running on lab machines in that case, always java mode?
X or is it possible to add to java.class.path while app is running?
X have to use a special class loader
X new class loader for single files
X if more than one class defined, forces it to run externally
X (basically any time it sees "class" in the code..
X may be subject to errors, but errs on side of just running ext)
X runs out of processing data folder
_ bring back "rename" ?
@@ -60,7 +78,8 @@ _ may need a progress bar for "save as"
_ or just the file copy function in general
_ since it may take a long time (i.e. 1000s of screen grabs)
_ opening up sketch folder may be extremely slow
_ scanning sketchbook folder may be extremely slow
_ not sure why this would be the case
_ preproc: making all functions public that have no specifier
_ this will make draw() etc all much easier
@@ -71,14 +90,6 @@ _ basic sample audio playback needed for p5
_ what's up with int() -> toInt() conversion?
_ hack to not use console on the code folder
_ no errors will propogate, but it should run fine
_ lib/build should not be a subfolder of p5
_ p5 environment installed to /Applications on lab machines
_ instead use a temp folder
_ maybe when running on lab machines in that case, always java mode?
//