aries-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Mark Nuttall <mnutt...@apache.org>
Subject Re: svn commit: r1603727 - in /aries/trunk/proxy/proxy-impl/src: main/java/org/apache/aries/proxy/impl/ main/java/org/apache/aries/proxy/impl/gen/ test/java/org/apache/aries/blueprint/proxy/ test/java/org/apache/aries/proxy/test/ test/java/org/apache/aries...
Date Fri, 20 Jun 2014 12:56:52 GMT
Hi Guillaume,
Is it possible that you missed a small change out of this commit?

/org.apache.aries.proxy.impl/src/test/java/org/apache/aries/blueprint/proxy/ProxySubclassGeneratorTest.java
line 279 states,
 synchronized (getClassLoadingLock(name)) {

However the getClassLoadingLock() method does not exist. This is preventing
the test class from compiling, and so breaking the build, as per recent
notes from Jenkins.

Many thanks in advance,
Regards,
Mark



On 19 June 2014 08:01, <gnodet@apache.org> wrote:

> Author: gnodet
> Date: Thu Jun 19 07:01:32 2014
> New Revision: 1603727
>
> URL: http://svn.apache.org/r1603727
> Log:
> [ARIES-1216] Error when creating proxies with an invisible super class in
> the hierarchy
>
> Added:
>     aries/trunk/proxy/proxy-impl/src/test/java/org/apache/aries/proxy/test/
>
> aries/trunk/proxy/proxy-impl/src/test/java/org/apache/aries/proxy/test/a/
>
> aries/trunk/proxy/proxy-impl/src/test/java/org/apache/aries/proxy/test/a/ProxyTestClassA.java
>
> aries/trunk/proxy/proxy-impl/src/test/java/org/apache/aries/proxy/test/b/
>
> aries/trunk/proxy/proxy-impl/src/test/java/org/apache/aries/proxy/test/b/ProxyTestClassB.java
>
> aries/trunk/proxy/proxy-impl/src/test/java/org/apache/aries/proxy/test/c/
>
> aries/trunk/proxy/proxy-impl/src/test/java/org/apache/aries/proxy/test/c/ProxyTestClassC.java
> Modified:
>
> aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/AsmProxyManager.java
>
> aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/gen/ProxySubclassAdapter.java
>
> aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/gen/ProxySubclassGenerator.java
>
> aries/trunk/proxy/proxy-impl/src/test/java/org/apache/aries/blueprint/proxy/ProxySubclassGeneratorTest.java
>
> Modified:
> aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/AsmProxyManager.java
> URL:
> http://svn.apache.org/viewvc/aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/AsmProxyManager.java?rev=1603727&r1=1603726&r2=1603727&view=diff
>
> ==============================================================================
> ---
> aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/AsmProxyManager.java
> (original)
> +++
> aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/AsmProxyManager.java
> Thu Jun 19 07:01:32 2014
> @@ -18,13 +18,19 @@
>   */
>  package org.apache.aries.proxy.impl;
>
> +import java.io.IOException;
>  import java.lang.reflect.Constructor;
>  import java.lang.reflect.InvocationHandler;
>  import java.lang.reflect.Modifier;
>  import java.lang.reflect.Proxy;
> +import java.net.URL;
> +import java.util.ArrayList;
>  import java.util.Collection;
> +import java.util.Enumeration;
>  import java.util.HashSet;
>  import java.util.Iterator;
> +import java.util.List;
> +import java.util.NoSuchElementException;
>  import java.util.Set;
>  import java.util.concurrent.Callable;
>
> @@ -100,13 +106,100 @@ public final class AsmProxyManager exten
>          }
>        }
>        if(proxyObject == null){
> -        proxyObject =
> ProxySubclassGenerator.newProxySubclassInstance(classToProxy, new
> ProxyHandler(this, dispatcher, listener));
> +        // ARIES-1216 : in some cases, some class can not be visible from
> the root class classloader.
> +        // If that's the case, we need to build a custom classloader that
> has visibility on all those classes
> +        // If we could generate a proper constructor this would not be
> necessary, but since we have to rely
> +        // on the generated serialization constructor to bypass the JVM
> verifier, we don't have much choice
> +        ClassLoader classLoader = classToProxy.getClassLoader();
> +        boolean allVisible = true;
> +        for (Class<?> clazz : classes) {
> +          try {
> +            if (classLoader.loadClass(clazz.getName()) != clazz) {
> +              throw new UnableToProxyException(classToProxy, "The
> requested class " + clazz + " is different from the one seen by by " +
> classToProxy);
> +            }
> +          } catch (ClassNotFoundException e) {
> +            allVisible = false;
> +            break;
> +          }
> +        }
> +        if (!allVisible) {
> +          List<ClassLoader> classLoaders = new ArrayList<ClassLoader>();
> +          for (Class<?> clazz : classes) {
> +            ClassLoader cl = clazz.getClassLoader();
> +            if (cl != null && !classLoaders.contains(cl)) {
> +              classLoaders.add(cl);
> +            }
> +          }
> +          classLoader = new MultiClassLoader(classLoaders);
> +        }
> +        proxyObject =
> ProxySubclassGenerator.newProxySubclassInstance(classToProxy, classLoader,
> new ProxyHandler(this, dispatcher, listener));
>        }
>      }
>
>      return proxyObject;
>    }
>
> +  private static class MultiClassLoader extends ClassLoader {
> +    private final List<ClassLoader> parents;
> +    private MultiClassLoader(List<ClassLoader> parents) {
> +      this.parents = parents;
> +    }
> +
> +    @Override
> +    public Class<?> loadClass(String name, boolean resolve) throws
> ClassNotFoundException {
> +      for (ClassLoader cl : parents) {
> +         try {
> +           return cl.loadClass(name);
> +         } catch (ClassNotFoundException e) {
> +           // Ignore
> +         }
> +        }
> +        throw new ClassNotFoundException(name);
> +    }
> +
> +    @Override
> +    public URL getResource(String name) {
> +      for (ClassLoader cl : parents) {
> +         URL url = cl.getResource(name);
> +         if (url != null) {
> +           return url;
> +         }
> +       }
> +       return null;
> +    }
> +
> +    @Override
> +    public Enumeration<URL> getResources(String name) throws IOException {
> +      final List<Enumeration<URL>> tmp = new
> ArrayList<Enumeration<URL>>();
> +      for (ClassLoader cl : parents) {
> +        tmp.add(cl.getResources(name));
> +      }
> +      return new Enumeration<URL>() {
> +        int index = 0;
> +        @Override
> +        public boolean hasMoreElements() {
> +          return next();
> +        }
> +        @Override
> +        public URL nextElement() {
> +          if (!next()) {
> +            throw new NoSuchElementException();
> +          }
> +          return tmp.get(index).nextElement();
> +        }
> +        private boolean next() {
> +          while (index < tmp.size()) {
> +            if (tmp.get(index) != null &&
> tmp.get(index).hasMoreElements()) {
> +              return true;
> +            }
> +            index++;
> +          }
> +          return false;
> +        }
> +      };
> +    }
> +  }
> +
>    private Class<?> getLowestSubclass(Set<Class<?>> notInterfaces)
throws
>         UnableToProxyException {
>
>
> Modified:
> aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/gen/ProxySubclassAdapter.java
> URL:
> http://svn.apache.org/viewvc/aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/gen/ProxySubclassAdapter.java?rev=1603727&r1=1603726&r2=1603727&view=diff
>
> ==============================================================================
> ---
> aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/gen/ProxySubclassAdapter.java
> (original)
> +++
> aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/gen/ProxySubclassAdapter.java
> Thu Jun 19 07:01:32 2014
> @@ -271,6 +271,10 @@ public class ProxySubclassAdapter extend
>          // read the current class and use a
>          // ProxySubclassHierarchyAdapter
>          // to process only methods on that class that are in the list
> +        ClassLoader loader = currentlyAnalysedClass.getClassLoader();
> +        if (loader == null) {
> +          loader = this.loader;
> +        }
>          ClassReader cr = new
> ClassReader(loader.getResourceAsStream(currentlyAnalysedClass
>              .getName().replaceAll("\\.", "/")
>              + ".class"));
>
> Modified:
> aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/gen/ProxySubclassGenerator.java
> URL:
> http://svn.apache.org/viewvc/aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/gen/ProxySubclassGenerator.java?rev=1603727&r1=1603726&r2=1603727&view=diff
>
> ==============================================================================
> ---
> aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/gen/ProxySubclassGenerator.java
> (original)
> +++
> aries/trunk/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/gen/ProxySubclassGenerator.java
> Thu Jun 19 07:01:32 2014
> @@ -72,9 +72,13 @@ public class ProxySubclassGenerator
>
>    public static Class<?> getProxySubclass(Class<?> aClass) throws
> UnableToProxyException
>    {
> +    return getProxySubclass(aClass, aClass.getClassLoader());
> +  }
> +
> +  public static Class<?> getProxySubclass(Class<?> aClass, ClassLoader
> loader) throws UnableToProxyException
> +  {
>      LOGGER.debug(Constants.LOG_ENTRY, "getProxySubclass", new Object[] {
> aClass });
>
> -    ClassLoader loader = aClass.getClassLoader();
>      // in the special case where the loader is null we use a default
> classloader
>      // this is for subclassing java.* or javax.* packages, so that one
> will do
>      if (loader == null) loader = defaultClassLoader;
> @@ -152,13 +156,19 @@ public class ProxySubclassGenerator
>    public static Object newProxySubclassInstance(Class<?> classToProxy,
> InvocationHandler ih)
>        throws UnableToProxyException
>    {
> +    return newProxySubclassInstance(classToProxy,
> classToProxy.getClassLoader(), ih);
> +  }
> +
> +  public static Object newProxySubclassInstance(Class<?> classToProxy,
> ClassLoader loader, InvocationHandler ih)
> +      throws UnableToProxyException
> +  {
>
>      LOGGER.debug(Constants.LOG_ENTRY, "newProxySubclassInstance", new
> Object[] {
> -        classToProxy, ih });
> +        classToProxy, loader, ih });
>
>      Object proxySubclassInstance = null;
>      try {
> -      Class<?> generatedProxySubclass = getProxySubclass(classToProxy);
> +      Class<?> generatedProxySubclass = getProxySubclass(classToProxy,
> loader);
>        LOGGER.debug("Getting the proxy subclass constructor");
>        // Because the newer JVMs throw a VerifyError if a class attempts
> to in a constructor other than their superclasses constructor,
>        // and because we can't know what objects/values we need to pass
> into the class being proxied constructor,
>
> Modified:
> aries/trunk/proxy/proxy-impl/src/test/java/org/apache/aries/blueprint/proxy/ProxySubclassGeneratorTest.java
> URL:
> http://svn.apache.org/viewvc/aries/trunk/proxy/proxy-impl/src/test/java/org/apache/aries/blueprint/proxy/ProxySubclassGeneratorTest.java?rev=1603727&r1=1603726&r2=1603727&view=diff
>
> ==============================================================================
> ---
> aries/trunk/proxy/proxy-impl/src/test/java/org/apache/aries/blueprint/proxy/ProxySubclassGeneratorTest.java
> (original)
> +++
> aries/trunk/proxy/proxy-impl/src/test/java/org/apache/aries/blueprint/proxy/ProxySubclassGeneratorTest.java
> Thu Jun 19 07:01:32 2014
> @@ -23,12 +23,18 @@ import static org.junit.Assert.assertFal
>  import static org.junit.Assert.assertNotNull;
>  import static org.junit.Assert.assertTrue;
>
> +import java.io.ByteArrayOutputStream;
> +import java.io.IOException;
> +import java.io.InputStream;
>  import java.lang.reflect.InvocationHandler;
>  import java.lang.reflect.InvocationTargetException;
>  import java.lang.reflect.Method;
>  import java.lang.reflect.Modifier;
>  import java.util.ArrayList;
> +import java.util.Arrays;
> +import java.util.Collections;
>  import java.util.List;
> +import java.util.Set;
>  import java.util.concurrent.Callable;
>
>  import org.apache.aries.proxy.FinalModifierException;
> @@ -40,6 +46,7 @@ import org.apache.aries.proxy.impl.Proxy
>  import org.apache.aries.proxy.impl.SingleInstanceDispatcher;
>  import org.apache.aries.proxy.impl.gen.ProxySubclassGenerator;
>  import org.apache.aries.proxy.impl.gen.ProxySubclassMethodHashSet;
> +import org.apache.aries.util.io.IOUtils;
>  import org.junit.Before;
>  import org.junit.Test;
>
> @@ -236,6 +243,86 @@ public class ProxySubclassGeneratorTest
>      ((FakeInvocationHandler)ih).setDelegate(GENERIC_CLASS.newInstance());
>      super.testGenerics();
>    }
> +
> +  @Test
> +  public void testClassLoaders() throws Exception {
> +    ClassLoader clA = new
> LimitedClassLoader("org.apache.aries.proxy.test.a", null, null);
> +    ClassLoader clB = new
> LimitedClassLoader("org.apache.aries.proxy.test.b",
> "org.apache.aries.proxy.test.a", clA);
> +    ClassLoader clC = new
> LimitedClassLoader("org.apache.aries.proxy.test.c",
> "org.apache.aries.proxy.test.b", clB);
> +
> +    Class<?> clazzA =
> clA.loadClass("org.apache.aries.proxy.test.a.ProxyTestClassA");
> +    Class<?> clazzB =
> clB.loadClass("org.apache.aries.proxy.test.b.ProxyTestClassB");
> +    Class<?> clazzC =
> clC.loadClass("org.apache.aries.proxy.test.c.ProxyTestClassC");
> +
> +    final Object object =
> clazzC.getConstructor(String.class).newInstance("hello");
> +
> +    o = new AsmProxyManager().createNewProxy(null, Arrays.asList(clazzA,
> clazzB, clazzC), constantly(object), null);
> +    generatedProxySubclass = o.getClass();
> +    Method m = generatedProxySubclass.getDeclaredMethod("hello", new
> Class[] {});
> +    Object returned = m.invoke(o);
> +    assertEquals("hello", returned);
> +  }
> +
> +  private static class LimitedClassLoader extends ClassLoader {
> +    Set<String> providedPackages;
> +    Set<String> importedPackages;
> +    List<ClassLoader> parents;
> +
> +    public LimitedClassLoader(String provided, String imported,
> ClassLoader parent) {
> +      providedPackages = Collections.singleton(provided);
> +      importedPackages = imported != null ?
> Collections.singleton(imported) : Collections.<String>emptySet();
> +      parents = parent != null ? Collections.singletonList(parent) :
> Collections.<ClassLoader>emptyList();
> +    }
> +
> +    @Override
> +    protected Class<?> loadClass(String name, boolean resolve) throws
> ClassNotFoundException {
> +      synchronized (getClassLoadingLock(name)) {
> +        // First, check if the class has already been loaded
> +        Class<?> c = findLoadedClass(name);
> +        if (c == null) {
> +          String pkg = name.substring(0, name.lastIndexOf('.'));
> +          if (pkg.startsWith("java.") || pkg.startsWith("sun.reflect")) {
> +            return getClass().getClassLoader().loadClass(name);
> +          } else if (providedPackages.contains(pkg)) {
> +            c = findClass(name);
> +          } else if (importedPackages.contains(pkg)) {
> +            for (ClassLoader cl : parents) {
> +              try {
> +                c = cl.loadClass(name);
> +              } catch (ClassNotFoundException e) {
> +                // Ignore
> +              }
> +            }
> +          }
> +        }
> +        if (c == null) {
> +          throw new ClassNotFoundException(name);
> +        }
> +        if (resolve) {
> +          resolveClass(c);
> +        }
> +        return c;
> +      }
> +    }
> +
> +    @Override
> +    protected Class<?> findClass(String name) throws
> ClassNotFoundException {
> +      String pkg = name.substring(0, name.lastIndexOf('.'));
> +      if (getPackage(pkg) == null) {
> +        definePackage(pkg, null, null, null, null, null, null, null);
> +      }
> +      String path = name.replace('.', '/').concat(".class");
> +      InputStream is =
> LimitedClassLoader.class.getClassLoader().getResourceAsStream(path);
> +      ByteArrayOutputStream baos = new ByteArrayOutputStream();
> +      try {
> +        IOUtils.copy(is, baos);
> +      } catch (IOException e) {
> +        throw new ClassNotFoundException(name, e);
> +      }
> +      byte[] buf = baos.toByteArray();
> +      return defineClass(name, buf, 0, buf.length);
> +    }
> +  }
>
>    private Class<?> getGeneratedSubclass() throws Exception
>    {
> @@ -317,4 +404,12 @@ public class ProxySubclassGeneratorTest
>    protected Object getP3() {
>      return new ProxyTestClassGeneral();
>    }
> +
> +  private Callable<Object> constantly(final Object result) {
> +    return new Callable<Object>() {
> +      public Object call() throws Exception {
> +        return result;
> +      }
> +    };
> +  }
>  }
>
> Added:
> aries/trunk/proxy/proxy-impl/src/test/java/org/apache/aries/proxy/test/a/ProxyTestClassA.java
> URL:
> http://svn.apache.org/viewvc/aries/trunk/proxy/proxy-impl/src/test/java/org/apache/aries/proxy/test/a/ProxyTestClassA.java?rev=1603727&view=auto
>
> ==============================================================================
> ---
> aries/trunk/proxy/proxy-impl/src/test/java/org/apache/aries/proxy/test/a/ProxyTestClassA.java
> (added)
> +++
> aries/trunk/proxy/proxy-impl/src/test/java/org/apache/aries/proxy/test/a/ProxyTestClassA.java
> Thu Jun 19 07:01:32 2014
> @@ -0,0 +1,32 @@
> +/*
> + * 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.aries.proxy.test.a;
> +
> +public class ProxyTestClassA {
> +
> +  private final String message;
> +
> +  public ProxyTestClassA(String message) {
> +    this.message = message;
> +  }
> +
> +  public String getMessage() {
> +     return message;
> +  }
> +}
>
> Added:
> aries/trunk/proxy/proxy-impl/src/test/java/org/apache/aries/proxy/test/b/ProxyTestClassB.java
> URL:
> http://svn.apache.org/viewvc/aries/trunk/proxy/proxy-impl/src/test/java/org/apache/aries/proxy/test/b/ProxyTestClassB.java?rev=1603727&view=auto
>
> ==============================================================================
> ---
> aries/trunk/proxy/proxy-impl/src/test/java/org/apache/aries/proxy/test/b/ProxyTestClassB.java
> (added)
> +++
> aries/trunk/proxy/proxy-impl/src/test/java/org/apache/aries/proxy/test/b/ProxyTestClassB.java
> Thu Jun 19 07:01:32 2014
> @@ -0,0 +1,28 @@
> +/*
> + * 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.aries.proxy.test.b;
> +
> +import org.apache.aries.proxy.test.a.ProxyTestClassA;
> +
> +public class ProxyTestClassB extends ProxyTestClassA {
> +
> +  public ProxyTestClassB(String message) {
> +    super(message);
> +  }
> +}
>
> Added:
> aries/trunk/proxy/proxy-impl/src/test/java/org/apache/aries/proxy/test/c/ProxyTestClassC.java
> URL:
> http://svn.apache.org/viewvc/aries/trunk/proxy/proxy-impl/src/test/java/org/apache/aries/proxy/test/c/ProxyTestClassC.java?rev=1603727&view=auto
>
> ==============================================================================
> ---
> aries/trunk/proxy/proxy-impl/src/test/java/org/apache/aries/proxy/test/c/ProxyTestClassC.java
> (added)
> +++
> aries/trunk/proxy/proxy-impl/src/test/java/org/apache/aries/proxy/test/c/ProxyTestClassC.java
> Thu Jun 19 07:01:32 2014
> @@ -0,0 +1,33 @@
> +/*
> + * 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.aries.proxy.test.c;
> +
> +import org.apache.aries.proxy.test.b.ProxyTestClassB;
> +
> +public class ProxyTestClassC extends ProxyTestClassB {
> +
> +  public ProxyTestClassC(String message) {
> +    super(message);
> +  }
> +
> +  public String hello() {
> +    return getMessage();
> +  }
> +
> +}
>
>
>

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message