[ 
https://issues.apache.org/jira/browse/ARIES-1447?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15000184#comment-15000184
 ] 

Tuomas Kiviaho commented on ARIES-1447:
---------------------------------------

Here's one manifestation https://hibernate.atlassian.net/browse/HHH-10245 that 
is a problem for the Hibernate team and their javassist class cache based 
{{ClassTransformer}}, but similar problems arise later even when using patched 
hibernate. 

{{WovenClass}} classloader doesn't have dynamic imports yet in place so the 
{{ClassTransformer}} fails when the given bytecode contains references to 
classes that are not yet known by the {{WovenClass}} classloader such as 
Hibernate internals or class references that are only known by the 
{{PersistenceProvider}} classloader (which can differ from Hibernate 
{{ClassTransformer}} classloader).

One way to test this with a mock could be to place class references to bytecode 
that are outside both of the classloader used to initiate the 
{{ClassTransformer}} and the classloader you get from {{WovenClass}}. I'm not 
that familiar neiher with Aries itests nor with bytecode manipulation that I 
could provide you with one based on the above scenario.
 
PS. I'm using a patched version of previous major number to have support for 
bundle fragments etc., but this part of the codebase seems to be still same 
although manual declaration of weaving packages is missing and there instead 
only hardcoded OpenJPA/EclipseLink paths that basically link everything to the 
weaved class. Hibernate seems to be missing completely. The workaround is 
therefore done against an older version where there was still a concept of a 
wrapping transformer.

> JPAWeavingHook transforming with wrong classloader
> --------------------------------------------------
>
>                 Key: ARIES-1447
>                 URL: https://issues.apache.org/jira/browse/ARIES-1447
>             Project: Aries
>          Issue Type: Bug
>          Components: JPA
>    Affects Versions: jpa-2.2.0
>         Environment: jpa 1.0.1
>            Reporter: Tuomas Kiviaho
>
> {{PersistenceUnitInfo}} has a {{getNewTempClassLoader}} which includes both 
> provider and persistence unit classloader. The provider classloader is 
> important when enhancing the class, but now the transformations is only done 
> against persistence unit classloader that doesn't yet have needed the dynamic 
> imports in place.
> As a workaround, I am mimicking the proper approach by using 
> {{TempBundleDelegatingClassLoader}} in my patched version of 
> {{WrappingTransformer}}
> BTW: The {{org.apache.aries.jpa.container.weaving.packages}} (that seems to 
> be completely removed from 2.x???) could be replaced with ASM code that looks 
> for referenced packages before and after transformation and adds the 
> difference to dynamic imports. How I'm adding packages manually because the 
> wildcard approach just doesn't seem right.
> {code:title=org/apache/aries/jpa/container/weaving/impl/WrappingTransformer.java
>  }
> @@ -26,7 +26,9 @@
>  import javax.persistence.spi.ClassTransformer;
>  
>  import org.apache.aries.jpa.container.impl.NLS;
> +import 
> org.apache.aries.jpa.container.unit.impl.TempBundleDelegatingClassLoader;
>  import org.osgi.framework.Bundle;
> +import org.osgi.framework.BundleReference;
>  import org.osgi.framework.Constants;
>  import org.osgi.framework.ServiceReference;
>  import org.osgi.framework.wiring.BundleCapability;
> @@ -35,6 +37,7 @@
>  
>  class WrappingTransformer implements ClassTransformer {
>    private final ClassTransformer delegate;
> +  private final ServiceReference<?> persistenceProvider;
>    private final Collection<String> packageImportsToAdd = new 
> HashSet<String>();
>    
>    public WrappingTransformer(ClassTransformer delegate,
> @@ -48,6 +51,7 @@
>      }
>      
>      this.delegate = delegate;
> +    this.persistenceProvider = persistenceProvider;
>      
>      Object packages = 
> persistenceProvider.getProperty("org.apache.aries.jpa.container.weaving.packages");
>      
> @@ -56,7 +60,7 @@
>          packageImportsToAdd.add(s);
>        }
>      } else {
> -      Bundle provider = persistenceProvider.getBundle();
> +      Bundle provider = persistenceProvider.getBundle(); 
>        String suffix = ";" + Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE + "=" +
>        provider.getSymbolicName() + ";" + Constants.BUNDLE_VERSION_ATTRIBUTE 
>        + "=" + provider.getVersion();
> @@ -70,11 +74,25 @@
>  
>    public WrappingTransformer(ClassTransformer transformer) {
>      delegate = transformer;
> +    persistenceProvider = null;
>    }
>  
>    public byte[] transform(ClassLoader arg0, String arg1, Class<?> arg2,
>        ProtectionDomain arg3, byte[] arg4) throws IllegalClassFormatException 
> {
> -    return delegate.transform(arg0, arg1, arg2, arg3, arg4);
> +    Bundle bundle = this.persistenceProvider.getBundle();
> +    BundleWiring bundleWiring = bundle.adapt(BundleWiring.class);
> +    ClassLoader classLoader = bundleWiring.getClassLoader();
> +    BundleReference bundleReference = (BundleReference) arg0;
> +    bundle = bundleReference.getBundle();
> +    classLoader = new TempBundleDelegatingClassLoader(bundle, classLoader);
> +    Thread thread = Thread.currentThread();
> +    ClassLoader contextClassLoader = thread.getContextClassLoader();
> +    thread.setContextClassLoader(classLoader);
> +    try {
> +      return delegate.transform(classLoader, arg1, arg2, arg3, arg4);
> +    } finally {
> +      thread.setContextClassLoader(contextClassLoader);
> +    }
>    }
>    
>    public Collection<String> getPackagesToAdd() {
> {code}



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to