Repository: wicket Updated Branches: refs/heads/wicket-7.x ea7e36b17 -> 27b9a67d9
WICKET-4324 [wicket-ioc] LazyInitProxyFactory CGLIB proxies naming strategy may cause java.lang.IllegalAccessError Change the calculation of the 'prefix' in WicketNamingStrategy from 'WICKET_package.Class' to 'package.Wicket_Proxy_Class' Project: http://git-wip-us.apache.org/repos/asf/wicket/repo Commit: http://git-wip-us.apache.org/repos/asf/wicket/commit/27b9a67d Tree: http://git-wip-us.apache.org/repos/asf/wicket/tree/27b9a67d Diff: http://git-wip-us.apache.org/repos/asf/wicket/diff/27b9a67d Branch: refs/heads/wicket-7.x Commit: 27b9a67d9e986d8998888e9984125ce2a2248498 Parents: ea7e36b Author: Martin Tzvetanov Grigorov <[email protected]> Authored: Mon Jun 19 21:59:05 2017 +0200 Committer: Martin Tzvetanov Grigorov <[email protected]> Committed: Mon Jun 19 21:59:05 2017 +0200 ---------------------------------------------------------------------- .../wicket/proxy/LazyInitProxyFactory.java | 7 +- .../wicket/proxy/LazyInitProxyFactoryTest.java | 67 ++++++++++++++++++++ .../proxy/PackagePrivateConcreteObject.java | 54 ++++++++++++++++ 3 files changed, 127 insertions(+), 1 deletion(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/wicket/blob/27b9a67d/wicket-ioc/src/main/java/org/apache/wicket/proxy/LazyInitProxyFactory.java ---------------------------------------------------------------------- diff --git a/wicket-ioc/src/main/java/org/apache/wicket/proxy/LazyInitProxyFactory.java b/wicket-ioc/src/main/java/org/apache/wicket/proxy/LazyInitProxyFactory.java index bfd34a1..26400e5 100644 --- a/wicket-ioc/src/main/java/org/apache/wicket/proxy/LazyInitProxyFactory.java +++ b/wicket-ioc/src/main/java/org/apache/wicket/proxy/LazyInitProxyFactory.java @@ -42,6 +42,7 @@ import org.apache.wicket.core.util.lang.WicketObjects; import org.apache.wicket.model.IModel; import org.apache.wicket.proxy.objenesis.ObjenesisProxyFactory; import org.apache.wicket.util.io.IClusterable; +import org.apache.wicket.util.string.Strings; /** * A factory class that creates lazy init proxies given a type and a {@link IProxyTargetLocator} @@ -610,7 +611,11 @@ public class LazyInitProxyFactory public String getClassName(final String prefix, final String source, final Object key, final Predicate names) { - return super.getClassName("WICKET_" + prefix, source, key, names); + int lastIdxOfDot = prefix.lastIndexOf('.'); + String packageName = prefix.substring(0, lastIdxOfDot); + String className = prefix.substring(lastIdxOfDot + 1); + String newPrefix = packageName + ".Wicket_Proxy_" + className; + return super.getClassName(newPrefix, source, key, names); } } http://git-wip-us.apache.org/repos/asf/wicket/blob/27b9a67d/wicket-ioc/src/test/java/org/apache/wicket/proxy/LazyInitProxyFactoryTest.java ---------------------------------------------------------------------- diff --git a/wicket-ioc/src/test/java/org/apache/wicket/proxy/LazyInitProxyFactoryTest.java b/wicket-ioc/src/test/java/org/apache/wicket/proxy/LazyInitProxyFactoryTest.java index 897c628..60bab12 100644 --- a/wicket-ioc/src/test/java/org/apache/wicket/proxy/LazyInitProxyFactoryTest.java +++ b/wicket-ioc/src/test/java/org/apache/wicket/proxy/LazyInitProxyFactoryTest.java @@ -42,6 +42,8 @@ public class LazyInitProxyFactoryTest extends Assert private static ConcreteObject concreteObject = new ConcreteObject("concrete"); + private static final PackagePrivateConcreteObject PACKAGE_PRIVATE_CONCRETE_OBJECT = new PackagePrivateConcreteObject("package-private-concrete"); + private static IProxyTargetLocator interfaceObjectLocator = new IProxyTargetLocator() { private static final long serialVersionUID = 1L; @@ -64,6 +66,17 @@ public class LazyInitProxyFactoryTest extends Assert } }; + private final static IProxyTargetLocator PACKAGE_PRIVATE_CONCRETE_OBJECT_LOCATOR = new IProxyTargetLocator() + { + private static final long serialVersionUID = 1L; + + @Override + public Object locateProxyTarget() + { + return LazyInitProxyFactoryTest.PACKAGE_PRIVATE_CONCRETE_OBJECT; + } + }; + private static IProxyTargetLocator stringObjectLocator = new IProxyTargetLocator() { private static final long serialVersionUID = 1L; @@ -176,6 +189,60 @@ public class LazyInitProxyFactoryTest extends Assert } /** + * Tests lazy init proxy to represent package private concrete objects + * + * https://issues.apache.org/jira/browse/WICKET-4324 + */ + @Test + public void testPackagePrivateConcreteProxy() + { + PackagePrivateConcreteObject proxy = (PackagePrivateConcreteObject)LazyInitProxyFactory.createProxy( + PackagePrivateConcreteObject.class, PACKAGE_PRIVATE_CONCRETE_OBJECT_LOCATOR); + + // test proxy implements ILazyInitProxy + assertThat(proxy, instanceOf(ILazyInitProxy.class)); + assertTrue(((ILazyInitProxy)proxy).getObjectLocator() == PACKAGE_PRIVATE_CONCRETE_OBJECT_LOCATOR); + + // test we do not have a jdk dynamic proxy + assertFalse(Proxy.isProxyClass(proxy.getClass())); + + // test method invocation + assertEquals(proxy.getMessage(), "package-private-concrete"); + + // test serialization + PackagePrivateConcreteObject proxy2 = WicketObjects.cloneObject(proxy); + assertTrue(proxy != proxy2); + assertEquals(proxy2.getMessage(), "package-private-concrete"); + + // test equals/hashcode method interception + final IObjectMethodTester tester = new ObjectMethodTester(); + assertTrue(tester.isValid()); + + // test only a single class is generated, + // otherwise permgen space will fill up with each proxy + assertSame(proxy.getClass(), LazyInitProxyFactory.createProxy( + PackagePrivateConcreteObject.class, PACKAGE_PRIVATE_CONCRETE_OBJECT_LOCATOR).getClass()); + + IProxyTargetLocator testerLocator = new IProxyTargetLocator() + { + private static final long serialVersionUID = 1L; + + @Override + public Object locateProxyTarget() + { + return tester; + } + }; + + ObjectMethodTester testerProxy = (ObjectMethodTester)LazyInitProxyFactory.createProxy( + ObjectMethodTester.class, testerLocator); + testerProxy.equals(this); + testerProxy.hashCode(); + testerProxy.toString(); + assertTrue(tester.isValid()); + } + + /** * Tests lazy init concrete replacement replacement */ @Test http://git-wip-us.apache.org/repos/asf/wicket/blob/27b9a67d/wicket-ioc/src/test/java/org/apache/wicket/proxy/PackagePrivateConcreteObject.java ---------------------------------------------------------------------- diff --git a/wicket-ioc/src/test/java/org/apache/wicket/proxy/PackagePrivateConcreteObject.java b/wicket-ioc/src/test/java/org/apache/wicket/proxy/PackagePrivateConcreteObject.java new file mode 100644 index 0000000..3b31e63 --- /dev/null +++ b/wicket-ioc/src/test/java/org/apache/wicket/proxy/PackagePrivateConcreteObject.java @@ -0,0 +1,54 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.wicket.proxy; + +/** + * Mock dependency that does not implement an interface. + * Its visibility is package private (to {@link LazyInitProxyFactoryTest}) to test a bug + * described at https://issues.apache.org/jira/browse/WICKET-4324 + */ +class PackagePrivateConcreteObject +{ + private String message; + + /** + * Empty default constructor. It is required by cglib to create a proxy. + */ + public PackagePrivateConcreteObject() + { + + } + + /** + * Constructor + * + * @param message + */ + public PackagePrivateConcreteObject(final String message) + { + this.message = message; + } + + /** + * @return message + */ + public String getMessage() + { + return message; + } + +}
