Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Session.getService does not use proper classloader in OSGI environment #703

Merged
merged 3 commits into from
Jan 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 24 additions & 33 deletions api/src/main/java/jakarta/mail/Session.java
Original file line number Diff line number Diff line change
Expand Up @@ -816,43 +816,37 @@ private <T extends Service> T getService(Provider provider, URLName url, Class<T
null, null, null);
}

Object service = null;

// get the ClassLoader associated with the Authenticator
ClassLoader cl;
Class<?> acl;
if (authenticator != null)
cl = authenticator.getClass().getClassLoader();
acl = authenticator.getClass();
else
cl = this.getClass().getClassLoader();
acl = streamProvider.getClass();

// now load the class
Class<?> serviceClass = null;
try {
// First try the "application's" class loader.
ClassLoader ccl = getContextClassLoader();
if (ccl != null)
try {
serviceClass =
Class.forName(provider.getClassName(), false, ccl);
} catch (ClassNotFoundException ex) {
// ignore it
}
if (serviceClass == null || !type.isAssignableFrom(serviceClass))
serviceClass =
Class.forName(provider.getClassName(), false, cl);

if (!type.isAssignableFrom(serviceClass))
throw new ClassCastException(
type.getName() + " " + serviceClass.getName());
} catch (Exception ex1) {
for (ClassLoader l : getClassLoaders(Thread.class,
provider.getClass(),
acl,
streamProvider.getClass(),
getClass(),
System.class)) {
try {
//load and verify provider is compatible in this classloader
serviceClass = Class.forName(provider.getClassName(),
false, l).asSubclass(type);
break;
} catch (ClassNotFoundException | ClassCastException ex) {
// ignore it
}
}

if (serviceClass == null) {
// That didn't work, now try the "system" class loader.
// (Need both of these because JDK 1.1 class loaders
// may not delegate to their parent class loader.)
try {
serviceClass = Class.forName(provider.getClassName());
if (!type.isAssignableFrom(serviceClass))
throw new ClassCastException(
type.getName() + " " + serviceClass.getName());
serviceClass = Class.forName(provider.getClassName())
.asSubclass(type);
} catch (Exception ex) {
// Nothing worked, give up.
logger.log(Level.FINE, "Exception loading provider", ex);
Expand All @@ -866,14 +860,11 @@ private <T extends Service> T getService(Provider provider, URLName url, Class<T
Constructor<?> cons = serviceClass.getConstructor(c);

Object[] o = {this, url};
service = cons.newInstance(o);

return type.cast(cons.newInstance(o));
} catch (Exception ex) {
logger.log(Level.FINE, "Exception loading provider", ex);
throw new NoSuchProviderException(provider.getProtocol());
}

return type.cast(service);
}

/**
Expand Down Expand Up @@ -991,7 +982,7 @@ public void load(InputStream is) throws IOException {
} else {
gcl = getContextClassLoader(); //Fail safe
}

// next, add all the non-default services
ServiceLoader<Provider> sl = ServiceLoader.load(Provider.class, gcl);
for (Provider p : sl) {
Expand Down
3 changes: 2 additions & 1 deletion doc/release/CHANGES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,9 @@ longer available.

CHANGES IN THE 2.1.3 RELEASE
----------------------------
E 695 SharedFileInputStream should comply with spec
E 631 Session.getService does not use proper classloader in OSGI environment
E 665 Jakarta Mail erroneously assumes that classes can be loaded from Thread#getContextClassLoader
E 695 SharedFileInputStream should comply with spec


CHANGES IN THE 2.1.2 RELEASE
Expand Down
Loading