* Run Application.init() in a fresh thread to shield it against class loaders
and rhino contexts that may be associated with the calling thread. Fixes bug 613 <http://helma.org/bugs/show_bug.cgi?id=613>
This commit is contained in:
parent
007f61b324
commit
30eb6663bc
1 changed files with 149 additions and 110 deletions
|
@ -303,9 +303,9 @@ public final class Application implements Runnable {
|
|||
/**
|
||||
* Get the application ready to run, initializing the evaluators and type manager.
|
||||
*/
|
||||
public synchronized void init()
|
||||
throws DatabaseException, IllegalAccessException,
|
||||
InstantiationException, ClassNotFoundException {
|
||||
public void init()
|
||||
throws DatabaseException, IllegalAccessException, InstantiationException,
|
||||
ClassNotFoundException, InterruptedException {
|
||||
init(null);
|
||||
}
|
||||
|
||||
|
@ -314,14 +314,54 @@ public final class Application implements Runnable {
|
|||
*
|
||||
* @param ignoreDirs comma separated list of directory names to ignore
|
||||
*/
|
||||
public synchronized void init(String ignoreDirs)
|
||||
public void init(final String ignoreDirs)
|
||||
throws DatabaseException, IllegalAccessException, InstantiationException,
|
||||
ClassNotFoundException, InterruptedException {
|
||||
|
||||
Initializer i = new Initializer(ignoreDirs);
|
||||
i.start();
|
||||
i.join();
|
||||
if (i.exception != null) {
|
||||
if (i.exception instanceof DatabaseException)
|
||||
throw (DatabaseException) i.exception;
|
||||
if (i.exception instanceof IllegalAccessException)
|
||||
throw (IllegalAccessException) i.exception;
|
||||
if (i.exception instanceof InstantiationException)
|
||||
throw (InstantiationException) i.exception;
|
||||
if (i.exception instanceof ClassNotFoundException)
|
||||
throw (ClassNotFoundException) i.exception;
|
||||
throw new RuntimeException(i.exception);
|
||||
}
|
||||
}
|
||||
|
||||
// We need to call initialize in a fresh thread because the calling thread could
|
||||
// already be associated with a rhino context, for example when starting from the
|
||||
// manage application.
|
||||
class Initializer extends Thread {
|
||||
Exception exception = null;
|
||||
String ignoreDirs;
|
||||
|
||||
Initializer(String dirs) {
|
||||
super("INIT-" + name);
|
||||
ignoreDirs = dirs;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
try {
|
||||
synchronized (Application.this) {
|
||||
initInternal();
|
||||
}
|
||||
} catch (Exception x) {
|
||||
exception = x;
|
||||
}
|
||||
}
|
||||
|
||||
private void initInternal()
|
||||
throws DatabaseException, IllegalAccessException,
|
||||
InstantiationException, ClassNotFoundException {
|
||||
|
||||
running = true;
|
||||
|
||||
// create and init type mananger
|
||||
typemgr = new TypeManager(this, ignoreDirs);
|
||||
typemgr = new TypeManager(Application.this, ignoreDirs);
|
||||
// set the context classloader. Note that this must be done before
|
||||
// using the logging framework so that a new LogFactory gets created
|
||||
// for this app.
|
||||
|
@ -339,7 +379,7 @@ public final class Application implements Runnable {
|
|||
HelmaExtension ext = (HelmaExtension) extensions.get(i);
|
||||
|
||||
try {
|
||||
ext.applicationStarted(this);
|
||||
ext.applicationStarted(Application.this);
|
||||
} catch (ConfigurationException e) {
|
||||
logEvent("couldn't init extension " + ext.getName() + ": " +
|
||||
e.toString());
|
||||
|
@ -365,7 +405,7 @@ public final class Application implements Runnable {
|
|||
}
|
||||
|
||||
for (int i = 0; i < minThreads; i++) {
|
||||
RequestEvaluator ev = new RequestEvaluator(this);
|
||||
RequestEvaluator ev = new RequestEvaluator(Application.this);
|
||||
|
||||
if (i == 0) {
|
||||
ev.initScriptingEngine();
|
||||
|
@ -379,7 +419,7 @@ public final class Application implements Runnable {
|
|||
customCronJobs = new Hashtable();
|
||||
|
||||
// create the skin manager
|
||||
skinmgr = new SkinManager(this);
|
||||
skinmgr = new SkinManager(Application.this);
|
||||
|
||||
// read in root id, root prototype, user prototype
|
||||
rootId = props.getProperty("rootid", "0");
|
||||
|
@ -404,11 +444,11 @@ public final class Application implements Runnable {
|
|||
|
||||
p.put("_children", "collection(" + userPrototype + ")");
|
||||
p.put("_children.accessname", usernameField);
|
||||
userRootMapping = new DbMapping(this, "__userroot__", p);
|
||||
userRootMapping = new DbMapping(Application.this, "__userroot__", p);
|
||||
userRootMapping.update();
|
||||
|
||||
// create the node manager
|
||||
nmgr = new NodeManager(this);
|
||||
nmgr = new NodeManager(Application.this);
|
||||
nmgr.init(dbDir.getAbsoluteFile(), props);
|
||||
|
||||
// create and init session manager
|
||||
|
@ -416,7 +456,7 @@ public final class Application implements Runnable {
|
|||
"helma.framework.core.SessionManager");
|
||||
sessionMgr = (SessionManager) Class.forName(sessionMgrImpl).newInstance();
|
||||
logEvent("Using session manager class " + sessionMgrImpl);
|
||||
sessionMgr.init(this);
|
||||
sessionMgr.init(Application.this);
|
||||
|
||||
// read the sessions if wanted
|
||||
if ("true".equalsIgnoreCase(getProperty("persistentSessions"))) {
|
||||
|
@ -428,10 +468,9 @@ public final class Application implements Runnable {
|
|||
releaseEvaluator(ev);
|
||||
}
|
||||
}
|
||||
|
||||
// reset the classloader to the parent/system/server classloader.
|
||||
Thread.currentThread().setContextClassLoader(typemgr.getClassLoader().getParent());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create and start scheduler and cleanup thread
|
||||
|
|
Loading…
Add table
Reference in a new issue