import org.apache.commons.lang.StringUtils;
import ro.fortsoft.pf4j.DefaultPluginManager;
+import ro.fortsoft.pf4j.JarPluginManager;
import ro.fortsoft.pf4j.PluginManager;
import ro.fortsoft.pf4j.PluginWrapper;
import ro.fortsoft.pf4j.demo.api.Greeting;
printLogo();
// create the plugin manager
- final PluginManager pluginManager = new DefaultPluginManager();
+// final PluginManager pluginManager = new DefaultPluginManager();
+ final PluginManager pluginManager = new JarPluginManager();
// load the plugins
pluginManager.loadPlugins();
#
log4j.logger.ro.fortsoft.pf4j=DEBUG, Console
# !!! Put the bellow classes on level TRACE when you are in trouble
-log4j.logger.ro.fortsoft.pf4j.PluginClassLoader=WARN, Console
+log4j.logger.ro.fortsoft.pf4j.PluginClassLoader=DEBUG, Console
log4j.logger.ro.fortsoft.pf4j.AbstractExtensionFinder=DEBUG, Console
log4j.additivity.ro.fortsoft.pf4j=false
log4j.additivity.ro.fortsoft.pf4j.PluginClassLoader=false
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import ro.fortsoft.pf4j.util.ClassUtils;
import java.util.ArrayList;
import java.util.Collections;
log.debug("Added extension '{}' with ordinal {}", className, extensionWrapper.getOrdinal());
} else {
log.trace("'{}' is not an extension for extension point '{}'", className, type.getName());
+ if (RuntimeMode.DEVELOPMENT.equals(pluginManager.getRuntimeMode())) {
+ checkDifferentClassLoaders(type, extensionClass);
+ }
}
} catch (ClassNotFoundException e) {
log.error(e.getMessage(), e);
return extensionWrapper;
}
+ private void checkDifferentClassLoaders(Class<?> type, Class<?> extensionClass) {
+ ClassLoader typeClassLoader = type.getClassLoader(); // class loader of extension point
+ ClassLoader extensionClassLoader = extensionClass.getClassLoader();
+ boolean match = ClassUtils.getAllInterfacesNames(extensionClass).contains(type.getSimpleName());
+ if (match && !extensionClassLoader.equals(typeClassLoader)) {
+ // in this scenario the method 'isAssignableFrom' returns only FALSE
+ // see http://www.coderanch.com/t/557846/java/java/FWIW-FYI-isAssignableFrom-isInstance-differing
+ log.error("Different class loaders: '{}' (E) and '{}' (EP)", extensionClassLoader, typeClassLoader);
+ }
+ }
+
}
--- /dev/null
+/*
+ * Copyright 2016 Decebal Suiu
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package ro.fortsoft.pf4j.util;
+
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Decebal Suiu
+ */
+public class ClassUtils {
+
+ public static List<String> getAllInterfacesNames(Class<?> aClass) {
+ return toString(getAllInterfaces(aClass));
+ }
+
+ public static List<Class<?>> getAllInterfaces(Class<?> aClass) {
+ List<Class<?>> list = new ArrayList<>();
+
+ while (aClass != null) {
+ Class<?>[] interfaces = aClass.getInterfaces();
+ for (Class<?> anInterface : interfaces) {
+ if (!list.contains(anInterface)) {
+ list.add(anInterface);
+ }
+
+ List<Class<?>> superInterfaces = getAllInterfaces(anInterface);
+ for (Class<?> superInterface : superInterfaces) {
+ if (!list.contains(superInterface)) {
+ list.add(superInterface);
+ }
+ }
+ }
+
+ aClass = aClass.getSuperclass();
+ }
+
+ return list;
+ }
+
+ /*
+ public static List<String> getAllAbstractClassesNames(Class<?> aClass) {
+ return toString(getAllInterfaces(aClass));
+ }
+
+ public static List getAllAbstractClasses(Class aClass) {
+ List<Class<?>> list = new ArrayList<>();
+
+ Class<?> superclass = aClass.getSuperclass();
+ while (superclass != null) {
+ if (Modifier.isAbstract(superclass.getModifiers())) {
+ list.add(superclass);
+ }
+ superclass = superclass.getSuperclass();
+ }
+
+ return list;
+ }
+ */
+
+ /**
+ * Uses {@link Class#getSimpleName()} to convert from {@link Class} to {@link String}.
+ *
+ * @param classes
+ * @return
+ */
+ private static List<String> toString(List<Class<?>> classes) {
+ List<String> list = new ArrayList<>();
+
+ for (Class<?> aClass : classes) {
+ list.add(aClass.getSimpleName());
+ }
+
+ return list;
+ }
+
+}