You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by da...@apache.org on 2003/01/08 13:31:05 UTC
cvs commit: jakarta-james/src/java/org/apache/james/transport JamesSpoolManager.java MailetLoader.java MatchLoader.java
danny 2003/01/08 04:31:05
Modified: src/java/org/apache/james/transport JamesSpoolManager.java
MailetLoader.java MatchLoader.java
Log:
Mailet Classloader changes. First efforts..
Mailet and matcher classes and their dependancies can now be loaded
from ~/apps/james/SAR-INF/classes
and jars in ~/apps/james/SAR-INF/lib/
Revision Changes Path
1.24 +92 -143 jakarta-james/src/java/org/apache/james/transport/JamesSpoolManager.java
Index: JamesSpoolManager.java
===================================================================
RCS file: /home/cvs/jakarta-james/src/java/org/apache/james/transport/JamesSpoolManager.java,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -r1.23 -r1.24
--- JamesSpoolManager.java 7 Jan 2003 11:57:25 -0000 1.23
+++ JamesSpoolManager.java 8 Jan 2003 12:31:05 -0000 1.24
@@ -6,12 +6,9 @@
* the LICENSE file.
*/
package org.apache.james.transport;
-
import java.util.HashMap;
import java.util.Iterator;
-
import javax.mail.MessagingException;
-
import org.apache.avalon.cornerstone.services.threads.ThreadManager;
import org.apache.avalon.excalibur.thread.ThreadPool;
import org.apache.avalon.framework.activity.Disposable;
@@ -24,6 +21,9 @@
import org.apache.avalon.framework.configuration.Configurable;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.context.Context;
+import org.apache.avalon.framework.context.ContextException;
+import org.apache.avalon.framework.context.Contextualizable;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.james.core.MailImpl;
import org.apache.james.services.MailStore;
@@ -33,7 +33,6 @@
import org.apache.mailet.MailetException;
import org.apache.mailet.Matcher;
import org.apache.mailet.SpoolRepository;
-
/**
* Manages the mail spool. This class is responsible for retrieving
* messages from the spool, directing messages to the appropriate
@@ -47,57 +46,45 @@
*/
public class JamesSpoolManager
extends AbstractLogEnabled
- implements Composable, Configurable, Initializable,
- Runnable, Disposable, Component {
-
+ implements Composable, Configurable, Initializable, Runnable, Disposable, Component, Contextualizable {
+ private Context context;
/**
* Whether 'deep debugging' is turned on.
*/
private final static boolean DEEP_DEBUG = false;
-
/**
* System component manager
*/
private DefaultComponentManager compMgr;
-
/**
* The configuration object used by this spool manager.
*/
private Configuration conf;
-
private SpoolRepository spool;
-
private MailetContext mailetContext;
-
/**
* The map of processor names to processors
*/
private HashMap processors;
-
/**
* The number of threads used to move mail through the spool.
*/
private int numThreads;
-
/**
* The ThreadPool containing the spool threads.
*/
private ThreadPool workerPool;
-
/**
* The ThreadManager from which the thread pool is obtained.
*/
private ThreadManager threadManager;
-
/**
* @see org.apache.avalon.framework.component.Composable#compose(ComponentManager)
*/
- public void compose(ComponentManager comp)
- throws ComponentException {
- threadManager = (ThreadManager)comp.lookup( ThreadManager.ROLE );
+ public void compose(ComponentManager comp) throws ComponentException {
+ threadManager = (ThreadManager) comp.lookup(ThreadManager.ROLE);
compMgr = new DefaultComponentManager(comp);
}
-
/**
* @see org.apache.avalon.framework.configuration.Configurable#configure(Configuration)
*/
@@ -105,55 +92,48 @@
this.conf = conf;
numThreads = conf.getChild("threads").getValueAsInteger(1);
}
-
/**
* @see org.apache.avalon.framework.activity.Initializable#initialize()
*/
public void initialize() throws Exception {
-
getLogger().info("JamesSpoolManager init...");
- workerPool = threadManager.getThreadPool( "default" );
- MailStore mailstore
- = (MailStore) compMgr.lookup("org.apache.james.services.MailStore");
+ workerPool = threadManager.getThreadPool("default");
+ MailStore mailstore = (MailStore) compMgr.lookup("org.apache.james.services.MailStore");
spool = mailstore.getInboundSpool();
- if (null == spool)
- {
- String exceptionMessage = "The mailstore's inbound spool is null. The mailstore is misconfigured";
+ if (null == spool) {
+ String exceptionMessage =
+ "The mailstore's inbound spool is null. The mailstore is misconfigured";
if (getLogger().isErrorEnabled()) {
- getLogger().error( exceptionMessage );
+ getLogger().error(exceptionMessage);
}
throw new ConfigurationException(exceptionMessage);
}
if ((DEEP_DEBUG) && (getLogger().isDebugEnabled())) {
getLogger().debug("Got spool");
}
-
- mailetContext
- = (MailetContext) compMgr.lookup("org.apache.mailet.MailetContext");
+ mailetContext = (MailetContext) compMgr.lookup("org.apache.mailet.MailetContext");
MailetLoader mailetLoader = new MailetLoader();
MatchLoader matchLoader = new MatchLoader();
try {
+ mailetLoader.setLogger(getLogger());
+ matchLoader.setLogger(getLogger());
+ mailetLoader.contextualize(context);
+ matchLoader.contextualize(context);
mailetLoader.configure(conf.getChild("mailetpackages"));
matchLoader.configure(conf.getChild("matcherpackages"));
compMgr.put(Resources.MAILET_LOADER, mailetLoader);
compMgr.put(Resources.MATCH_LOADER, matchLoader);
} catch (ConfigurationException ce) {
- final String message =
- "Unable to configure mailet/matcher Loaders: "
- + ce.getMessage();
-
+ final String message = "Unable to configure mailet/matcher Loaders: " + ce.getMessage();
if (getLogger().isErrorEnabled()) {
- getLogger().error( message, ce );
+ getLogger().error(message, ce);
}
- throw new RuntimeException( message );
+ throw new RuntimeException(message);
}
-
//A processor is a Collection of
processors = new HashMap();
-
- final Configuration[] processorConfs = conf.getChildren( "processor" );
- for ( int i = 0; i < processorConfs.length; i++ )
- {
+ final Configuration[] processorConfs = conf.getChildren("processor");
+ for (int i = 0; i < processorConfs.length; i++) {
Configuration processorConf = processorConfs[i];
String processorName = processorConf.getAttribute("name");
try {
@@ -162,51 +142,41 @@
processor.setSpool(spool);
processor.initialize();
processors.put(processorName, processor);
-
// If this is the root processor, add the PostmasterAlias
// mailet silently to the top
if (processorName.equals("root")) {
- Matcher matcher = matchLoader.getMatcher("All",
- mailetContext);
- Mailet mailet = mailetLoader.getMailet("PostmasterAlias",
- mailetContext, null);
+ Matcher matcher = matchLoader.getMatcher("All", mailetContext);
+ Mailet mailet = mailetLoader.getMailet("PostmasterAlias", mailetContext, null);
processor.add(matcher, mailet);
}
-
- final Configuration[] mailetConfs
- = processorConf.getChildren( "mailet" );
+ final Configuration[] mailetConfs = processorConf.getChildren("mailet");
// Loop through the mailet configuration, load
// all of the matcher and mailets, and add
// them to the processor.
- for ( int j = 0; j < mailetConfs.length; j++ )
- {
+ for (int j = 0; j < mailetConfs.length; j++) {
Configuration c = mailetConfs[j];
String mailetClassName = c.getAttribute("class");
String matcherName = c.getAttribute("match");
Mailet mailet = null;
Matcher matcher = null;
try {
- matcher = matchLoader.getMatcher(matcherName,
- mailetContext);
+ matcher = matchLoader.getMatcher(matcherName, mailetContext);
//The matcher itself should log that it's been inited.
if (getLogger().isInfoEnabled()) {
StringBuffer infoBuffer =
- new StringBuffer(64)
- .append("Matcher ")
- .append(matcherName)
- .append(" instantiated.");
+ new StringBuffer(64).append("Matcher ").append(matcherName).append(
+ " instantiated.");
getLogger().info(infoBuffer.toString());
}
} catch (MessagingException ex) {
// **** Do better job printing out exception
if (getLogger().isErrorEnabled()) {
StringBuffer errorBuffer =
- new StringBuffer(256)
- .append("Unable to init matcher ")
- .append(matcherName)
- .append(": ")
- .append(ex.toString());
- getLogger().error( errorBuffer.toString(), ex );
+ new StringBuffer(256).append("Unable to init matcher ").append(
+ matcherName).append(
+ ": ").append(
+ ex.toString());
+ getLogger().error(errorBuffer.toString(), ex);
}
System.err.println("Unable to init matcher " + matcherName);
System.err.println("Check spool manager logs for more details.");
@@ -215,26 +185,23 @@
throw ex;
}
try {
- mailet = mailetLoader.getMailet(mailetClassName,
- mailetContext, c);
+ mailet = mailetLoader.getMailet(mailetClassName, mailetContext, c);
if (getLogger().isInfoEnabled()) {
StringBuffer infoBuffer =
- new StringBuffer(64)
- .append("Mailet ")
- .append(mailetClassName)
- .append(" instantiated.");
+ new StringBuffer(64).append("Mailet ").append(
+ mailetClassName).append(
+ " instantiated.");
getLogger().info(infoBuffer.toString());
}
} catch (MessagingException ex) {
// **** Do better job printing out exception
if (getLogger().isErrorEnabled()) {
StringBuffer errorBuffer =
- new StringBuffer(256)
- .append("Unable to init mailet ")
- .append(mailetClassName)
- .append(": ")
- .append(ex.toString());
- getLogger().error( errorBuffer.toString(), ex );
+ new StringBuffer(256).append("Unable to init mailet ").append(
+ mailetClassName).append(
+ ": ").append(
+ ex.toString());
+ getLogger().error(errorBuffer.toString(), ex);
}
System.err.println("Unable to init mailet " + mailetClassName);
System.err.println("Check spool manager logs for more details.");
@@ -245,61 +212,49 @@
//Add this pair to the processor
processor.add(matcher, mailet);
}
-
// Close the processor matcher/mailet lists.
//
// Please note that this is critical to the proper operation
// of the LinearProcessor code. The processor will not be
// able to service mails until this call is made.
processor.closeProcessorLists();
-
if (getLogger().isInfoEnabled()) {
StringBuffer infoBuffer =
- new StringBuffer(64)
- .append("Processor ")
- .append(processorName)
- .append(" instantiated.");
+ new StringBuffer(64).append("Processor ").append(processorName).append(
+ " instantiated.");
getLogger().info(infoBuffer.toString());
}
} catch (Exception ex) {
if (getLogger().isErrorEnabled()) {
StringBuffer errorBuffer =
- new StringBuffer(256)
- .append("Unable to init processor ")
- .append(processorName)
- .append(": ")
- .append(ex.toString());
- getLogger().error( errorBuffer.toString(), ex );
+ new StringBuffer(256).append("Unable to init processor ").append(
+ processorName).append(
+ ": ").append(
+ ex.toString());
+ getLogger().error(errorBuffer.toString(), ex);
}
throw ex;
}
}
if (getLogger().isInfoEnabled()) {
StringBuffer infoBuffer =
- new StringBuffer(64)
- .append("Spooler Manager uses ")
- .append(numThreads)
- .append(" Thread(s)");
+ new StringBuffer(64).append("Spooler Manager uses ").append(numThreads).append(
+ " Thread(s)");
getLogger().info(infoBuffer.toString());
}
- for ( int i = 0 ; i < numThreads ; i++ )
+ for (int i = 0; i < numThreads; i++)
workerPool.execute(this);
}
-
/**
* This routinely checks the message spool for messages, and processes
* them as necessary
*/
public void run() {
-
- if (getLogger().isInfoEnabled())
- {
- getLogger().info("Run JamesSpoolManager: "
- + Thread.currentThread().getName());
+ if (getLogger().isInfoEnabled()) {
+ getLogger().info("Run JamesSpoolManager: " + Thread.currentThread().getName());
getLogger().info("Spool=" + spool.getClass().getName());
}
-
- while(true) {
+ while (true) {
try {
String key = spool.accept();
Mail mail = spool.retrieve(key);
@@ -311,29 +266,26 @@
}
if (getLogger().isDebugEnabled()) {
StringBuffer debugBuffer =
- new StringBuffer(64)
- .append("==== Begin processing mail ")
- .append(mail.getName())
- .append("====");
+ new StringBuffer(64).append("==== Begin processing mail ").append(
+ mail.getName()).append(
+ "====");
getLogger().debug(debugBuffer.toString());
}
process(mail);
// Only remove an email from the spool is processing is
// complete, or if it has no recipients
- if ((Mail.GHOST.equals(mail.getState())) ||
- (mail.getRecipients() == null) ||
- (mail.getRecipients().size() == 0)) {
+ if ((Mail.GHOST.equals(mail.getState()))
+ || (mail.getRecipients() == null)
+ || (mail.getRecipients().size() == 0)) {
spool.remove(key);
if (getLogger().isDebugEnabled()) {
StringBuffer debugBuffer =
- new StringBuffer(64)
- .append("==== Removed from spool mail ")
- .append(mail.getName())
- .append("====");
+ new StringBuffer(64).append("==== Removed from spool mail ").append(
+ mail.getName()).append(
+ "====");
getLogger().debug(debugBuffer.toString());
}
- }
- else {
+ } else {
// spool.remove() has a side-effect! It unlocks the
// message so that other threads can work on it! If
// we don't remove it, we must unlock it!
@@ -343,13 +295,11 @@
} catch (Exception e) {
e.printStackTrace();
if (getLogger().isErrorEnabled()) {
- getLogger().error("Exception in JamesSpoolManager.run "
- + e.getMessage());
+ getLogger().error("Exception in JamesSpoolManager.run " + e.getMessage());
}
}
}
}
-
/**
* Process this mail message by the appropriate processor as designated
* in the state of the Mail object.
@@ -364,8 +314,7 @@
return;
}
try {
- LinearProcessor processor
- = (LinearProcessor)processors.get(processorName);
+ LinearProcessor processor = (LinearProcessor) processors.get(processorName);
if (processor == null) {
StringBuffer exceptionMessageBuffer =
new StringBuffer(128)
@@ -380,21 +329,17 @@
StringBuffer logMessageBuffer = null;
if (getLogger().isDebugEnabled()) {
logMessageBuffer =
- new StringBuffer(64)
- .append("Processing ")
- .append(mail.getName())
- .append(" through ")
- .append(processorName);
+ new StringBuffer(64).append("Processing ").append(mail.getName()).append(
+ " through ").append(
+ processorName);
getLogger().debug(logMessageBuffer.toString());
}
processor.service(mail);
if (getLogger().isDebugEnabled()) {
logMessageBuffer =
- new StringBuffer(128)
- .append("Processed")
- .append(mail.getName())
- .append(" through ")
- .append(processorName);
+ new StringBuffer(128).append("Processed").append(mail.getName()).append(
+ " through ").append(
+ processorName);
getLogger().debug(logMessageBuffer.toString());
getLogger().debug("Result was " + mail.getState());
}
@@ -402,11 +347,10 @@
} catch (Exception e) {
// This is a strange error situation that shouldn't ordinarily
// happen
- StringBuffer exceptionBuffer =
- new StringBuffer(64)
- .append("Exception in processor <")
- .append(processorName)
- .append(">");
+ StringBuffer exceptionBuffer =
+ new StringBuffer(64).append("Exception in processor <").append(
+ processorName).append(
+ ">");
getLogger().error(exceptionBuffer.toString(), e);
if (processorName.equals(Mail.ERROR)) {
// We got an error on the error processor...
@@ -422,16 +366,15 @@
if (getLogger().isErrorEnabled()) {
StringBuffer logMessageBuffer =
new StringBuffer(128)
- .append("An error occurred processing ")
- .append(mail.getName())
- .append(" through ")
- .append(processorName);
+ .append("An error occurred processing ")
+ .append(mail.getName())
+ .append(" through ")
+ .append(processorName);
getLogger().error(logMessageBuffer.toString());
getLogger().error("Result was " + mail.getState());
}
}
}
-
/**
* The dispose operation is called at the end of a components lifecycle.
* Instances of this class use this method to release and destroy any
@@ -446,13 +389,19 @@
getLogger().info("JamesSpoolManager dispose...");
Iterator it = processors.keySet().iterator();
while (it.hasNext()) {
- String processorName = (String)it.next();
+ String processorName = (String) it.next();
if (getLogger().isDebugEnabled()) {
getLogger().debug("Processor " + processorName);
}
- LinearProcessor processor = (LinearProcessor)processors.get(processorName);
+ LinearProcessor processor = (LinearProcessor) processors.get(processorName);
processor.dispose();
processors.remove(processor);
}
+ }
+ /**
+ * @see org.apache.avalon.framework.context.Contextualizable#contextualize(Context)
+ */
+ public void contextualize(Context context) {
+ this.context = context;
}
}
1.8 +66 -24 jakarta-james/src/java/org/apache/james/transport/MailetLoader.java
Index: MailetLoader.java
===================================================================
RCS file: /home/cvs/jakarta-james/src/java/org/apache/james/transport/MailetLoader.java,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- MailetLoader.java 2 Oct 2002 06:12:03 -0000 1.7
+++ MailetLoader.java 8 Jan 2003 12:31:05 -0000 1.8
@@ -6,41 +6,48 @@
* the LICENSE file.
*/
package org.apache.james.transport;
-
+import java.io.File;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.Vector;
+import javax.mail.MessagingException;
import org.apache.avalon.framework.component.Component;
import org.apache.avalon.framework.configuration.Configurable;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.context.Context;
+import org.apache.avalon.framework.context.ContextException;
+import org.apache.avalon.framework.context.Contextualizable;
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.avalon.phoenix.BlockContext;
import org.apache.james.core.MailetConfigImpl;
import org.apache.mailet.Mailet;
import org.apache.mailet.MailetContext;
import org.apache.mailet.MailetException;
-
-import javax.mail.MessagingException;
-import java.util.Vector;
-
/**
* Loads Mailets for use inside James.
*
* @author Serge Knystautas <se...@lokitech.com>
* @author Federico Barbieri <sc...@systemy.it>
*/
-public class MailetLoader implements Component, Configurable {
-
+public class MailetLoader implements Component, Configurable, Contextualizable {
+ private ClassLoader theClassLoader = null;
+ private String baseDirectory = null;
+ private Logger logger;
/**
* The list of packages that may contain Mailets
*/
private Vector mailetPackages;
-
/**
* @see org.apache.avalon.framework.configuration.Configurable#configure(Configuration)
*/
public void configure(Configuration conf) throws ConfigurationException {
mailetPackages = new Vector();
mailetPackages.addElement("");
- final Configuration[] pkgConfs = conf.getChildren( "mailetpackage" );
- for ( int i = 0; i < pkgConfs.length; i++ )
- {
+ final Configuration[] pkgConfs = conf.getChildren("mailetpackage");
+ for (int i = 0; i < pkgConfs.length; i++) {
Configuration c = pkgConfs[i];
String packageName = c.getValue();
if (!packageName.endsWith(".")) {
@@ -48,8 +55,34 @@
}
mailetPackages.addElement(packageName);
}
+ File base = new File(baseDirectory + "/SAR-INF/lib");
+ String[] flist = base.list();
+ Vector jarlist = new Vector();
+ URL[] classPath = null;
+ try {
+ jarlist.add(new URL("file://" + baseDirectory + "/SAR-INF/classes/"));
+ } catch (MalformedURLException e) {
+ logger.error(
+ "cant add "
+ + "file://"
+ + baseDirectory
+ + "/SAR-INF/classes/ to mailet classloader");
+ }
+ if (flist != null) {
+ for (int i = 0; i < flist.length; i++) {
+ try {
+ if (flist[i].indexOf("jar") == flist[i].length() - 3) {
+ jarlist.add(new URL("file://" + flist[i]));
+ logger.debug("added " + flist[i] + " to Mailet Classloader");
+ }
+ } catch (MalformedURLException e) {
+ logger.error("cant add " + "file://" + flist[i] + " to mailet classloader");
+ }
+ }
+ }
+ classPath = (URL[]) jarlist.toArray(new URL[jarlist.size()]);
+ theClassLoader = new URLClassLoader(classPath, this.getClass().getClassLoader());
}
-
/**
* Get a new Mailet with the specified name acting
* in the specified context.
@@ -63,18 +96,15 @@
throws MessagingException {
try {
for (int i = 0; i < mailetPackages.size(); i++) {
- String className = (String)mailetPackages.elementAt(i) + mailetName;
- ClassLoader theClassLoader = null;
+ String className = (String) mailetPackages.elementAt(i) + mailetName;
try {
MailetConfigImpl configImpl = new MailetConfigImpl();
configImpl.setMailetName(mailetName);
configImpl.setConfiguration(configuration);
configImpl.setMailetContext(context);
-
if (theClassLoader == null) {
theClassLoader = this.getClass().getClassLoader();
}
-
Mailet mailet = (Mailet) theClassLoader.loadClass(className).newInstance();
mailet.init(configImpl);
return mailet;
@@ -84,20 +114,32 @@
}
StringBuffer exceptionBuffer =
new StringBuffer(128)
- .append("Requested mailet not found: ")
- .append(mailetName)
- .append(". looked in ")
- .append(mailetPackages.toString());
+ .append("Requested mailet not found: ")
+ .append(mailetName)
+ .append(". looked in ")
+ .append(mailetPackages.toString());
throw new ClassNotFoundException(exceptionBuffer.toString());
} catch (MessagingException me) {
throw me;
} catch (Exception e) {
StringBuffer exceptionBuffer =
- new StringBuffer(128)
- .append("Could not load mailet (")
- .append(mailetName)
- .append(")");
+ new StringBuffer(128).append("Could not load mailet (").append(mailetName).append(
+ ")");
throw new MailetException(exceptionBuffer.toString(), e);
}
+ }
+ /**
+ * @see org.apache.avalon.framework.context.Contextualizable#contextualize(Context)
+ */
+ public void contextualize(final Context context) throws ContextException {
+ try {
+ baseDirectory = ((BlockContext) context).getBaseDirectory().getCanonicalPath();
+ } catch (IOException e) {
+ logger.error("cant get base directory for mailet loader");
+ throw new ContextException("cant contextualise loader " + e.getMessage(), e);
+ }
+ }
+ public void setLogger(Logger logger) {
+ this.logger = logger;
}
}
1.9 +68 -29 jakarta-james/src/java/org/apache/james/transport/MatchLoader.java
Index: MatchLoader.java
===================================================================
RCS file: /home/cvs/jakarta-james/src/java/org/apache/james/transport/MatchLoader.java,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- MatchLoader.java 2 Oct 2002 06:12:03 -0000 1.8
+++ MatchLoader.java 8 Jan 2003 12:31:05 -0000 1.9
@@ -6,41 +6,49 @@
* the LICENSE file.
*/
package org.apache.james.transport;
-
+import java.io.File;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.Vector;
+import javax.mail.MessagingException;
import org.apache.avalon.framework.component.Component;
import org.apache.avalon.framework.configuration.Configurable;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.context.Context;
+import org.apache.avalon.framework.context.ContextException;
+import org.apache.avalon.framework.context.Contextualizable;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.avalon.phoenix.BlockContext;
import org.apache.james.core.MatcherConfigImpl;
import org.apache.mailet.MailetContext;
import org.apache.mailet.MailetException;
import org.apache.mailet.Matcher;
-
-import javax.mail.MessagingException;
-import java.util.Vector;
-
/**
* Loads Matchers for use inside James.
*
* @author Serge Knystautas <se...@lokitech.com>
* @author Federico Barbieri <sc...@systemy.it>
*/
-public class MatchLoader implements Component, Configurable {
-
+public class MatchLoader implements Component, Configurable, Contextualizable {
/**
* The list of packages that may contain Mailets
*/
private Vector matcherPackages;
-
+ private ClassLoader theClassLoader = null;
+ private String baseDirectory = null;
+ private Logger logger;
/**
* @see org.apache.avalon.framework.configuration.Configurable#configure(Configuration)
*/
public void configure(Configuration conf) throws ConfigurationException {
matcherPackages = new Vector();
matcherPackages.addElement("");
- final Configuration[] pkgConfs = conf.getChildren( "matcherpackage" );
- for ( int i = 0; i < pkgConfs.length; i++ )
- {
+ final Configuration[] pkgConfs = conf.getChildren("matcherpackage");
+ for (int i = 0; i < pkgConfs.length; i++) {
Configuration c = pkgConfs[i];
String packageName = c.getValue();
if (!packageName.endsWith(".")) {
@@ -48,8 +56,34 @@
}
matcherPackages.addElement(packageName);
}
+ File base = new File(baseDirectory + "/SAR-INF/lib");
+ String[] flist = base.list();
+ Vector jarlist = new Vector();
+ URL[] classPath = null;
+ try {
+ jarlist.add(new URL("file://" + baseDirectory + "/SAR-INF/lib/classes/"));
+ } catch (MalformedURLException e) {
+ logger.error(
+ "cant add "
+ + "file://"
+ + baseDirectory
+ + "/SAR-INF/classes/ to matcher classloader");
+ }
+ if (flist != null) {
+ for (int i = 0; i < flist.length; i++) {
+ try {
+ if (flist[i].indexOf("jar") == flist[i].length() - 3) {
+ jarlist.add(new URL("file://" + flist[i]));
+ logger.debug("added " + flist[i] + " to Matcher Classloader");
+ }
+ } catch (MalformedURLException e) {
+ logger.error("cant add " + "file://" + flist[i] + " to matcher classloader");
+ }
+ }
+ }
+ classPath = (URL[]) jarlist.toArray(new URL[jarlist.size()]);
+ theClassLoader = new URLClassLoader(classPath, this.getClass().getClassLoader());
}
-
/**
* Get a new Matcher with the specified name acting
* in the specified context.
@@ -59,8 +93,7 @@
* matcher
* @throws MessagingException if an error occurs
*/
- public Matcher getMatcher(String matchName, MailetContext context)
- throws MessagingException {
+ public Matcher getMatcher(String matchName, MailetContext context) throws MessagingException {
try {
String condition = (String) null;
int i = matchName.indexOf('=');
@@ -68,19 +101,13 @@
condition = matchName.substring(i + 1);
matchName = matchName.substring(0, i);
}
- ClassLoader theClassLoader = null;
for (i = 0; i < matcherPackages.size(); i++) {
- String className = (String)matcherPackages.elementAt(i) + matchName;
+ String className = (String) matcherPackages.elementAt(i) + matchName;
try {
MatcherConfigImpl configImpl = new MatcherConfigImpl();
configImpl.setMatcherName(matchName);
configImpl.setCondition(condition);
configImpl.setMailetContext(context);
-
- if (theClassLoader == null) {
- theClassLoader = this.getClass().getClassLoader();
- }
-
Matcher matcher = (Matcher) theClassLoader.loadClass(className).newInstance();
matcher.init(configImpl);
return matcher;
@@ -90,20 +117,32 @@
}
StringBuffer exceptionBuffer =
new StringBuffer(128)
- .append("Requested matcher not found: ")
- .append(matchName)
- .append(". looked in ")
- .append(matcherPackages.toString());
+ .append("Requested matcher not found: ")
+ .append(matchName)
+ .append(". looked in ")
+ .append(matcherPackages.toString());
throw new ClassNotFoundException(exceptionBuffer.toString());
} catch (MessagingException me) {
throw me;
} catch (Exception e) {
StringBuffer exceptionBuffer =
- new StringBuffer(128)
- .append("Could not load matcher (")
- .append(matchName)
- .append(")");
+ new StringBuffer(128).append("Could not load matcher (").append(matchName).append(
+ ")");
throw new MailetException(exceptionBuffer.toString(), e);
}
+ }
+ /**
+ * @see org.apache.avalon.framework.context.Contextualizable#contextualize(Context)
+ */
+ public void contextualize(final Context context) throws ContextException {
+ try {
+ baseDirectory = ((BlockContext) context).getBaseDirectory().getCanonicalPath();
+ } catch (IOException e) {
+ logger.error("cant get base directory for matcher loader");
+ throw new ContextException("cant contextualise loader " + e.getMessage(), e);
+ }
+ }
+ public void setLogger(Logger logger) {
+ this.logger = logger;
}
}
--
To unsubscribe, e-mail: <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>
RE: cvs commit: jakarta-james/src/java/org/apache/james/transport JamesSpoolManager.java MailetLoader.java MatchLoader.java
Posted by Danny Angus <da...@apache.org>.
Hi,
This commit marks the first step towards the mailet deployment/classloading
goals set out on the wiki.
Unfortunately formatting changes got caught up with the code changes, sorry.
It doesn't achieve much more than prove that I have my head round the
lifecycle of mailets and matchers. I've run some tests on it, and it
_appears_ to work as advertised and without breaking anything.
In a nutshell you can now put mailets and matchers and their dependancies
into ~/apps/james/SAR-INF/classes or in jars in ~/apps/james/SAR-INF/lib.
I don't know if it would be a desirable addition to 2.2 or not, from the POV
of stability, but I know its something folks've wanted for quite a while.
Next step is to seperate the mailet classloader from James to hide non API
classes not explicitly installed for mailets. I know I'll have to make an
exception for the current db-access mailets until we do something to make
them compliant.
d.
> danny 2003/01/08 04:31:05
>
> Modified: src/java/org/apache/james/transport JamesSpoolManager.java
> MailetLoader.java MatchLoader.java
> Log:
> Mailet Classloader changes. First efforts..
> Mailet and matcher classes and their dependancies can now be loaded
> from ~/apps/james/SAR-INF/classes
> and jars in ~/apps/james/SAR-INF/lib/
--
To unsubscribe, e-mail: <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>