costin 01/03/09 15:47:41
Modified: src/share/org/apache/tomcat/core BaseInterceptor.java
src/share/org/apache/tomcat/modules/config
LoaderInterceptor11.java
src/share/org/apache/tomcat/modules/mappers
ReloadInterceptor.java
src/share/org/apache/tomcat/modules/session
SimpleSessionStore.java
Log:
Fixes in reloading.
- added a comment about "oldLoader" note
- refactored LoaderInterceptor - it no longer depends ( or care ) about
reloading details
- ReloadIntereptor is taking care of hooking in the class loader, so
it knows about automatic dependencies.
- if a change is detected, re-do the contextMap ( this fixes 503 when
the app is reloaded )
Revision Changes Path
1.45 +8 -0
jakarta-tomcat/src/share/org/apache/tomcat/core/BaseInterceptor.java
Index: BaseInterceptor.java
===================================================================
RCS file:
/home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/core/BaseInterceptor.java,v
retrieving revision 1.44
retrieving revision 1.45
diff -u -r1.44 -r1.45
--- BaseInterceptor.java 2001/03/08 07:23:01 1.44
+++ BaseInterceptor.java 2001/03/09 23:47:39 1.45
@@ -443,6 +443,14 @@
/** Reload notification - called whenever a reload is done.
This can be used to serialize sessions, log the event,
remove any resource that was class-loader dependent.
+
+ Note. The current implementation uses a note "oldLoader"
+ that will keep a reference to the previous class loader
+ during this hook. It will be set by the module that creates
+ the loaders, and should be destroyed when the hook is done.
+ This can also be implemented using a get/setOldClassLoader
+ in Context, but so far this is used in only 2 modules, adding
+ new API is not needed.
*/
public void reload( Request req, Context ctx)
throws TomcatException
1.9 +48 -67
jakarta-tomcat/src/share/org/apache/tomcat/modules/config/LoaderInterceptor11.java
Index: LoaderInterceptor11.java
===================================================================
RCS file:
/home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/modules/config/LoaderInterceptor11.java,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- LoaderInterceptor11.java 2001/03/07 23:51:08 1.8
+++ LoaderInterceptor11.java 2001/03/09 23:47:39 1.9
@@ -72,8 +72,10 @@
* Set class loader based on WEB-INF/classes, lib.
* Compatible with JDK1.1, but takes advantage of URLClassLoader if
* java2 is detected.
- *
*
+ * Note. LoaderInterceptor must be the first in the reload and contextInit
+ * chains.
+ *
* @author [EMAIL PROTECTED]
*/
public class LoaderInterceptor11 extends BaseInterceptor {
@@ -95,7 +97,10 @@
public void setUseNoParent( boolean b ) {
useNoParent=b;
}
-
+
+ /** Add all WEB-INF/classes and WEB-INF/lib to the context
+ * path
+ */
public void addContext( ContextManager cm, Context context)
throws TomcatException
{
@@ -133,98 +138,74 @@
} catch( MalformedURLException ex ) {
}
}
-
- // Add servlet.jar and jasper.jar
}
-
+
+ /** Construct a class loader to be used with the context
+ */
public void contextInit( Context context)
throws TomcatException
{
if( debug>0 ) log( "Init context " + context.getPath());
ContextManager cm = context.getContextManager();
- URL classP[]=context.getClassPath();
- if( debug>5 ) {
- log(" Context classpath URLs:");
- for (int i = 0; i < classP.length; i++)
- log(" " + classP[i].toString() );
- }
-
- DependManager dm=(DependManager)context.getContainer().
- getNote("DependManager");
- if( dm==null ) {
- // No depend manager - that means no ReloadInterceptor.
- }
-
- ClassLoader parent=null;
- if( useAL && !context.isTrusted() )
- parent=cm.getParentLoader();
- else if( useNoParent )
- parent=null;
- else
- parent=this.getClass().getClassLoader();
-
- ClassLoader loader=jdk11Compat.newClassLoaderInstance( classP, parent);
- if( debug > 0 )
- log("Loader " + loader.getClass().getName() + " " + parent);
-
- if( dm != null ) {
- // If depend manager is present, create a wrapper loader
- // that will add dependencies for reloading ( using depentManager)
- loader=new DependClassLoader( dm, loader);
- }
- // If another reloading scheme is implemented, you'll
- // have to plug it in here.
-
+ ClassLoader loader=constructLoader( context );
context.setClassLoader( loader );
// support for jasper and other applications
context.setAttribute( "org.apache.tomcat.classloader",loader);
}
+ /** Construct another class loader, when the context is reloaded.
+ */
public void reload( Request req, Context context) throws TomcatException {
log( "Reload event " + context.getPath() );
+
+ // construct a new loader
+ ClassLoader oldLoader=context.getClassLoader();
+
+ // will be used by reloader or other modules to try to
+ // migrate the data.
+ context.getContainer().setNote( "oldLoader", oldLoader);
- DependManager dm=(DependManager)context.getContainer().
- getNote("DependManager");
+ ClassLoader loader=constructLoader( context );
+ context.setClassLoader( loader );
+ context.setAttribute( "org.apache.tomcat.classloader", loader);
+ }
- ContextManager cm = context.getContextManager();
- URL urls[]=context.getClassPath();
+ /** Override this method to provide an alternate loader
+ * (or create a new interceptor )
+ */
+ protected ClassLoader constructLoader(Context context )
+ throws TomcatException
+ {
+ URL classP[]=context.getClassPath();
if( debug>5 ) {
log(" Context classpath URLs:");
- for (int i = 0; i < urls.length; i++)
- log(" " + urls[i].toString() );
+ for (int i = 0; i < classP.length; i++)
+ log(" " + classP[i].toString() );
}
- if( dm!=null ) {
- // we are using a util.depend for reloading
- dm.reset();
- }
- // construct a new loader
- ClassLoader oldLoader=context.getClassLoader();
- int oldLoaderNote=cm.getNoteId( ContextManager.CONTAINER_NOTE,
- "oldLoader");
- context.getContainer().setNote( oldLoaderNote, oldLoader);
-
ClassLoader parent=null;
- if( useAL )
+ if( useAL && !context.isTrusted() ) {
+ if( debug > 0 ) log( "Using webapp loader " + context.isTrusted());
parent=cm.getParentLoader();
- else if( useNoParent )
+ } else if( useNoParent ) {
+ if( debug > 0 ) log( "Using no parent loader ");
parent=null;
- else
+ } else {
+ if( debug > 0 ) log( "Using container loader ");
parent=this.getClass().getClassLoader();
-
- // Construct a class loader. Use URLClassLoader if Java2,
- // replacement ( SimpleClassLoader ) if not
- // SimpleClassLoader loader=new SimpleClassLoader(urls, parent);
- ClassLoader loader=jdk11Compat.newClassLoaderInstance( urls, parent);
+ }
+
+ ClassLoader loader=jdk11Compat.newClassLoaderInstance( classP, parent);
+ if( debug > 0 )
+ log("Loader " + loader.getClass().getName() + " " + parent);
- if( dm!=null )
- loader=new DependClassLoader( dm, loader);
- context.setClassLoader( loader );
- context.setAttribute( "org.apache.tomcat.classloader", loader);
+ // If another reloading scheme is implemented, you'll
+ // have to plug it in here.
+ return loader;
}
-
+
// --------------------
static final Jdk11Compat jdk11Compat=Jdk11Compat.getJdkCompat();
1.5 +41 -5
jakarta-tomcat/src/share/org/apache/tomcat/modules/mappers/ReloadInterceptor.java
Index: ReloadInterceptor.java
===================================================================
RCS file:
/home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/modules/mappers/ReloadInterceptor.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- ReloadInterceptor.java 2001/03/07 23:52:48 1.4
+++ ReloadInterceptor.java 2001/03/09 23:47:40 1.5
@@ -72,6 +72,7 @@
* will determine if the context needs reload.
*
* This interceptor supports multiple forms of reloading.
+ * Configuration. Must be set after LoaderInterceptor
*/
public class ReloadInterceptor extends BaseInterceptor
{
@@ -126,8 +127,33 @@
dep.setLastModified( inf_xml.lastModified() );
dm.addDependency( dep );
}
+
+ // Use a DependClassLoader to autmatically record class loader
+ // deps
+ loaderHook(dm, context);
}
+
+ public void reload( Request req, Context context) throws TomcatException {
+ DependManager dm=(DependManager)context.getContainer().
+ getNote("DependManager");
+
+ if( dm!=null ) {
+ // we are using a util.depend for reloading
+ dm.reset();
+ }
+ loaderHook(dm, context);
+ }
+
+
+ protected void loaderHook( DependManager dm, Context context ) {
+ // ReloadInterceptor must be configured _after_ LoaderInterceptor
+ ClassLoader cl=context.getClassLoader();
+ ClassLoader loader=new DependClassLoader( dm, cl);
+ context.setClassLoader(loader);
+ context.setAttribute( "org.apache.tomcat.classloader", loader);
+ }
+
public int contextMap( Request request ) {
Context ctx=request.getContext();
@@ -136,6 +162,10 @@
// XXX This interceptor will be added per/context.
if( ! ctx.getReloadable() ) return 0;
+ // We are remapping ?
+ if( request.getAttribute("tomcat.ReloadInterceptor")!=null)
+ return DECLINED;
+
DependManager dm=(DependManager)ctx.getContainer().
getNote(dependManagerNote);
if( ! dm.shouldReload() ) return 0;
@@ -171,8 +201,16 @@
ctx1.init();
- // XXX Make sure ctx is destroyed - we may have
- // undetected leaks
+ // remap the request
+ request.setAttribute("tomcat.ReloadInterceptor", this);
+ BaseInterceptor ri[]=
+ cm.getContainer().getInterceptors(Container.H_contextMap);
+
+ for( int i=0; i< ri.length; i++ ) {
+ if( ri[i]==this ) break;
+ int status=ri[i].contextMap( request );
+ if( status!=0 ) return status;
+ }
} else {
// This is the old ( buggy) behavior
@@ -204,9 +242,7 @@
BaseInterceptor cI[]=ctx.getContainer().getInterceptors();
for( int i=0; i< cI.length; i++ ) {
cI[i].reload( request, ctx );
- int oldLoaderNote=cm.getNoteId
- ( ContextManager.CONTAINER_NOTE, "oldLoader");
- ctx.getContainer().setNote( oldLoaderNote, null);
+ ctx.getContainer().setNote( "oldLoader", null);
}
}
} catch( TomcatException ex) {
1.12 +1 -3
jakarta-tomcat/src/share/org/apache/tomcat/modules/session/SimpleSessionStore.java
Index: SimpleSessionStore.java
===================================================================
RCS file:
/home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/modules/session/SimpleSessionStore.java,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- SimpleSessionStore.java 2001/03/02 04:49:31 1.11
+++ SimpleSessionStore.java 2001/03/09 23:47:40 1.12
@@ -156,10 +156,8 @@
}
session.setState( ServerSession.STATE_SUSPEND );
- int oldLoaderNote=cm.getNoteId( ContextManager.CONTAINER_NOTE,
- "oldLoader");
ClassLoader oldLoader=(ClassLoader)ctx.getContainer().
- getNote(oldLoaderNote);
+ getNote("oldLoader");
Hashtable newSession=new Hashtable();
Enumeration e = session.getAttributeNames();
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, email: [EMAIL PROTECTED]