I want to wite a custom Mailet for the Apache James Mail Server.
I'm running James through Docker via the linagora/james-project
image. The setup works (only locally of course, but that's enough for the moment), as I can set up accounts and connect to them with Thunderbird via IMAP and I can send mails between those accounts.
Now I want to deploy my custom Mailet to this setup. I have tried it using this tutorial: https://james.apache.org/server/3/dev-extend-mailet.html (I had to create the folder /conf/lib/ since it didn't exist) but it won't work. In the Log I see errors like this one:
james | [main] INFO org.apache.james.mailetcontainer.lib.AbstractStateMailetProcessor - Matcher All instantiated.
james | [main] ERROR org.apache.james.mailetcontainer.lib.AbstractStateMailetProcessor - Unable to init mailet com.jeremiaslubberger.mailets.TestMailet: javax.mail.MessagingException: Can not load mailet com.jeremiaslubberger.mailets.TestMailet;
james | nested exception is:
james | java.lang.ClassNotFoundException: com.jeremiaslubberger.mailets.TestMailet
james | javax.mail.MessagingException: Can not load mailet com.jeremiaslubberger.mailets.TestMailet;
james | nested exception is:
james | java.lang.ClassNotFoundException: com.jeremiaslubberger.mailets.TestMailet
By searching the source code, I found the file ExtendedClassLoader.java
where there is a line
public static final String EXTENSIONS_JARS_FOLDER_NAME = "extensions-jars/";
So I tried creating this folder (in the James root folder) and putting the JAR containing the custom Mailet there.
This still produces errors and doesn't work, however the Log now looks like this:
james | [main] INFO org.apache.james.mailetcontainer.lib.AbstractStateMailetProcessor - Matcher All instantiated.
james | Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/mailet/GenericMailet
james | at java.lang.ClassLoader.defineClass1(Native Method)
james | at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
james | at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
james | at java.net.URLClassLoader.defineClass(URLClassLoader.java:467)
james | at java.net.URLClassLoader.access$100(URLClassLoader.java:73)
james | at java.net.URLClassLoader$1.run(URLClassLoader.java:368)
james | at java.net.URLClassLoader$1.run(URLClassLoader.java:362)
james | at java.security.AccessController.doPrivileged(Native Method)
james | at java.net.URLClassLoader.findClass(URLClassLoader.java:361)
james | at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
james | at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
james | at org.apache.james.utils.ExtendedClassLoader.locateClass(ExtendedClassLoader.java:80)
james | at org.apache.james.utils.GuiceGenericLoader.instanciate(GuiceGenericLoader.java:37)
james | at org.apache.james.utils.GuiceMailetLoader.getMailet(GuiceMailetLoader.java:45)
My custom Mailet does extend GenericMailet, but so do all other (default) Mailets. Also, I exported my mailet including all resources, so there should be nothing missing there. Now I'm out of ideas.
Can anyone please help? Where do I need to put the JAR containing my custom Mailet?
You should run James from the
pwd = /james-root/bin/
. Otherwise you will get an ClassNotFoundException on application startup. It is because relative class path definition in therun.sh
. I spent lot of time to figure it out))