📄 webapploader.java
字号:
}
} else {
closeJARs(false);
}
}
/**
* Return the set of repositories defined for this class loader.
* If none are defined, a zero-length array is returned.
* For security reason, returns a clone of the Array (since
* String are immutable).
*/
public String[] findRepositories() {
return ((String[])repositories.clone());
}
public String[] getRepositories() {
return ((String[])repositories.clone());
}
/** Extra repositories for this loader
*/
public String getRepositoriesString() {
StringBuffer sb=new StringBuffer();
for( int i=0; i<repositories.length ; i++ ) {
sb.append( repositories[i]).append(":");
}
return sb.toString();
}
public String[] getLoaderRepositories() {
if( loaderRepositories==null ) return null;
String res[]=new String[ loaderRepositories.size()];
loaderRepositories.toArray(res);
return res;
}
public String getLoaderRepositoriesString() {
String repositories[]=getLoaderRepositories();
StringBuffer sb=new StringBuffer();
for( int i=0; i<repositories.length ; i++ ) {
sb.append( repositories[i]).append(":");
}
return sb.toString();
}
/**
* Classpath, as set in org.apache.catalina.jsp_classpath context
* property
*
* @return The classpath
*/
public String getClasspath() {
return classpath;
}
/**
* Has the internal repository associated with this Loader been modified,
* such that the loaded classes should be reloaded?
*/
public boolean modified() {
return (classLoader.modified());
}
/**
* Used to periodically signal to the classloader to release JAR resources.
*/
public void closeJARs(boolean force) {
if (classLoader !=null){
classLoader.closeJARs(force);
}
}
/**
* Remove a property change listener from this component.
*
* @param listener The listener to remove
*/
public void removePropertyChangeListener(PropertyChangeListener listener) {
support.removePropertyChangeListener(listener);
}
/**
* Return a String representation of this component.
*/
public String toString() {
StringBuffer sb = new StringBuffer("WebappLoader[");
if (container != null)
sb.append(container.getName());
sb.append("]");
return (sb.toString());
}
// ------------------------------------------------------ Lifecycle Methods
/**
* Add a lifecycle event listener to this component.
*
* @param listener The listener to add
*/
public void addLifecycleListener(LifecycleListener listener) {
lifecycle.addLifecycleListener(listener);
}
/**
* Get the lifecycle listeners associated with this lifecycle. If this
* Lifecycle has no listeners registered, a zero-length array is returned.
*/
public LifecycleListener[] findLifecycleListeners() {
return lifecycle.findLifecycleListeners();
}
/**
* Remove a lifecycle event listener from this component.
*
* @param listener The listener to remove
*/
public void removeLifecycleListener(LifecycleListener listener) {
lifecycle.removeLifecycleListener(listener);
}
private boolean initialized=false;
public void init() {
initialized=true;
if( oname==null ) {
// not registered yet - standalone or API
if( container instanceof StandardContext) {
// Register ourself. The container must be a webapp
try {
StandardContext ctx=(StandardContext)container;
Engine eng=(Engine)ctx.getParent().getParent();
String path = ctx.getPath();
if (path.equals("")) {
path = "/";
}
oname=new ObjectName(ctx.getEngineName() + ":type=Loader,path=" +
path + ",host=" + ctx.getParent().getName());
Registry.getRegistry(null, null).registerComponent(this, oname, null);
controller=oname;
} catch (Exception e) {
log.error("Error registering loader", e );
}
}
}
if( container == null ) {
// JMX created the loader
// TODO
}
}
public void destroy() {
if( controller==oname ) {
// Self-registration, undo it
Registry.getRegistry(null, null).unregisterComponent(oname);
oname = null;
}
initialized = false;
}
/**
* Start this component, initializing our associated class loader.
*
* @exception LifecycleException if a lifecycle error occurs
*/
public void start() throws LifecycleException {
// Validate and update our current component state
if( ! initialized ) init();
if (started)
throw new LifecycleException
(sm.getString("webappLoader.alreadyStarted"));
if (log.isDebugEnabled())
log.debug(sm.getString("webappLoader.starting"));
lifecycle.fireLifecycleEvent(START_EVENT, null);
started = true;
if (container.getResources() == null) {
log.info("No resources for " + container);
return;
}
// Register a stream handler factory for the JNDI protocol
URLStreamHandlerFactory streamHandlerFactory =
new DirContextURLStreamHandlerFactory();
if (first) {
first = false;
try {
URL.setURLStreamHandlerFactory(streamHandlerFactory);
} catch (Exception e) {
// Log and continue anyway, this is not critical
log.error("Error registering jndi stream handler", e);
} catch (Throwable t) {
// This is likely a dual registration
log.info("Dual registration of jndi stream handler: "
+ t.getMessage());
}
}
// Construct a class loader based on our current repositories list
try {
classLoader = createClassLoader();
classLoader.setResources(container.getResources());
classLoader.setDelegate(this.delegate);
if (container instanceof StandardContext)
classLoader.setAntiJARLocking(((StandardContext) container).getAntiJARLocking());
for (int i = 0; i < repositories.length; i++) {
classLoader.addRepository(repositories[i]);
}
// Configure our repositories
setRepositories();
setClassPath();
setPermissions();
if (classLoader instanceof Lifecycle)
((Lifecycle) classLoader).start();
// Binding the Webapp class loader to the directory context
DirContextURLStreamHandler.bind
((ClassLoader) classLoader, this.container.getResources());
StandardContext ctx=(StandardContext)container;
Engine eng=(Engine)ctx.getParent().getParent();
String path = ctx.getPath();
if (path.equals("")) {
path = "/";
}
ObjectName cloname = new ObjectName
(ctx.getEngineName() + ":type=WebappClassLoader,path="
+ path + ",host=" + ctx.getParent().getName());
Registry.getRegistry(null, null)
.registerComponent(classLoader, cloname, null);
} catch (Throwable t) {
log.error( "LifecycleException ", t );
throw new LifecycleException("start: ", t);
}
}
/**
* Stop this component, finalizing our associated class loader.
*
* @exception LifecycleException if a lifecycle error occurs
*/
public void stop() throws LifecycleException {
// Validate and update our current component state
if (!started)
throw new LifecycleException
(sm.getString("webappLoader.notStarted"));
if (log.isDebugEnabled())
log.debug(sm.getString("webappLoader.stopping"));
lifecycle.fireLifecycleEvent(STOP_EVENT, null);
started = false;
// Remove context attributes as appropriate
if (container instanceof Context) {
ServletContext servletContext =
((Context) container).getServletContext();
servletContext.removeAttribute(Globals.CLASS_PATH_ATTR);
}
// Throw away our current class loader
if (classLoader instanceof Lifecycle)
((Lifecycle) classLoader).stop();
DirContextURLStreamHandler.unbind((ClassLoader) classLoader);
try {
StandardContext ctx=(StandardContext)container;
Engine eng=(Engine)ctx.getParent().getParent();
String path = ctx.getPath();
if (path.equals("")) {
path = "/";
}
ObjectName cloname = new ObjectName
(ctx.getEngineName() + ":type=WebappClassLoader,path="
+ path + ",host=" + ctx.getParent().getName());
Registry.getRegistry(null, null).unregisterComponent(cloname);
} catch (Throwable t) {
log.error( "LifecycleException ", t );
}
classLoader = null;
destroy();
}
// ----------------------------------------- PropertyChangeListener Methods
/**
* Process property change events from our associated Context.
*
* @param event The property change event that has occurred
*/
public void propertyChange(PropertyChangeEvent event) {
// Validate the source of this event
if (!(event.getSource() instanceof Context))
return;
Context context = (Context) event.getSource();
// Process a relevant property change
if (event.getPropertyName().equals("reloadable")) {
try {
setReloadable
( ((Boolean) event.getNewValue()).booleanValue() );
} catch (NumberFormatException e) {
log.error(sm.getString("webappLoader.reloadable",
event.getNewValue().toString()));
}
}
}
// ------------------------------------------------------- Private Methods
/**
* Create associated classLoader.
*/
private WebappClassLoader createClassLoader()
throws Exception {
Class clazz = Class.forName(loaderClass);
WebappClassLoader classLoader = null;
if (parentClassLoader == null) {
parentClassLoader = container.getParentClassLoader();
}
Class[] argTypes = { ClassLoader.class };
Object[] args = { parentClassLoader };
Constructor constr = clazz.getConstructor(argTypes);
classLoader = (WebappClassLoader) constr.newInstance(args);
return classLoader;
}
/**
* Configure associated class loader permissions.
*/
private void setPermissions() {
if (!Globals.IS_SECURITY_ENABLED)
return;
if (!(container instanceof Context))
return;
// Tell the class loader the root of the context
ServletContext servletContext =
((Context) container).getServletContext();
// Assigning permissions for the work directory
File workDir =
(File) servletContext.getAttribute(Globals.WORK_DIR_ATTR);
if (workDir != null) {
try {
String workDirPath = workDir.getCanonicalPath();
classLoader.addPermission
(new FilePermission(workDirPath, "read,write"));
classLoader.addPermission
(new FilePermission(workDirPath + File.separator + "-",
"read,write,delete"));
} catch (IOException e) {
// Ignore
}
}
try {
URL rootURL = servletContext.getResource("/");
classLoader.addPermission(rootURL);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -