Validate Joda-Time bridge in plugin class loaders
@@ -34,10 +34,12 @@ import com.facebook.presto.spi.type.Type;
import com.facebook.presto.type.TypeRegistry;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Ordering;
+import io.airlift.jodabridge.JdkBasedZoneInfoProvider;
import io.airlift.log.Logger;
import io.airlift.node.NodeInfo;
import io.airlift.resolver.ArtifactResolver;
import io.airlift.resolver.DefaultArtifact;
+import org.joda.time.DateTime;
import org.sonatype.aether.artifact.Artifact;
import javax.annotation.concurrent.ThreadSafe;
@@ -152,6 +154,7 @@ public class PluginManager
{
log.info("-- Loading plugin %s --", plugin);
URLClassLoader pluginClassLoader = buildClassLoader(plugin);
+ validateClassLoader(pluginClassLoader);
try (ThreadContextClassLoader ignored = new ThreadContextClassLoader(pluginClassLoader)) {
loadPlugin(pluginClassLoader);
}
@@ -314,4 +317,22 @@ public class PluginManager
Collections.sort(list, Ordering.natural().nullsLast().onResultOf(Artifact::getFile));
return list;
}
+
+ private static void validateClassLoader(ClassLoader loader)
+ {
+ if (classExists(loader, DateTime.class) && !classExists(loader, JdkBasedZoneInfoProvider.class)) {
+ throw new RuntimeException("Plugin classpath contains Joda-Time without joda-to-java-time-bridge");
+ }
+ }
+
+ private static boolean classExists(ClassLoader classLoader, Class<?> clazz)
+ {
+ try {
+ classLoader.loadClass(clazz.getName());
+ return true;
+ }
+ catch (ClassNotFoundException e) {
+ return false;
+ }
+ }
}
