Browse Source

Reactivate protection against the issues similar with #97

pull/125/head
Decebal Suiu 8 years ago
parent
commit
e8d5b8eebf
  1. 4
      demo/app/src/main/java/ro/fortsoft/pf4j/demo/Boot.java
  2. 2
      demo/app/src/main/resources/log4j.properties
  3. 15
      pf4j/src/main/java/ro/fortsoft/pf4j/AbstractExtensionFinder.java
  4. 91
      pf4j/src/main/java/ro/fortsoft/pf4j/util/ClassUtils.java

4
demo/app/src/main/java/ro/fortsoft/pf4j/demo/Boot.java

@ -21,6 +21,7 @@ import java.util.Set;
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;
@ -37,7 +38,8 @@ public class Boot {
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();

2
demo/app/src/main/resources/log4j.properties

@ -5,7 +5,7 @@ log4j.rootLogger=DEBUG, Console
#
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

15
pf4j/src/main/java/ro/fortsoft/pf4j/AbstractExtensionFinder.java

@ -17,6 +17,7 @@ package ro.fortsoft.pf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ro.fortsoft.pf4j.util.ClassUtils;
import java.util.ArrayList;
import java.util.Collections;
@ -106,6 +107,9 @@ public abstract class AbstractExtensionFinder implements ExtensionFinder, Plugin
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);
@ -229,4 +233,15 @@ public abstract class AbstractExtensionFinder implements ExtensionFinder, Plugin
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);
}
}
}

91
pf4j/src/main/java/ro/fortsoft/pf4j/util/ClassUtils.java

@ -0,0 +1,91 @@
/*
* 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;
}
}
Loading…
Cancel
Save