Watcher: Fix sending of emails

In order to be able to send emails, the thread context classs loader
must be set to the watcher plugin class loader (and reset afterwards),
otherwise some javax.activation classes needed to create mime attachments
cannot be found.

In addition the activation jar dependency has been removed.

Closes elastic/elasticsearch#1066
Closes elastic/elasticsearch#708

Original commit: elastic/x-pack-elasticsearch@10042375ec
This commit is contained in:
Alexander Reelsen 2015-12-09 10:04:15 +01:00
parent b6ce09a361
commit 62cd783942
3 changed files with 34 additions and 1 deletions

View File

@ -33,7 +33,6 @@ dependencies {
compile 'com.google.guava:guava:16.0.1' // needed by watcher and shield tests for jimfs
compile 'com.google.code.findbugs:jsr305:3.0.1' // TODO: remove this
compile 'com.sun.mail:javax.mail:1.5.3'
compile 'javax.activation:activation:1.1.1'
testCompile 'org.subethamail:subethasmtp:3.1.7'
// common test deps

View File

@ -4,4 +4,11 @@ grant {
// needed to set expert SSL options, etc
permission java.lang.RuntimePermission "setFactory";
// needed when sending emails for javax.activation
// otherwise a classnotfound exception is thrown due to trying
// to load the class with the application class loader
permission java.lang.RuntimePermission "setContextClassLoader";
permission java.lang.RuntimePermission "getClassLoader";
};

View File

@ -99,6 +99,7 @@ public class Account {
}
transport.connect(config.smtp.host, config.smtp.port, user, password);
ClassLoader contextClassLoader = null;
try {
MimeMessage message = profile.toMimeMessage(email, session);
String mid = message.getMessageID();
@ -108,6 +109,17 @@ public class Account {
// we need to add it back
message.setHeader(Profile.MESSAGE_ID_HEADER, mid);
}
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
// unprivileged code such as scripts do not have SpecialPermission
sm.checkPermission(new SpecialPermission());
}
contextClassLoader = AccessController.doPrivileged((PrivilegedAction<ClassLoader>) () -> Thread.currentThread().getContextClassLoader());
// if we cannot get the context class loader, changing does not make sense, as we run into the danger of not being able to change it back
if (contextClassLoader != null) {
setContextClassLoader(this.getClass().getClassLoader());
}
transport.sendMessage(message, message.getAllRecipients());
} finally {
try {
@ -115,10 +127,25 @@ public class Account {
} catch (MessagingException me) {
logger.error("failed to close email transport for account [" + config.name + "]");
}
if (contextClassLoader != null) {
setContextClassLoader(contextClassLoader);
}
}
return email;
}
private void setContextClassLoader(final ClassLoader classLoader) {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
// unprivileged code such as scripts do not have SpecialPermission
sm.checkPermission(new SpecialPermission());
}
AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
Thread.currentThread().setContextClassLoader(classLoader);
return null;
});
}
static class Config {
static final String SMTP_SETTINGS_PREFIX = "mail.smtp.";