Search code examples
javaosgivaadinbyte-buddyvaadin-flow

Fix classloading issue with ByteBuddy and Vaadin in OSGi setup


I have issues with Vaadin flow in an OSGi setup and it seems to be related to the way some classes are loaded in the internals, when using Polymer Templates. Here is my issue with some details https://github.com/vaadin/flow/issues/7377.

In TemplateModelProxyHandler:229ff the following code is used to load the Proxy Class

Class<?> proxyType = proxyBuilder

// Handle bean methods (and abstract methods for error handling)
.method(method -> isAccessor(method) || method.isAbstract())
.intercept(MethodDelegation.to(proxyHandler))

// Handle internal $stateNode methods
.defineField("$stateNode", StateNode.class)
.method(method -> "$stateNode".equals(method.getName()))
.intercept(FieldAccessor.ofField("$stateNode"))

// Handle internal $modelType methods
.defineField("$modelType", BeanModelType.class)
.method(method -> "$modelType".equals(method.getName()))
.intercept(FieldAccessor.ofField("$modelType"))

// Create the class
.name(proxyClassName).make()
.load(classLoader, ClassLoadingStrategy.Default.WRAPPER)
.getLoaded();

Here, two Class Loaders are important. First, the OSGi Bundle ClassLoader (classLoader) here. Second, the classloader of the Bundle which contains the class TemplateModelProxyHandler, e.g. TemplateModelProxyHandler.class.getClassLoader(). Is there a way to use both classloaders here? Is there a simple method to achieve that with ByteBuddy?


Solution

  • Have a look into the MultipleParentClassLoader that is shipped with Byte Buddy. It allows you to specify multiple parents to a class loader and define a class within it.