You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by pa...@apache.org on 2017/04/05 12:55:10 UTC
wicket git commit: WICKET-6353: override resolveProxyClass to lookup
classes in Wicket's ClassResolver
Repository: wicket
Updated Branches:
refs/heads/classloadingfix [created] 5b7ff7d03
WICKET-6353: override resolveProxyClass to lookup classes in Wicket's ClassResolver
Project: http://git-wip-us.apache.org/repos/asf/wicket/repo
Commit: http://git-wip-us.apache.org/repos/asf/wicket/commit/5b7ff7d0
Tree: http://git-wip-us.apache.org/repos/asf/wicket/tree/5b7ff7d0
Diff: http://git-wip-us.apache.org/repos/asf/wicket/diff/5b7ff7d0
Branch: refs/heads/classloadingfix
Commit: 5b7ff7d03a9a4fe1ec20a7021ab7ec46ef2fbca8
Parents: 137fa9e
Author: Emond Papegaaij <pa...@apache.org>
Authored: Wed Apr 5 14:54:28 2017 +0200
Committer: Emond Papegaaij <pa...@apache.org>
Committed: Wed Apr 5 14:54:28 2017 +0200
----------------------------------------------------------------------
.../wicket/serialize/java/JavaSerializer.java | 111 ++++++++++++++++---
1 file changed, 98 insertions(+), 13 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/wicket/blob/5b7ff7d0/wicket-core/src/main/java/org/apache/wicket/serialize/java/JavaSerializer.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/serialize/java/JavaSerializer.java b/wicket-core/src/main/java/org/apache/wicket/serialize/java/JavaSerializer.java
index 1ca239b..39c09ce 100644
--- a/wicket-core/src/main/java/org/apache/wicket/serialize/java/JavaSerializer.java
+++ b/wicket-core/src/main/java/org/apache/wicket/serialize/java/JavaSerializer.java
@@ -25,6 +25,10 @@ import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectStreamClass;
import java.io.OutputStream;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.Proxy;
import org.apache.wicket.Application;
import org.apache.wicket.ThreadContext;
@@ -188,45 +192,126 @@ public class JavaSerializer implements ISerializer
protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException,
ClassNotFoundException
{
- String className = desc.getName();
-
try
{
return super.resolveClass(desc);
}
- catch (ClassNotFoundException ex1)
+ catch (ClassNotFoundException cnfEx)
{
// ignore this exception.
- log.debug("Class not found by the object outputstream itself, trying the IClassResolver");
+ log.debug(
+ "Class not found by the object outputstream itself, trying the IClassResolver");
+
+ Class< ? > candidate = resolveClassInWicket(desc.getName());
+ if (candidate == null)
+ {
+ throw cnfEx;
+ }
+ return candidate;
}
+ }
+ private Class< ? > resolveClassByName(String className) throws ClassNotFoundException
+ {
+ try
+ {
+ return Class.forName(className, false, latestUserDefinedLoader());
+ }
+ catch (ClassNotFoundException cnfEx)
+ {
+ Class< ? > ret = resolveClassInWicket(className);
+ if (ret == null)
+ throw cnfEx;
+ return ret;
+ }
+ }
- Class<?> candidate = null;
+ private Class< ? > resolveClassInWicket(String className) throws ClassNotFoundException
+ {
+ Class< ? > candidate;
try
{
- // Can the application always be taken??
- // Should be if serialization happened in thread with application set
- // (WICKET-2195)
Application application = Application.get();
ApplicationSettings applicationSettings = application.getApplicationSettings();
IClassResolver classResolver = applicationSettings.getClassResolver();
candidate = classResolver.resolveClass(className);
- if (candidate == null)
- {
- candidate = super.resolveClass(desc);
- }
}
catch (WicketRuntimeException ex)
{
if (ex.getCause() instanceof ClassNotFoundException)
{
- throw (ClassNotFoundException)ex.getCause();
+ throw (ClassNotFoundException) ex.getCause();
+ }
+ else
+ {
+ ClassNotFoundException wrapperCnf = new ClassNotFoundException();
+ wrapperCnf.initCause(ex);
+ throw wrapperCnf;
}
}
return candidate;
}
+
+ @Override
+ protected Class< ? > resolveProxyClass(String[] interfaces) throws ClassNotFoundException
+ {
+ ClassLoader latestLoader = latestUserDefinedLoader();
+ ClassLoader nonPublicLoader = null;
+ boolean hasNonPublicInterface = false;
+
+ // define proxy in class loader of non-public interface(s), if any
+ Class< ? >[] classObjs = new Class< ? >[interfaces.length];
+ for (int i = 0; i < interfaces.length; i++)
+ {
+ Class< ? > cl = resolveClassByName(interfaces[i]);
+ if ((cl.getModifiers() & Modifier.PUBLIC) == 0)
+ {
+ if (hasNonPublicInterface)
+ {
+ if (nonPublicLoader != cl.getClassLoader())
+ {
+ throw new IllegalAccessError(
+ "conflicting non-public interface class loaders");
+ }
+ }
+ else
+ {
+ nonPublicLoader = cl.getClassLoader();
+ hasNonPublicInterface = true;
+ }
+ }
+ classObjs[i] = cl;
+ }
+ try
+ {
+ return Proxy.getProxyClass(hasNonPublicInterface ? nonPublicLoader : latestLoader,
+ classObjs);
+ }
+ catch (IllegalArgumentException e)
+ {
+ throw new ClassNotFoundException(null, e);
+ }
+ }
+
+ private static ClassLoader latestUserDefinedLoader()
+ {
+ try
+ {
+ Method originalMethod =
+ ObjectInputStream.class.getDeclaredMethod("latestUserDefinedLoader");
+ originalMethod.setAccessible(true);
+ return (ClassLoader) originalMethod.invoke(null);
+ }
+ catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException
+ | NoSuchMethodException | SecurityException e)
+ {
+ // should not happen
+ throw new WicketRuntimeException(e);
+ }
+ }
}
+
/**
* Write objects to the wrapped output stream and log a meaningful message for serialization
* problems.