Repository: zest-java Updated Branches: refs/heads/develop afb9409de -> 3e86de34e
ZEST-50 : Implemented a way to allow for custom bytecode generation, but includes a wider mechanism to install a custom AssemblyHelper. This feature is somewhat not supported, as this still all sits in core/runtime until we have some real usecases. Project: http://git-wip-us.apache.org/repos/asf/zest-java/repo Commit: http://git-wip-us.apache.org/repos/asf/zest-java/commit/3e86de34 Tree: http://git-wip-us.apache.org/repos/asf/zest-java/tree/3e86de34 Diff: http://git-wip-us.apache.org/repos/asf/zest-java/diff/3e86de34 Branch: refs/heads/develop Commit: 3e86de34ea82a73e09916f5292d54050f6b45082 Parents: afb9409 Author: Niclas Hedhman <[email protected]> Authored: Thu Apr 21 08:37:18 2016 +0800 Committer: Niclas Hedhman <[email protected]> Committed: Thu Apr 21 08:37:18 2016 +0800 ---------------------------------------------------------------------- core/bootstrap/src/docs/bootstrap.txt | 16 ++++++ .../zest/bootstrap/DocumentationSupport.java | 56 +++++++++++++++++++- .../bootstrap/ApplicationModelFactoryImpl.java | 16 +++++- .../zest/runtime/bootstrap/AssemblyHelper.java | 9 +++- .../runtime/composite/FragmentClassLoader.java | 2 +- .../test/java/org/apache/zest/test/ASMTest.java | 3 +- 6 files changed, 96 insertions(+), 6 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/zest-java/blob/3e86de34/core/bootstrap/src/docs/bootstrap.txt ---------------------------------------------------------------------- diff --git a/core/bootstrap/src/docs/bootstrap.txt b/core/bootstrap/src/docs/bootstrap.txt index 68d5373..7ea2c30 100644 --- a/core/bootstrap/src/docs/bootstrap.txt +++ b/core/bootstrap/src/docs/bootstrap.txt @@ -289,4 +289,20 @@ source=core/bootstrap/src/test/java/org/apache/zest/bootstrap/DocumentationSuppo tag=full -------------- +== Custom AssemblyHelper == +There are rare cases, where a custom AssemblyHelper might be needed. One known use-case is tp introduce an alternative +bytecode generation algorithm, either better than the one we have, or for a different system, such as Dalvik. +To do this, add the +AssemblyHelper+ implementation instance as +metaInfo+ to the +ApplicationAssembly+ + +We think this is so rare, that the +AssemblyHelper+ class will remain in the +core/runtime+ module and has not +been promoted to the +core/bootstrap+ module. If you plan to use this feature, please contact the Zest development +team at [email protected]+ to ensure we can make this a better supported, backed by real usecases. + +Fictitious example of using a hypothetical Dalvik capable classloader; + +[source,java] +-------------- +source=core/bootstrap/src/test/java/org/apache/zest/bootstrap/DocumentationSupport.java +tag=customAssemblyHelper +-------------- http://git-wip-us.apache.org/repos/asf/zest-java/blob/3e86de34/core/bootstrap/src/test/java/org/apache/zest/bootstrap/DocumentationSupport.java ---------------------------------------------------------------------- diff --git a/core/bootstrap/src/test/java/org/apache/zest/bootstrap/DocumentationSupport.java b/core/bootstrap/src/test/java/org/apache/zest/bootstrap/DocumentationSupport.java index 902f2e8..51ead3b 100644 --- a/core/bootstrap/src/test/java/org/apache/zest/bootstrap/DocumentationSupport.java +++ b/core/bootstrap/src/test/java/org/apache/zest/bootstrap/DocumentationSupport.java @@ -28,8 +28,10 @@ import org.apache.zest.api.service.importer.NewObjectImporter; import org.apache.zest.api.structure.Application; import org.apache.zest.api.structure.ApplicationDescriptor; import org.apache.zest.api.structure.Module; -import org.apache.zest.functional.Iterables; +import org.apache.zest.runtime.bootstrap.AssemblyHelper; +import org.apache.zest.runtime.composite.FragmentClassLoader; +@SuppressWarnings( "ALL" ) public class DocumentationSupport { @@ -439,4 +441,56 @@ public class DocumentationSupport } + public static class DalvikAssembly + { + // START SNIPPET: customAssemblyHelper + private static Energy4Java zest; + + private static Application application; + + public static void main( String[] args ) + throws Exception + { + // Create a Zest Runtime + zest = new Energy4Java(); + application = zest.newApplication( new ApplicationAssembler() + { + + @Override + public ApplicationAssembly assemble( ApplicationAssemblyFactory appFactory ) + throws AssemblyException + { + ApplicationAssembly assembly = appFactory.newApplicationAssembly(); + assembly.setMetaInfo( new DalvikAssemblyHelper() ); + // END SNIPPET: customAssemblyHelper + // START SNIPPET: customAssemblyHelper + return assembly; + } + } ); + // activate the application + application.activate(); + } + + + public static class DalvikAssemblyHelper extends AssemblyHelper + { + @Override + protected FragmentClassLoader instantiateFragmentClassLoader( ClassLoader parent ) + { + return new DalvikFragmentClassLoader(parent); + } + } + + public static class DalvikFragmentClassLoader extends FragmentClassLoader + { + + public DalvikFragmentClassLoader( ClassLoader parent ) + { + super( parent ); + } + + } + // END SNIPPET: customAssemblyHelper + } + } http://git-wip-us.apache.org/repos/asf/zest-java/blob/3e86de34/core/runtime/src/main/java/org/apache/zest/runtime/bootstrap/ApplicationModelFactoryImpl.java ---------------------------------------------------------------------- diff --git a/core/runtime/src/main/java/org/apache/zest/runtime/bootstrap/ApplicationModelFactoryImpl.java b/core/runtime/src/main/java/org/apache/zest/runtime/bootstrap/ApplicationModelFactoryImpl.java index 87c9392..ff7bf84 100644 --- a/core/runtime/src/main/java/org/apache/zest/runtime/bootstrap/ApplicationModelFactoryImpl.java +++ b/core/runtime/src/main/java/org/apache/zest/runtime/bootstrap/ApplicationModelFactoryImpl.java @@ -55,7 +55,7 @@ public final class ApplicationModelFactoryImpl public ApplicationDescriptor newApplicationModel( ApplicationAssembly assembly ) throws AssemblyException { - AssemblyHelper helper = new AssemblyHelper(); + AssemblyHelper helper = createAssemblyHelper( assembly ); ApplicationAssemblyImpl applicationAssembly = (ApplicationAssemblyImpl) assembly; ActivatorsModel<Application> applicationActivators = new ActivatorsModel<>( applicationAssembly.activators() ); @@ -121,6 +121,20 @@ public final class ApplicationModelFactoryImpl return applicationModel; } + private AssemblyHelper createAssemblyHelper( ApplicationAssembly assembly ) + { + if( assembly instanceof ApplicationAssemblyImpl ) + { + ApplicationAssemblyImpl impl = (ApplicationAssemblyImpl) assembly; + AssemblyHelper helper = impl.metaInfo().get( AssemblyHelper.class ); + if( helper != null ) + { + return helper; + } + } + return new AssemblyHelper(); + } + private static class BindingVisitor implements HierarchicalVisitor<Object, Object, BindingException> { http://git-wip-us.apache.org/repos/asf/zest-java/blob/3e86de34/core/runtime/src/main/java/org/apache/zest/runtime/bootstrap/AssemblyHelper.java ---------------------------------------------------------------------- diff --git a/core/runtime/src/main/java/org/apache/zest/runtime/bootstrap/AssemblyHelper.java b/core/runtime/src/main/java/org/apache/zest/runtime/bootstrap/AssemblyHelper.java index 2848b41..7615fdf 100644 --- a/core/runtime/src/main/java/org/apache/zest/runtime/bootstrap/AssemblyHelper.java +++ b/core/runtime/src/main/java/org/apache/zest/runtime/bootstrap/AssemblyHelper.java @@ -63,7 +63,7 @@ public class AssemblyHelper return new SideEffectModel( sideEffectClass, instantiationClass( sideEffectClass ) ); } - private Class instantiationClass( Class fragmentClass ) + protected Class instantiationClass( Class fragmentClass ) { Class instantiationClass = fragmentClass; if( !InvocationHandler.class.isAssignableFrom( fragmentClass ) ) @@ -92,12 +92,17 @@ public class AssemblyHelper FragmentClassLoader cl = modifierClassLoaders.get( classLoader ); if( cl == null ) { - cl = new FragmentClassLoader( classLoader ); + cl = instantiateFragmentClassLoader( classLoader ); modifierClassLoaders.put( classLoader, cl ); } return cl; } + protected FragmentClassLoader instantiateFragmentClassLoader( ClassLoader classLoader ) + { + return new FragmentClassLoader( classLoader ); + } + public boolean appliesTo( Class<?> fragmentClass, Method method, Iterable<Class<?>> types, Class<?> mixinClass ) { AppliesToFilter appliesToFilter = appliesToInstances.get( fragmentClass ); http://git-wip-us.apache.org/repos/asf/zest-java/blob/3e86de34/core/runtime/src/main/java/org/apache/zest/runtime/composite/FragmentClassLoader.java ---------------------------------------------------------------------- diff --git a/core/runtime/src/main/java/org/apache/zest/runtime/composite/FragmentClassLoader.java b/core/runtime/src/main/java/org/apache/zest/runtime/composite/FragmentClassLoader.java index 6157259..a5215fc 100644 --- a/core/runtime/src/main/java/org/apache/zest/runtime/composite/FragmentClassLoader.java +++ b/core/runtime/src/main/java/org/apache/zest/runtime/composite/FragmentClassLoader.java @@ -158,7 +158,7 @@ public class FragmentClassLoader return getClass().getClassLoader().loadClass( name ); } - public static byte[] generateClass( String name, Class baseClass ) + public byte[] generateClass( String name, Class baseClass ) throws ClassNotFoundException { String classSlash = name.replace( '.', '/' ); http://git-wip-us.apache.org/repos/asf/zest-java/blob/3e86de34/core/runtime/src/test/java/org/apache/zest/test/ASMTest.java ---------------------------------------------------------------------- diff --git a/core/runtime/src/test/java/org/apache/zest/test/ASMTest.java b/core/runtime/src/test/java/org/apache/zest/test/ASMTest.java index c384f3e..5d4d726 100644 --- a/core/runtime/src/test/java/org/apache/zest/test/ASMTest.java +++ b/core/runtime/src/test/java/org/apache/zest/test/ASMTest.java @@ -153,8 +153,9 @@ public class ASMTest public void fragmentClassLoaderGenerateClassTest() throws Exception { + FragmentClassLoader classLoader = new FragmentClassLoader( getClass().getClassLoader() ); byte[] asm = generateClass(); - byte[] cl = FragmentClassLoader.generateClass( + byte[] cl = classLoader.generateClass( QI256Test.TestTransient.TestTransientMixin.class.getName() + "_Stub", QI256Test.TestTransient.TestTransientMixin.class );
