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

SystemProperty: Remember the classloader which loaded a class #2000

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
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
46 changes: 32 additions & 14 deletions xmppserver/src/main/java/org/jivesoftware/util/SystemProperty.java
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,7 @@ public void xmlPropertyDeleted(final String property, final Map<String, Object>
private final Class baseClass;
private final Class collectionType;
private final boolean sorted;
private volatile ClassLoader classLoader;

private SystemProperty(final Builder<T> builder) {
// Before we do anything, convert XML based provider setup to Database based
Expand All @@ -241,6 +242,9 @@ private SystemProperty(final Builder<T> builder) {
this.plugin = builder.plugin;
this.description = LocaleUtils.getLocalizedPluginString(plugin, "system_property." + key);
this.defaultValue = builder.defaultValue;
if (defaultValue instanceof Class) {
this.classLoader = ((Class<?>) defaultValue).getClassLoader();
}
this.minValue = builder.minValue;
this.maxValue = builder.maxValue;
this.dynamic = builder.dynamic;
Expand Down Expand Up @@ -302,21 +306,31 @@ private Class getConverterClass() {
*/
@SuppressWarnings("unchecked")
public T getValue() {
final T value = (T) FROM_STRING.get(getConverterClass()).apply(JiveGlobals.getProperty(key), this);
if (value == null || (Collection.class.isAssignableFrom(value.getClass()) && ((Collection) value).isEmpty())) {
return defaultValue;
}
if (minValue != null && ((Comparable) minValue).compareTo(value) > 0) {
LOGGER.warn("Configured value of {} is less than the minimum value of {} for the SystemProperty {} - will use default value of {} instead",
value, minValue, key, defaultValue);
return defaultValue;
}
if (maxValue != null && ((Comparable) maxValue).compareTo(value) < 0) {
LOGGER.warn("Configured value of {} is more than the maximum value of {} for the SystemProperty {} - will use default value of {} instead",
value, maxValue, key, defaultValue);
return defaultValue;
ClassLoader previousClassLoader = Thread.currentThread().getContextClassLoader();
try {
ClassLoader cl = classLoader;
if (cl != null) {
Thread.currentThread().setContextClassLoader(cl);
}

final T value = (T) FROM_STRING.get(getConverterClass()).apply(JiveGlobals.getProperty(key), this);
if (value == null || (Collection.class.isAssignableFrom(value.getClass()) && ((Collection) value).isEmpty())) {
return defaultValue;
}
if (minValue != null && ((Comparable) minValue).compareTo(value) > 0) {
LOGGER.warn("Configured value of {} is less than the minimum value of {} for the SystemProperty {} - will use default value of {} instead",
value, minValue, key, defaultValue);
return defaultValue;
}
if (maxValue != null && ((Comparable) maxValue).compareTo(value) < 0) {
LOGGER.warn("Configured value of {} is more than the maximum value of {} for the SystemProperty {} - will use default value of {} instead",
value, maxValue, key, defaultValue);
return defaultValue;
}
return value;
} finally {
Thread.currentThread().setContextClassLoader(previousClassLoader);
}
return value;
}

/**
Expand Down Expand Up @@ -354,6 +368,10 @@ public String getDefaultDisplayValue() {
* @param value the new value for the SystemProperty
*/
public void setValue(final T value) {
if (value instanceof Class) {
Class<?> clazz = ((Class<?>) value);
this.classLoader = clazz.getClassLoader();
}
JiveGlobals.setProperty(key, TO_STRING.get(getConverterClass()).apply(value, this), isEncrypted());
}

Expand Down