You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by re...@apache.org on 2020/12/17 01:24:44 UTC

[cxf] 01/03: [cxf-8340] add precompiled class for Graalvm native support (#721)

This is an automated email from the ASF dual-hosted git repository.

reta pushed a commit to branch 3.4.x-fixes
in repository https://gitbox.apache.org/repos/asf/cxf.git

commit 5ec867cd053cb9121f0b5260eff8020bb1aed0b2
Author: olivier dufour <ol...@gmail.com>
AuthorDate: Thu Dec 17 00:36:41 2020 +0100

    [cxf-8340] add precompiled class for Graalvm native support (#721)
    
    CXF-8340: Add precompiled (generated) class loading for Graalvm native support
---
 .../java/org/apache/cxf/common/jaxb/JAXBUtils.java | 432 +------------------
 .../cxf/common/spi/ClassGeneratorClassLoader.java  | 150 +++++++
 .../cxf/common/spi/ClassLoaderProxyService.java    |  58 +++
 .../apache/cxf/common/spi/ClassLoaderService.java  |  26 ++
 .../cxf/common/spi/GeneratedClassClassLoader.java  | 115 +++++
 .../spi/GeneratedClassClassLoaderCapture.java      |  36 ++
 .../common/spi/GeneratedNamespaceClassLoader.java  |  51 +++
 .../cxf/common/spi/NamespaceClassCreator.java      |  32 ++
 .../cxf/common/spi/NamespaceClassGenerator.java    | 451 +++++++++++++++++++
 .../java/org/apache/cxf/common/util/ASMHelper.java | 441 +------------------
 .../org/apache/cxf/common/util/ASMHelperImpl.java  | 274 ++++++++++++
 .../org/apache/cxf/common/util/OpcodesProxy.java   |  94 ++++
 .../org/apache/cxf/common/util/StringUtils.java    |  14 +
 .../main/resources/META-INF/cxf/bus-extensions.txt |   2 +
 .../org/apache/cxf/common/util/ASMHelperTest.java  |  35 +-
 parent/pom.xml                                     |   4 +-
 .../org/apache/cxf/binding/corba/CorbaConduit.java |   4 +-
 .../cxf/binding/corba/CorbaServerConduit.java      |   4 +-
 .../interceptors/CorbaStreamInInterceptor.java     |   3 +-
 .../cxf/binding/corba/utils/CorbaAnyHelper.java    | 270 +-----------
 .../corba/utils/CorbaFixedAnyImplClassCreator.java |  23 +
 .../CorbaFixedAnyImplClassCreatorProxyService.java |  48 +++
 .../corba/utils/CorbaFixedAnyImplClassLoader.java  |  35 ++
 .../corba/utils/CorbaFixedAnyImplGenerator.java    | 276 ++++++++++++
 .../binding/corba/wsdl/WSDLExtensionRegister.java  |   6 +-
 .../main/resources/META-INF/cxf/bus-extensions.txt |   1 +
 .../apache/cxf/binding/corba/CorbaConduitTest.java |   7 +
 .../cxf/binding/corba/CorbaServerConduitTest.java  |   4 +
 .../binding/xml/wsdl11/XMLWSDLExtensionLoader.java |   9 +-
 .../cxf/binding/xml/interceptor/TestBase.java      |   3 +-
 .../org/apache/cxf/jaxb/FactoryClassCreator.java   |  24 ++
 .../org/apache/cxf/jaxb/FactoryClassGenerator.java |  86 ++++
 .../org/apache/cxf/jaxb/FactoryClassLoader.java    |  40 ++
 .../apache/cxf/jaxb/FactoryClassProxyService.java  |  48 +++
 .../apache/cxf/jaxb/JAXBContextInitializer.java    |  62 +--
 .../java/org/apache/cxf/jaxb/JAXBDataBinding.java  |  31 +-
 .../cxf/jaxb/WrapperHelperClassGenerator.java      | 451 +++++++++++++++++++
 .../apache/cxf/jaxb/WrapperHelperClassLoader.java  |  64 +++
 .../org/apache/cxf/jaxb/WrapperHelperCompiler.java | 475 ---------------------
 .../org/apache/cxf/jaxb/WrapperHelperCreator.java  |  31 ++
 .../apache/cxf/jaxb/WrapperHelperProxyService.java |  53 +++
 .../org/apache/cxf/jaxb/io/DataWriterImpl.java     |  11 +-
 .../main/resources/META-INF/cxf/bus-extensions.txt |   2 +
 .../org/apache/cxf/jaxb/JAXBDataBindingTest.java   |  27 +-
 .../apache/cxf/jaxb/JAXBEncoderDecoderTest.java    |   5 +-
 .../java/org/apache/cxf/jaxb/JAXBUtilsTest.java    |   5 +-
 .../cxf/jaxrs/provider/AbstractJAXBProvider.java   |   2 +-
 .../apache/cxf/jaxws/WrapperClassGenerator.java    | 154 ++++---
 .../apache/cxf/jaxws/spi/WrapperClassCreator.java  |  28 ++
 .../jaxws/spi/WrapperClassCreatorProxyService.java |  53 +++
 .../apache/cxf/jaxws/spi/WrapperClassLoader.java   | 119 ++++++
 .../cxf/jaxws/support/JaxWsServiceFactoryBean.java |  10 +-
 .../main/resources/META-INF/cxf/bus-extensions.txt |   1 +
 ...ava => WrapperNamespaceClassGeneratorTest.java} |  67 ++-
 .../org/apache/cxf/jaxws/service/AddNumbers2.java  |  35 ++
 .../apache/cxf/jaxws/service/AddNumbers2Impl.java  |  36 ++
 .../cxf/endpoint/dynamic/DynamicClientFactory.java |   2 +-
 .../endpoint/dynamic/ExceptionClassCreator.java    |  23 +
 .../dynamic/ExceptionClassCreatorProxyService.java |  48 +++
 .../endpoint/dynamic/ExceptionClassGenerator.java  |  95 +++++
 .../cxf/endpoint/dynamic/ExceptionClassLoader.java |  42 ++
 .../cxf/endpoint/dynamic/TypeClassInitializer.java |  70 +--
 .../main/resources/META-INF/cxf/bus-extensions.txt |   1 +
 .../transport/http/HTTPWSDLExtensionLoader.java    |  10 +-
 .../jms/wsdl11/JMSWSDLExtensionLoader.java         |   4 +-
 .../impl/AddressingWSDLExtensionLoader.java        |   5 +-
 .../org/apache/cxf/wsdl/ExtensionClassCreator.java |  25 ++
 .../wsdl/ExtensionClassCreatorProxyService.java    |  50 +++
 .../apache/cxf/wsdl/ExtensionClassGenerator.java   | 294 +++++++++++++
 .../org/apache/cxf/wsdl/ExtensionClassLoader.java  |  43 ++
 .../org/apache/cxf/wsdl/JAXBExtensionHelper.java   | 295 +------------
 .../main/resources/META-INF/cxf/bus-extensions.txt |   2 +-
 .../apache/cxf/wsdl/JAXBExtensionHelperTest.java   |  67 +--
 .../cxf/systest/jaxws/ClientServerMiscTest.java    |  13 +-
 74 files changed, 3782 insertions(+), 2135 deletions(-)

diff --git a/core/src/main/java/org/apache/cxf/common/jaxb/JAXBUtils.java b/core/src/main/java/org/apache/cxf/common/jaxb/JAXBUtils.java
index ebaefee..920b096 100644
--- a/core/src/main/java/org/apache/cxf/common/jaxb/JAXBUtils.java
+++ b/core/src/main/java/org/apache/cxf/common/jaxb/JAXBUtils.java
@@ -76,14 +76,10 @@ import org.w3c.dom.Node;
 import org.xml.sax.EntityResolver;
 import org.xml.sax.InputSource;
 
+import org.apache.cxf.Bus;
 import org.apache.cxf.common.classloader.ClassLoaderUtils;
 import org.apache.cxf.common.logging.LogUtils;
-import org.apache.cxf.common.util.ASMHelper;
-import org.apache.cxf.common.util.ASMHelper.ClassWriter;
-import org.apache.cxf.common.util.ASMHelper.FieldVisitor;
-import org.apache.cxf.common.util.ASMHelper.Label;
-import org.apache.cxf.common.util.ASMHelper.MethodVisitor;
-import org.apache.cxf.common.util.ASMHelper.Opcodes;
+import org.apache.cxf.common.spi.ClassLoaderService;
 import org.apache.cxf.common.util.CachedClass;
 import org.apache.cxf.common.util.PackageUtils;
 import org.apache.cxf.common.util.ProxyHelper;
@@ -619,9 +615,10 @@ public final class JAXBUtils {
         return jaxbXjcLoader;
     }
 
-    public static Object setNamespaceMapper(final Map<String, String> nspref,
-                                           Marshaller marshaller) throws PropertyException {
-        Object mapper = createNamespaceWrapper(marshaller.getClass(), nspref);
+    public static Object setNamespaceMapper(Bus bus, final Map<String, String> nspref,
+                                            Marshaller marshaller) throws PropertyException {
+        ClassLoaderService classLoaderService = bus.getExtension(ClassLoaderService.class);
+        Object mapper = classLoaderService.createNamespaceWrapperInstance(marshaller.getClass(), nspref);
         if (mapper != null) {
             if (marshaller.getClass().getName().contains(".internal.")) {
                 marshaller.setProperty("com.sun.xml.internal.bind.namespacePrefixMapper",
@@ -1081,423 +1078,6 @@ public final class JAXBUtils {
         return false;
     }
 
-    private static synchronized Object createNamespaceWrapper(Class<?> mcls, Map<String, String> map) {
-        String postFix = "";
-        if (mcls.getName().contains("eclipse")) {
-            return createEclipseNamespaceMapper(mcls, map);
-        } else if (mcls.getName().contains(".internal")) {
-            postFix = "Internal";
-        } else if (mcls.getName().contains("com.sun")) {
-            postFix = "RI";
-        }
-        ASMHelper helper = new ASMHelper();
-        String className = "org.apache.cxf.jaxb.NamespaceMapper";
-        className += postFix;
-        Class<?> cls = helper.findClass(className, JAXBUtils.class);
-        Throwable t = null;
-        if (cls == null) {
-            try {
-                ClassWriter cw = helper.createClassWriter();
-                if (cw != null) {
-                    cls = createNamespaceWrapperInternal(helper, cw, postFix, mcls);
-                }
-            } catch (RuntimeException ex) {
-                // continue
-                t = ex;
-            }
-        }
-        if (cls == null
-            && (!mcls.getName().contains(".internal.") && mcls.getName().contains("com.sun"))) {
-            try {
-                cls = ClassLoaderUtils.loadClass("org.apache.cxf.common.jaxb.NamespaceMapper",
-                                                 JAXBUtils.class);
-            } catch (Throwable ex2) {
-                // ignore
-                t = ex2;
-            }
-        }
-        if (cls != null) {
-            try {
-                return cls.getConstructor(Map.class).newInstance(map);
-            } catch (Exception e) {
-                // ignore
-                t = e;
-            }
-        }
-        LOG.log(Level.INFO, "Could not create a NamespaceMapper compatible with Marshaller class " + mcls.getName(), t);
-        return null;
-    }
-    /*
-    // This is the "prototype" for the ASM generated class below
-    public static class MapNamespacePrefixMapper2
-        extends org.eclipse.persistence.internal.oxm.record.namespaces.MapNamespacePrefixMapper {
-
-        String[] nsctxt;
-
-        public MapNamespacePrefixMapper2(Map<String, String> foo) {
-            super(foo);
-        }
-        public String[] getPreDeclaredNamespaceUris() {
-            String[] sup = super.getPreDeclaredNamespaceUris();
-            if (nsctxt == null) {
-                return sup;
-            }
-            List<String> s = new ArrayList<>(Arrays.asList(sup));
-            for (int x = 1; x < nsctxt.length; x = x + 2) {
-                s.remove(nsctxt[x]);
-            }
-            return s.toArray(new String[s.size()]);
-        }
-        public void setContextualNamespaceDecls(String[] f) {
-            nsctxt = f;
-        }
-        public String[] getContextualNamespaceDecls() {
-            return nsctxt;
-        }
-    }
-    */
-    //CHECKSTYLE:OFF
-    //bunch of really long ASM based methods that cannot be shortened easily
-    private static Object createEclipseNamespaceMapper(Class<?> mcls, Map<String, String> map) {
-        ASMHelper helper = new ASMHelper();
-        String className = "org.apache.cxf.jaxb.EclipseNamespaceMapper";
-        String slashedName = "org/apache/cxf/jaxb/EclipseNamespaceMapper";
-        Class<?> cls = helper.findClass(className, JAXBUtils.class);
-
-        if (cls == null) {
-            ClassWriter cw = helper.createClassWriter();
-            if (cw == null) {
-                return null;
-            }
-            String superName = "org/eclipse/persistence/internal/oxm/record/namespaces/MapNamespacePrefixMapper";
-            FieldVisitor fv;
-            MethodVisitor mv;
-            cw.visit(Opcodes.V1_6,
-                     Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL + Opcodes.ACC_SUPER,
-                     slashedName, null,
-                     superName, null);
-
-            cw.visitSource("EclipseNamespaceMapper.java", null);
-
-            fv = cw.visitField(Opcodes.ACC_PRIVATE, "nsctxt", "[Ljava/lang/String;", null, null);
-            fv.visitEnd();
-
-
-            mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "(Ljava/util/Map;)V",
-                                "(Ljava/util/Map<Ljava/lang/String;Ljava/lang/String;>;)V", null);
-            mv.visitCode();
-            Label l0 = helper.createLabel();
-            mv.visitLabel(l0);
-            mv.visitVarInsn(Opcodes.ALOAD, 0);
-            mv.visitVarInsn(Opcodes.ALOAD, 1);
-            mv.visitMethodInsn(Opcodes.INVOKESPECIAL,
-                               superName, "<init>", "(Ljava/util/Map;)V", false);
-            Label l1 = helper.createLabel();
-            mv.visitLabel(l1);
-            mv.visitInsn(Opcodes.RETURN);
-            Label l2 = helper.createLabel();
-            mv.visitLabel(l2);
-            mv.visitMaxs(2, 2);
-            mv.visitEnd();
-
-
-            mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "setContextualNamespaceDecls", "([Ljava/lang/String;)V",
-                                null, null);
-            mv.visitCode();
-            l0 = helper.createLabel();
-            mv.visitLabel(l0);
-            mv.visitLineNumber(47, l0);
-            mv.visitVarInsn(Opcodes.ALOAD, 0);
-            mv.visitVarInsn(Opcodes.ALOAD, 1);
-            mv.visitFieldInsn(Opcodes.PUTFIELD, slashedName, "nsctxt", "[Ljava/lang/String;");
-            l1 = helper.createLabel();
-            mv.visitLabel(l1);
-            mv.visitLineNumber(48, l1);
-            mv.visitInsn(Opcodes.RETURN);
-            l2 = helper.createLabel();
-            mv.visitLabel(l2);
-            mv.visitLocalVariable("this", "L" + slashedName + ";", null, l0, l2, 0);
-            mv.visitLocalVariable("contextualNamespaceDecls", "[Ljava/lang/String;", null, l0, l2, 1);
-            mv.visitMaxs(2, 2);
-            mv.visitEnd();
-
-            mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "getContextualNamespaceDecls", "()[Ljava/lang/String;", null, null);
-            mv.visitCode();
-            l0 = helper.createLabel();
-            mv.visitLabel(l0);
-            mv.visitLineNumber(51, l0);
-            mv.visitVarInsn(Opcodes.ALOAD, 0);
-            mv.visitFieldInsn(Opcodes.GETFIELD, slashedName, "nsctxt", "[Ljava/lang/String;");
-            mv.visitInsn(Opcodes.ARETURN);
-            l1 = helper.createLabel();
-
-            mv.visitLabel(l1);
-            mv.visitLocalVariable("this", "L" + slashedName + ";", null, l0, l1, 0);
-
-            mv.visitMaxs(1, 1);
-            mv.visitEnd();
-
-
-            mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "getPreDeclaredNamespaceUris", "()[Ljava/lang/String;", null, null);
-            mv.visitCode();
-            l0 = helper.createLabel();
-            mv.visitLabel(l0);
-            mv.visitLineNumber(1036, l0);
-            mv.visitVarInsn(Opcodes.ALOAD, 0);
-            mv.visitMethodInsn(Opcodes.INVOKESPECIAL,
-                               superName,
-                               "getPreDeclaredNamespaceUris", "()[Ljava/lang/String;", false);
-            mv.visitVarInsn(Opcodes.ASTORE, 1);
-            l1 = helper.createLabel();
-            mv.visitLabel(l1);
-            mv.visitLineNumber(1037, l1);
-            mv.visitVarInsn(Opcodes.ALOAD, 0);
-            mv.visitFieldInsn(Opcodes.GETFIELD, slashedName, "nsctxt", "[Ljava/lang/String;");
-            l2 = helper.createLabel();
-            mv.visitJumpInsn(Opcodes.IFNONNULL, l2);
-            Label l3 = helper.createLabel();
-            mv.visitLabel(l3);
-            mv.visitLineNumber(1038, l3);
-            mv.visitVarInsn(Opcodes.ALOAD, 1);
-            mv.visitInsn(Opcodes.ARETURN);
-            mv.visitLabel(l2);
-            mv.visitLineNumber(1040, l2);
-            mv.visitFrame(Opcodes.F_APPEND, 1, new Object[] {"[Ljava/lang/String;"}, 0, null);
-            mv.visitTypeInsn(Opcodes.NEW, "java/util/ArrayList");
-            mv.visitInsn(Opcodes.DUP);
-            mv.visitVarInsn(Opcodes.ALOAD, 1);
-            mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/util/Arrays", "asList",
-                               "([Ljava/lang/Object;)Ljava/util/List;", false);
-            mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/util/ArrayList", "<init>",
-                               "(Ljava/util/Collection;)V", false);
-            mv.visitVarInsn(Opcodes.ASTORE, 2);
-            Label l4 = helper.createLabel();
-            mv.visitLabel(l4);
-            mv.visitLineNumber(1041, l4);
-            mv.visitInsn(Opcodes.ICONST_1);
-            mv.visitVarInsn(Opcodes.ISTORE, 3);
-            Label l5 = helper.createLabel();
-            mv.visitLabel(l5);
-            Label l6 = helper.createLabel();
-            mv.visitJumpInsn(Opcodes.GOTO, l6);
-            Label l7 = helper.createLabel();
-            mv.visitLabel(l7);
-            mv.visitLineNumber(1042, l7);
-            mv.visitFrame(Opcodes.F_APPEND, 2, new Object[] {"java/util/List", Opcodes.INTEGER}, 0, null);
-            mv.visitVarInsn(Opcodes.ALOAD, 2);
-            mv.visitVarInsn(Opcodes.ALOAD, 0);
-            mv.visitFieldInsn(Opcodes.GETFIELD, slashedName, "nsctxt", "[Ljava/lang/String;");
-            mv.visitVarInsn(Opcodes.ILOAD, 3);
-            mv.visitInsn(Opcodes.AALOAD);
-            mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/List", "remove", "(Ljava/lang/Object;)Z", true);
-            mv.visitInsn(Opcodes.POP);
-            Label l8 = helper.createLabel();
-            mv.visitLabel(l8);
-            mv.visitLineNumber(1041, l8);
-            mv.visitIincInsn(3, 2);
-            mv.visitLabel(l6);
-            mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
-            mv.visitVarInsn(Opcodes.ILOAD, 3);
-            mv.visitVarInsn(Opcodes.ALOAD, 0);
-            mv.visitFieldInsn(Opcodes.GETFIELD,
-                              slashedName,
-                              "nsctxt", "[Ljava/lang/String;");
-            mv.visitInsn(Opcodes.ARRAYLENGTH);
-            mv.visitJumpInsn(Opcodes.IF_ICMPLT, l7);
-            Label l9 = helper.createLabel();
-            mv.visitLabel(l9);
-            mv.visitLineNumber(1044, l9);
-            mv.visitVarInsn(Opcodes.ALOAD, 2);
-            mv.visitVarInsn(Opcodes.ALOAD, 2);
-            mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/List", "size", "()I", true);
-            mv.visitTypeInsn(Opcodes.ANEWARRAY, "java/lang/String");
-            mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/List",
-                               "toArray", "([Ljava/lang/Object;)[Ljava/lang/Object;", true);
-            mv.visitTypeInsn(Opcodes.CHECKCAST, "[Ljava/lang/String;");
-            mv.visitInsn(Opcodes.ARETURN);
-            Label l10 = helper.createLabel();
-            mv.visitLabel(l10);
-            mv.visitLocalVariable("this", "L" + slashedName + ";",
-                                  null, l0, l10, 0);
-            mv.visitLocalVariable("sup", "[Ljava/lang/String;", null, l1, l10, 1);
-            mv.visitLocalVariable("s", "Ljava/util/List;", "Ljava/util/List<Ljava/lang/String;>;", l4, l10, 2);
-            mv.visitLocalVariable("x", "I", null, l5, l9, 3);
-            mv.visitMaxs(3, 4);
-            mv.visitEnd();
-
-            cw.visitEnd();
-
-            byte[] bts = cw.toByteArray();
-            cls = helper.loadClass(className,
-                                   mcls, bts);
-        }
-        try {
-            return cls.getConstructor(Map.class).newInstance(map);
-        } catch (Throwable e) {
-            e.printStackTrace();
-            return null;
-        }
-    }
-
-    private static Class<?> createNamespaceWrapperInternal(ASMHelper helper, ClassWriter cw,
-                                                           String postFix, Class<?> ref) {
-        String className = "org.apache.cxf.jaxb.NamespaceMapper" + postFix;
-        String superName = "com/sun/xml/"
-            + ("RI".equals(postFix) ? "" : "internal/")
-            + "bind/marshaller/NamespacePrefixMapper";
-        String postFixedName = "org/apache/cxf/jaxb/NamespaceMapper" + postFix;
-
-        FieldVisitor fv;
-        MethodVisitor mv;
-
-        cw.visit(Opcodes.V1_6,
-                 Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL + Opcodes.ACC_SUPER,
-                 postFixedName, null,
-                 superName, null);
-
-        cw.visitSource("NamespaceMapper.java", null);
-
-        fv = cw.visitField(Opcodes.ACC_PRIVATE + Opcodes.ACC_FINAL,
-                           "nspref", "Ljava/util/Map;",
-                           "Ljava/util/Map<Ljava/lang/String;Ljava/lang/String;>;", null);
-        fv.visitEnd();
-
-        fv = cw.visitField(Opcodes.ACC_PRIVATE, "nsctxt", "[Ljava/lang/String;", null, null);
-        fv.visitEnd();
-
-        fv = cw.visitField(Opcodes.ACC_PRIVATE + Opcodes.ACC_FINAL + Opcodes.ACC_STATIC,
-                           "EMPTY_STRING", "[Ljava/lang/String;", null, null);
-        fv.visitEnd();
-
-        mv = cw.visitMethod(Opcodes.ACC_STATIC, "<clinit>", "()V", null, null);
-        mv.visitCode();
-        Label l0 = helper.createLabel();
-        mv.visitLabel(l0);
-        mv.visitLineNumber(30, l0);
-        mv.visitInsn(Opcodes.ICONST_0);
-        mv.visitTypeInsn(Opcodes.ANEWARRAY, "java/lang/String");
-        mv.visitFieldInsn(Opcodes.PUTSTATIC, postFixedName, "EMPTY_STRING", "[Ljava/lang/String;");
-        mv.visitInsn(Opcodes.RETURN);
-        mv.visitMaxs(1, 0);
-        mv.visitEnd();
-
-        mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>",
-                            "(Ljava/util/Map;)V",
-                            "(Ljava/util/Map<Ljava/lang/String;Ljava/lang/String;>;)V", null);
-        mv.visitCode();
-        l0 = helper.createLabel();
-        mv.visitLabel(l0);
-        mv.visitLineNumber(32, l0);
-        mv.visitVarInsn(Opcodes.ALOAD, 0);
-        mv.visitMethodInsn(Opcodes.INVOKESPECIAL, superName, "<init>", "()V", false);
-        Label l1 = helper.createLabel();
-        mv.visitLabel(l1);
-        mv.visitLineNumber(29, l1);
-        mv.visitVarInsn(Opcodes.ALOAD, 0);
-        mv.visitFieldInsn(Opcodes.GETSTATIC, postFixedName, "EMPTY_STRING", "[Ljava/lang/String;");
-        mv.visitFieldInsn(Opcodes.PUTFIELD, postFixedName, "nsctxt", "[Ljava/lang/String;");
-        Label l2 = helper.createLabel();
-        mv.visitLabel(l2);
-        mv.visitLineNumber(33, l2);
-        mv.visitVarInsn(Opcodes.ALOAD, 0);
-        mv.visitVarInsn(Opcodes.ALOAD, 1);
-        mv.visitFieldInsn(Opcodes.PUTFIELD, postFixedName, "nspref", "Ljava/util/Map;");
-        Label l3 = helper.createLabel();
-        mv.visitLabel(l3);
-        mv.visitLineNumber(34, l3);
-        mv.visitInsn(Opcodes.RETURN);
-        Label l4 = helper.createLabel();
-        mv.visitLabel(l4);
-        mv.visitLocalVariable("this", "L" + postFixedName + ";", null, l0, l4, 0);
-        mv.visitLocalVariable("nspref",
-                              "Ljava/util/Map;", "Ljava/util/Map<Ljava/lang/String;Ljava/lang/String;>;",
-                              l0, l4, 1);
-        mv.visitMaxs(2, 2);
-        mv.visitEnd();
-
-        mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "getPreferredPrefix",
-                            "(Ljava/lang/String;Ljava/lang/String;Z)Ljava/lang/String;",
-                            null, null);
-        mv.visitCode();
-        l0 = helper.createLabel();
-        mv.visitLabel(l0);
-        mv.visitLineNumber(39, l0);
-        mv.visitVarInsn(Opcodes.ALOAD, 0);
-        mv.visitFieldInsn(Opcodes.GETFIELD, postFixedName, "nspref", "Ljava/util/Map;");
-        mv.visitVarInsn(Opcodes.ALOAD, 1);
-        mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/Map",
-                           "get", "(Ljava/lang/Object;)Ljava/lang/Object;", true);
-        mv.visitTypeInsn(Opcodes.CHECKCAST, "java/lang/String");
-        mv.visitVarInsn(Opcodes.ASTORE, 4);
-        l1 = helper.createLabel();
-        mv.visitLabel(l1);
-        mv.visitLineNumber(40, l1);
-        mv.visitVarInsn(Opcodes.ALOAD, 4);
-        l2 = helper.createLabel();
-        mv.visitJumpInsn(Opcodes.IFNULL, l2);
-        l3 = helper.createLabel();
-        mv.visitLabel(l3);
-        mv.visitLineNumber(41, l3);
-        mv.visitVarInsn(Opcodes.ALOAD, 4);
-        mv.visitInsn(Opcodes.ARETURN);
-        mv.visitLabel(l2);
-        mv.visitLineNumber(43, l2);
-        mv.visitFrame(Opcodes.F_APPEND, 1, new Object[] {"java/lang/String"}, 0, null);
-        mv.visitVarInsn(Opcodes.ALOAD, 2);
-        mv.visitInsn(Opcodes.ARETURN);
-        l4 = helper.createLabel();
-        mv.visitLabel(l4);
-        mv.visitLocalVariable("this", "L" + postFixedName + ";", null, l0, l4, 0);
-        mv.visitLocalVariable("namespaceUri", "Ljava/lang/String;", null, l0, l4, 1);
-        mv.visitLocalVariable("suggestion", "Ljava/lang/String;", null, l0, l4, 2);
-        mv.visitLocalVariable("requirePrefix", "Z", null, l0, l4, 3);
-        mv.visitLocalVariable("prefix", "Ljava/lang/String;", null, l1, l4, 4);
-        mv.visitMaxs(2, 5);
-        mv.visitEnd();
-
-        mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "setContextualNamespaceDecls", "([Ljava/lang/String;)V", null, null);
-        mv.visitCode();
-        l0 = helper.createLabel();
-        mv.visitLabel(l0);
-        mv.visitLineNumber(47, l0);
-        mv.visitVarInsn(Opcodes.ALOAD, 0);
-        mv.visitVarInsn(Opcodes.ALOAD, 1);
-        mv.visitFieldInsn(Opcodes.PUTFIELD, postFixedName, "nsctxt", "[Ljava/lang/String;");
-        l1 = helper.createLabel();
-        mv.visitLabel(l1);
-        mv.visitLineNumber(48, l1);
-        mv.visitInsn(Opcodes.RETURN);
-        l2 = helper.createLabel();
-        mv.visitLabel(l2);
-        mv.visitLocalVariable("this", "L" + postFixedName + ";", null, l0, l2, 0);
-        mv.visitLocalVariable("contextualNamespaceDecls", "[Ljava/lang/String;", null, l0, l2, 1);
-        mv.visitMaxs(2, 2);
-        mv.visitEnd();
-
-        mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "getContextualNamespaceDecls", "()[Ljava/lang/String;", null, null);
-        mv.visitCode();
-        l0 = helper.createLabel();
-        mv.visitLabel(l0);
-        mv.visitLineNumber(51, l0);
-        mv.visitVarInsn(Opcodes.ALOAD, 0);
-        mv.visitFieldInsn(Opcodes.GETFIELD, postFixedName, "nsctxt", "[Ljava/lang/String;");
-        mv.visitInsn(Opcodes.ARETURN);
-        l1 = helper.createLabel();
-
-        mv.visitLabel(l1);
-        mv.visitLocalVariable("this", "L" + postFixedName + ";", null, l0, l1, 0);
-
-        mv.visitMaxs(1, 1);
-        mv.visitEnd();
-
-        cw.visitEnd();
-
-        byte[] bts = cw.toByteArray();
-        return helper.loadClass(className,
-                                ref, bts);
-    }
-    //CHECKSTYLE:ON
-
     public static JAXBContextProxy createJAXBContextProxy(final JAXBContext ctx) {
         return createJAXBContextProxy(ctx, null, null);
     }
diff --git a/core/src/main/java/org/apache/cxf/common/spi/ClassGeneratorClassLoader.java b/core/src/main/java/org/apache/cxf/common/spi/ClassGeneratorClassLoader.java
new file mode 100644
index 0000000..f7cc719
--- /dev/null
+++ b/core/src/main/java/org/apache/cxf/common/spi/ClassGeneratorClassLoader.java
@@ -0,0 +1,150 @@
+/**
+ * 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.cxf.common.spi;
+
+import java.lang.ref.WeakReference;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.BusFactory;
+import org.apache.cxf.common.util.StringUtils;
+import org.apache.cxf.common.util.WeakIdentityHashMap;
+
+/** Class loader used to store and retrieve class generated during runtime to avoid class generation each time.
+ *  inherited class use asmHelper to generate bytes and use @see #loadClass(String, Class&lt;?&gt;, byte[])
+ *  or @see #loadClass(String, ClassLoader, byte[]) to store generated class.Class can be generated during buildtime.
+ *  equivalent class is @see org.apache.cxf.common.spi.GeneratedClassClassLoader
+ * @author olivier dufour
+ */
+public class ClassGeneratorClassLoader {
+    protected static final Map<Class<?>, WeakReference<TypeHelperClassLoader>> CLASS_MAP
+            = new WeakIdentityHashMap<>();
+    protected static final Map<ClassLoader, WeakReference<TypeHelperClassLoader>> LOADER_MAP
+            = new WeakIdentityHashMap<>();
+    protected final Bus bus;
+
+    public ClassGeneratorClassLoader(final Bus bus) {
+        this.bus = bus == null ? BusFactory.getDefaultBus() : bus;
+    }
+
+    protected Class<?> loadClass(String className, Class<?> cls, byte[] bytes) {
+        GeneratedClassClassLoaderCapture capture = bus.getExtension(GeneratedClassClassLoaderCapture.class);
+        if (capture != null) {
+            capture.capture(className, bytes);
+        }
+        TypeHelperClassLoader loader = getOrCreateLoader(cls);
+        synchronized (loader) {
+            Class<?> clz = loader.lookupDefinedClass(className);
+            if (clz == null) {
+                return loader.defineClass(className, bytes);
+            }
+            return clz;
+        }
+    }
+    protected Class<?> loadClass(String className, ClassLoader l, byte[] bytes) {
+        GeneratedClassClassLoaderCapture capture = bus.getExtension(GeneratedClassClassLoaderCapture.class);
+        if (capture != null) {
+            capture.capture(className, bytes);
+        }
+        TypeHelperClassLoader loader = getOrCreateLoader(l);
+        synchronized (loader) {
+            Class<?> clz = loader.lookupDefinedClass(className);
+            if (clz == null) {
+                return loader.defineClass(className, bytes);
+            }
+            return clz;
+        }
+    }
+    protected Class<?> findClass(String className, Class<?> cls) {
+        return getOrCreateLoader(cls).lookupDefinedClass(className);
+    }
+
+    protected Class<?> findClass(String className, ClassLoader classLoader) {
+        return getOrCreateLoader(classLoader).lookupDefinedClass(className);
+    }
+    private synchronized TypeHelperClassLoader getOrCreateLoader(Class<?> cls) {
+        WeakReference<TypeHelperClassLoader> ref = CLASS_MAP.get(cls);
+        TypeHelperClassLoader ret;
+        if (ref == null || ref.get() == null) {
+            ret = new TypeHelperClassLoader(cls.getClassLoader());
+            CLASS_MAP.put(cls, new WeakReference<TypeHelperClassLoader>(ret));
+        } else {
+            ret = ref.get();
+        }
+        return ret;
+    }
+    private synchronized TypeHelperClassLoader getOrCreateLoader(ClassLoader l) {
+        WeakReference<TypeHelperClassLoader> ref = LOADER_MAP.get(l);
+        TypeHelperClassLoader ret;
+        if (ref == null || ref.get() == null) {
+            ret = new TypeHelperClassLoader(l);
+            LOADER_MAP.put(l, new WeakReference<TypeHelperClassLoader>(ret));
+        } else {
+            ret = ref.get();
+        }
+        return ret;
+    }
+
+    public static class TypeHelperClassLoader extends ClassLoader {
+        ConcurrentHashMap<String, Class<?>> defined = new ConcurrentHashMap<>();
+
+        TypeHelperClassLoader(ClassLoader parent) {
+            super(parent);
+        }
+        public Class<?> lookupDefinedClass(String name) {
+            return defined.get(StringUtils.slashesToPeriod(name));
+        }
+
+        @Override
+        protected Class<?> findClass(String name) throws ClassNotFoundException {
+            if (name.endsWith("package-info")) {
+                return getParent().loadClass(name);
+            }
+            return super.findClass(name);
+        }
+
+        public Class<?> defineClass(String name, byte[] bytes) {
+            Class<?> ret = defined.get(StringUtils.slashesToPeriod(name));
+            if (ret != null) {
+                return ret;
+            }
+            if (name.endsWith("package-info")) {
+                String s = name.substring(0, name.length() - 13);
+                Package p = super.getPackage(s);
+                if (p == null) {
+                    definePackage(StringUtils.slashesToPeriod(s),
+                            null,
+                            null,
+                            null,
+                            null,
+                            null,
+                            null,
+                            null);
+                }
+            }
+
+            ret = defined.computeIfAbsent(StringUtils.slashesToPeriod(name),
+                key -> TypeHelperClassLoader.super.defineClass(key, bytes, 0, bytes.length));
+
+            return ret;
+        }
+    }
+}
diff --git a/core/src/main/java/org/apache/cxf/common/spi/ClassLoaderProxyService.java b/core/src/main/java/org/apache/cxf/common/spi/ClassLoaderProxyService.java
new file mode 100644
index 0000000..aed9922
--- /dev/null
+++ b/core/src/main/java/org/apache/cxf/common/spi/ClassLoaderProxyService.java
@@ -0,0 +1,58 @@
+/**
+ * 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.cxf.common.spi;
+
+import java.util.Map;
+import java.util.logging.Logger;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.common.logging.LogUtils;
+
+public class ClassLoaderProxyService implements ClassLoaderService {
+    private static final Logger LOG = LogUtils.getL7dLogger(ClassLoaderProxyService.class);
+    private final NamespaceClassCreator srv;
+    public ClassLoaderProxyService(Bus bus) {
+        this(new NamespaceClassGenerator(bus));
+    }
+    public ClassLoaderProxyService(NamespaceClassCreator srv) {
+        this.srv = srv;
+    }
+
+    @Override
+    public Object createNamespaceWrapperInstance(Class<?> mcls, Map<String, String> map) {
+        Class<?> cls = srv.createNamespaceWrapperClass(mcls, map);
+        try {
+            return cls.getConstructor(Map.class).newInstance(map);
+        } catch (Throwable e) {
+            LOG.warning("NamespaceWrapper not found : " + e.toString());
+            return null;
+        }
+    }
+    public class LoadFirst extends ClassLoaderProxyService {
+        public LoadFirst(Bus bus) {
+            super(new GeneratedNamespaceClassLoader(bus));
+        }
+    }
+    public class GenerateJustInTime extends ClassLoaderProxyService {
+        public GenerateJustInTime(Bus bus) {
+            super(new NamespaceClassGenerator(bus));
+        }
+    }
+}
diff --git a/core/src/main/java/org/apache/cxf/common/spi/ClassLoaderService.java b/core/src/main/java/org/apache/cxf/common/spi/ClassLoaderService.java
new file mode 100644
index 0000000..1d1bd5c
--- /dev/null
+++ b/core/src/main/java/org/apache/cxf/common/spi/ClassLoaderService.java
@@ -0,0 +1,26 @@
+/**
+ * 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.cxf.common.spi;
+
+import java.util.Map;
+
+public interface ClassLoaderService {
+    Object createNamespaceWrapperInstance(Class<?> mcls, Map<String, String> map);
+}
diff --git a/core/src/main/java/org/apache/cxf/common/spi/GeneratedClassClassLoader.java b/core/src/main/java/org/apache/cxf/common/spi/GeneratedClassClassLoader.java
new file mode 100644
index 0000000..452c5fe
--- /dev/null
+++ b/core/src/main/java/org/apache/cxf/common/spi/GeneratedClassClassLoader.java
@@ -0,0 +1,115 @@
+/**
+ * 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.cxf.common.spi;
+
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.logging.Logger;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.common.classloader.ClassLoaderUtils;
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.common.util.StringUtils;
+
+/** Class loader used to find class generated during build time to avoid class generation during runtime.
+ *  inherited class implement same interface than generator class but find class in TypeHelperClassLoader
+ *  Runtime class generator use @see org.apache.cxf.common.spi.ClassGeneratorClassLoader
+ * @author olivier dufour
+ */
+public class GeneratedClassClassLoader {
+    private static final Logger LOG = LogUtils.getL7dLogger(ClassLoaderProxyService.class);
+    protected final Bus bus;
+
+    public GeneratedClassClassLoader(Bus bus) {
+        this.bus = bus;
+    }
+    protected Class<?> findClass(String className, Class<?> callingClass) {
+        ClassLoader cl = getClassLoader();
+        try {
+            return cl.loadClass(className);
+        } catch (ClassNotFoundException e) {
+            //ignore and try with other class loader
+        }
+        try {
+            return ClassLoaderUtils.loadClass(className, callingClass);
+        } catch (ClassNotFoundException e) {
+            LOG.fine("Failed to load class :" + e.toString());
+        }
+        return null;
+    }
+    public TypeHelperClassLoader getClassLoader() {
+        TypeHelperClassLoader loader = bus.getExtension(TypeHelperClassLoader.class);
+        if (loader == null) {
+            loader = bus.getExtension(TypeHelperClassLoader.class);
+            if (loader == null) {
+                ClassLoader parent = bus.getExtension(ClassLoader.class);
+                if (parent == null) {
+                    parent = Thread.currentThread().getContextClassLoader();
+                }
+                loader = new TypeHelperClassLoader(parent);
+                bus.setExtension(loader, TypeHelperClassLoader.class);
+            }
+        }
+        return loader;
+    }
+
+    public static class TypeHelperClassLoader extends ClassLoader {
+        ConcurrentHashMap<String, Class<?>> defined = new ConcurrentHashMap<>();
+
+        TypeHelperClassLoader(ClassLoader parent) {
+            super(parent);
+        }
+        public Class<?> lookupDefinedClass(String name) {
+            return defined.get(StringUtils.slashesToPeriod(name));
+        }
+
+        @Override
+        protected Class<?> findClass(String name) throws ClassNotFoundException {
+            if (name.endsWith("package-info")) {
+                return getParent().loadClass(name);
+            }
+            return super.findClass(name);
+        }
+
+        public Class<?> defineClass(String name, byte[] bytes) {
+            Class<?> ret = defined.get(StringUtils.slashesToPeriod(name));
+            if (ret != null) {
+                return ret;
+            }
+            if (name.endsWith("package-info")) {
+                String s = name.substring(0, name.length() - 13);
+                Package p = super.getPackage(s);
+                if (p == null) {
+                    definePackage(StringUtils.slashesToPeriod(s),
+                            null,
+                            null,
+                            null,
+                            null,
+                            null,
+                            null,
+                            null);
+                }
+            }
+
+            ret = defined.computeIfAbsent(StringUtils.slashesToPeriod(name),
+                key -> TypeHelperClassLoader.super.defineClass(key, bytes, 0, bytes.length));
+
+            return ret;
+        }
+    }
+}
diff --git a/core/src/main/java/org/apache/cxf/common/spi/GeneratedClassClassLoaderCapture.java b/core/src/main/java/org/apache/cxf/common/spi/GeneratedClassClassLoaderCapture.java
new file mode 100644
index 0000000..b71d582
--- /dev/null
+++ b/core/src/main/java/org/apache/cxf/common/spi/GeneratedClassClassLoaderCapture.java
@@ -0,0 +1,36 @@
+/**
+ * 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.cxf.common.spi;
+
+/** Implement this interface to store class generated in order during build phase
+ *  inject it back before runtime to avoid class generation.
+ *  produce dot class file thanks to save method.
+ *  You can check WrapperNamespaceClassGeneratorTest.testGeneratedFirst for usage
+ *  Here is list of extensions to set in order to avoid class loading after generation during build time.
+ *  bus.setExtension(new WrapperHelperClassLoader(bus), WrapperHelperCreator.class);
+ *  bus.setExtension(new ExtensionClassLoader(bus), ExtensionClassCreator.class);
+ *  bus.setExtension(new ExceptionClassLoader(bus), ExceptionClassCreator.class);
+ *  bus.setExtension(new GeneratedWrapperClassLoader(bus), WrapperClassCreator.class);
+ *  bus.setExtension(new FactoryClassLoader(bus), FactoryClassCreator.class);
+ *  bus.setExtension(new GeneratedNamespaceClassLoader(bus), NamespaceClassCreator.class);
+ * @author olivier dufour
+ */
+public interface GeneratedClassClassLoaderCapture {
+    void capture(String className, byte[] bytes);
+}
diff --git a/core/src/main/java/org/apache/cxf/common/spi/GeneratedNamespaceClassLoader.java b/core/src/main/java/org/apache/cxf/common/spi/GeneratedNamespaceClassLoader.java
new file mode 100644
index 0000000..1f3bf89
--- /dev/null
+++ b/core/src/main/java/org/apache/cxf/common/spi/GeneratedNamespaceClassLoader.java
@@ -0,0 +1,51 @@
+/**
+ * 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.cxf.common.spi;
+
+import java.util.Map;
+
+import org.apache.cxf.Bus;
+
+/** If class has been generated during build time
+ *  (use @see org.apache.cxf.common.spi.GeneratedClassClassLoaderCapture capture to save bytes)
+ *  you can set class loader to avoid class generation during runtime:
+ *  bus.setExtension(new GeneratedNamespaceClassLoader(bus), NamespaceClassCreator.class);
+ * @author olivier dufour
+ */
+public class GeneratedNamespaceClassLoader extends GeneratedClassClassLoader implements NamespaceClassCreator {
+    GeneratedNamespaceClassLoader(Bus bus) {
+        super(bus);
+    }
+    public synchronized Class<?> createNamespaceWrapperClass(Class<?> mcls, Map<String, String> map) {
+        String postFix = "";
+
+        if (mcls.getName().contains("eclipse")) {
+            return findClass("org.apache.cxf.jaxb.EclipseNamespaceMapper",
+                    NamespaceClassCreator.class);
+        } else if (mcls.getName().contains(".internal")) {
+            postFix = "Internal";
+        } else if (mcls.getName().contains("com.sun")) {
+            postFix = "RI";
+        }
+        return findClass("org.apache.cxf.jaxb.NamespaceMapper" + postFix, NamespaceClassCreator.class);
+
+
+    }
+}
diff --git a/core/src/main/java/org/apache/cxf/common/spi/NamespaceClassCreator.java b/core/src/main/java/org/apache/cxf/common/spi/NamespaceClassCreator.java
new file mode 100644
index 0000000..c951e4b
--- /dev/null
+++ b/core/src/main/java/org/apache/cxf/common/spi/NamespaceClassCreator.java
@@ -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.cxf.common.spi;
+
+import java.util.Map;
+
+/**
+ * SPI interface to implement the proxy defining logic.
+ * It enables to switch from unsafe to classloader logic for instance for java >= 9.
+ */
+public interface NamespaceClassCreator {
+
+    Class<?> createNamespaceWrapperClass(Class<?> mcls, Map<String, String> map);
+
+}
diff --git a/core/src/main/java/org/apache/cxf/common/spi/NamespaceClassGenerator.java b/core/src/main/java/org/apache/cxf/common/spi/NamespaceClassGenerator.java
new file mode 100644
index 0000000..fbdc524
--- /dev/null
+++ b/core/src/main/java/org/apache/cxf/common/spi/NamespaceClassGenerator.java
@@ -0,0 +1,451 @@
+/**
+ * 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.cxf.common.spi;
+
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.common.classloader.ClassLoaderUtils;
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.common.util.ASMHelper;
+import org.apache.cxf.common.util.OpcodesProxy;
+
+public class NamespaceClassGenerator extends ClassGeneratorClassLoader implements NamespaceClassCreator {
+
+    private static final Logger LOG = LogUtils.getL7dLogger(ClassGeneratorClassLoader.class);
+    private final ASMHelper helper;
+
+    public NamespaceClassGenerator(Bus bus) {
+        super(bus);
+        helper = bus.getExtension(ASMHelper.class);
+    }
+
+    @Override
+    public synchronized Class<?> createNamespaceWrapperClass(Class<?> mcls, Map<String, String> map) {
+        String postFix = "";
+
+        if (mcls.getName().contains("eclipse")) {
+            return createEclipseNamespaceMapper(mcls, map);
+        } else if (mcls.getName().contains(".internal")) {
+            postFix = "Internal";
+        } else if (mcls.getName().contains("com.sun")) {
+            postFix = "RI";
+        }
+
+        String className = "org.apache.cxf.jaxb.NamespaceMapper";
+        className += postFix;
+        Class<?> cls = findClass(className, NamespaceClassCreator.class);
+        Throwable t = null;
+        if (cls == null) {
+            try {
+                byte[] bts = createNamespaceWrapperInternal(postFix);
+                className = "org.apache.cxf.jaxb.NamespaceMapper" + postFix;
+                return loadClass(className, NamespaceClassCreator.class, bts);
+            } catch (RuntimeException ex) {
+                // continue
+                t = ex;
+            }
+        }
+        if (cls == null
+                && (!mcls.getName().contains(".internal.") && mcls.getName().contains("com.sun"))) {
+            try {
+                cls = ClassLoaderUtils.loadClass("org.apache.cxf.common.jaxb.NamespaceMapper",
+                        NamespaceClassCreator.class);
+            } catch (Throwable ex2) {
+                // ignore
+                t = ex2;
+            }
+        }
+        LOG.log(Level.INFO, "Could not create a NamespaceMapper compatible with Marshaller class " + mcls.getName(), t);
+        return cls;
+    }
+
+    private Class<?> createEclipseNamespaceMapper(Class<?> mcls, Map<String, String> map) {
+        String className = "org.apache.cxf.jaxb.EclipseNamespaceMapper";
+        Class<?> cls = findClass(className, NamespaceClassCreator.class);
+        if (cls != null) {
+            return cls;
+        }
+        byte[] bts = createEclipseNamespaceMapper();
+        //previous code use mcls instead of NamespaceClassGenerator.class
+        return loadClass(className, NamespaceClassCreator.class, bts);
+    }
+
+    /*
+    // This is the "prototype" for the ASM generated class below
+    public static class MapNamespacePrefixMapper2
+        extends org.eclipse.persistence.internal.oxm.record.namespaces.MapNamespacePrefixMapper {
+
+        String[] nsctxt;
+
+        public MapNamespacePrefixMapper2(Map<String, String> foo) {
+            super(foo);
+        }
+        public String[] getPreDeclaredNamespaceUris() {
+            String[] sup = super.getPreDeclaredNamespaceUris();
+            if (nsctxt == null) {
+                return sup;
+            }
+            List<String> s = new ArrayList<>(Arrays.asList(sup));
+            for (int x = 1; x < nsctxt.length; x = x + 2) {
+                s.remove(nsctxt[x]);
+            }
+            return s.toArray(new String[s.size()]);
+        }
+        public void setContextualNamespaceDecls(String[] f) {
+            nsctxt = f;
+        }
+        public String[] getContextualNamespaceDecls() {
+            return nsctxt;
+        }
+    }
+    */
+    //CHECKSTYLE:OFF
+    //bunch of really long ASM based methods that cannot be shortened easily
+    private byte[] createEclipseNamespaceMapper() {
+        OpcodesProxy Opcodes = helper.getOpCodes();
+        String slashedName = "org/apache/cxf/jaxb/EclipseNamespaceMapper";
+        ASMHelper.ClassWriter cw = helper.createClassWriter();
+        if (cw == null) {
+            return null;
+        }
+        String superName = "org/eclipse/persistence/internal/oxm/record/namespaces/MapNamespacePrefixMapper";
+        ASMHelper.FieldVisitor fv;
+        ASMHelper.MethodVisitor mv;
+        cw.visit(Opcodes.V1_6,
+                Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL + Opcodes.ACC_SUPER,
+                slashedName, null,
+                superName, null);
+
+        cw.visitSource("EclipseNamespaceMapper.java", null);
+
+        fv = cw.visitField(Opcodes.ACC_PRIVATE, "nsctxt", "[Ljava/lang/String;", null, null);
+        fv.visitEnd();
+
+
+        mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "(Ljava/util/Map;)V",
+                "(Ljava/util/Map<Ljava/lang/String;Ljava/lang/String;>;)V", null);
+        mv.visitCode();
+        ASMHelper.Label l0 = helper.createLabel();
+        mv.visitLabel(l0);
+        mv.visitVarInsn(Opcodes.ALOAD, 0);
+        mv.visitVarInsn(Opcodes.ALOAD, 1);
+        mv.visitMethodInsn(Opcodes.INVOKESPECIAL,
+                superName, "<init>", "(Ljava/util/Map;)V", false);
+        ASMHelper.Label l1 = helper.createLabel();
+        mv.visitLabel(l1);
+        mv.visitInsn(Opcodes.RETURN);
+        ASMHelper.Label l2 = helper.createLabel();
+        mv.visitLabel(l2);
+        mv.visitMaxs(0, 0);
+        mv.visitEnd();
+
+
+        mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "setContextualNamespaceDecls", "([Ljava/lang/String;)V",
+                null, null);
+        mv.visitCode();
+        l0 = helper.createLabel();
+        mv.visitLabel(l0);
+        mv.visitLineNumber(47, l0);
+        mv.visitVarInsn(Opcodes.ALOAD, 0);
+        mv.visitVarInsn(Opcodes.ALOAD, 1);
+        mv.visitFieldInsn(Opcodes.PUTFIELD, slashedName, "nsctxt", "[Ljava/lang/String;");
+        l1 = helper.createLabel();
+        mv.visitLabel(l1);
+        mv.visitLineNumber(48, l1);
+        mv.visitInsn(Opcodes.RETURN);
+        l2 = helper.createLabel();
+        mv.visitLabel(l2);
+        mv.visitLocalVariable("this", "L" + slashedName + ";", null, l0, l2, 0);
+        mv.visitLocalVariable("contextualNamespaceDecls", "[Ljava/lang/String;", null, l0, l2, 1);
+        mv.visitMaxs(0, 0);
+        mv.visitEnd();
+
+        mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "getContextualNamespaceDecls", "()[Ljava/lang/String;", null, null);
+        mv.visitCode();
+        l0 = helper.createLabel();
+        mv.visitLabel(l0);
+        mv.visitLineNumber(51, l0);
+        mv.visitVarInsn(Opcodes.ALOAD, 0);
+        mv.visitFieldInsn(Opcodes.GETFIELD, slashedName, "nsctxt", "[Ljava/lang/String;");
+        mv.visitInsn(Opcodes.ARETURN);
+        l1 = helper.createLabel();
+
+        mv.visitLabel(l1);
+        mv.visitLocalVariable("this", "L" + slashedName + ";", null, l0, l1, 0);
+
+        mv.visitMaxs(0, 0);
+        mv.visitEnd();
+
+
+        mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "getPreDeclaredNamespaceUris", "()[Ljava/lang/String;", null, null);
+        mv.visitCode();
+        l0 = helper.createLabel();
+        mv.visitLabel(l0);
+        mv.visitLineNumber(1036, l0);
+        mv.visitVarInsn(Opcodes.ALOAD, 0);
+        mv.visitMethodInsn(Opcodes.INVOKESPECIAL,
+                superName,
+                "getPreDeclaredNamespaceUris", "()[Ljava/lang/String;", false);
+        mv.visitVarInsn(Opcodes.ASTORE, 1);
+        l1 = helper.createLabel();
+        mv.visitLabel(l1);
+        mv.visitLineNumber(1037, l1);
+        mv.visitVarInsn(Opcodes.ALOAD, 0);
+        mv.visitFieldInsn(Opcodes.GETFIELD, slashedName, "nsctxt", "[Ljava/lang/String;");
+        l2 = helper.createLabel();
+        mv.visitJumpInsn(Opcodes.IFNONNULL, l2);
+        ASMHelper.Label l3 = helper.createLabel();
+        mv.visitLabel(l3);
+        mv.visitLineNumber(1038, l3);
+        mv.visitVarInsn(Opcodes.ALOAD, 1);
+        mv.visitInsn(Opcodes.ARETURN);
+        mv.visitLabel(l2);
+        mv.visitLineNumber(1040, l2);
+        mv.visitFrame(Opcodes.F_APPEND, 1, new Object[] {"[Ljava/lang/String;"}, 0, null);
+        mv.visitTypeInsn(Opcodes.NEW, "java/util/ArrayList");
+        mv.visitInsn(Opcodes.DUP);
+        mv.visitVarInsn(Opcodes.ALOAD, 1);
+        mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/util/Arrays", "asList",
+                "([Ljava/lang/Object;)Ljava/util/List;", false);
+        mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/util/ArrayList", "<init>",
+                "(Ljava/util/Collection;)V", false);
+        mv.visitVarInsn(Opcodes.ASTORE, 2);
+        ASMHelper.Label l4 = helper.createLabel();
+        mv.visitLabel(l4);
+        mv.visitLineNumber(1041, l4);
+        mv.visitInsn(Opcodes.ICONST_1);
+        mv.visitVarInsn(Opcodes.ISTORE, 3);
+        ASMHelper.Label l5 = helper.createLabel();
+        mv.visitLabel(l5);
+        ASMHelper.Label l6 = helper.createLabel();
+        mv.visitJumpInsn(Opcodes.GOTO, l6);
+        ASMHelper.Label l7 = helper.createLabel();
+        mv.visitLabel(l7);
+        mv.visitLineNumber(1042, l7);
+        mv.visitFrame(Opcodes.F_APPEND, 2, new Object[] {"java/util/List", Opcodes.INTEGER}, 0, null);
+        mv.visitVarInsn(Opcodes.ALOAD, 2);
+        mv.visitVarInsn(Opcodes.ALOAD, 0);
+        mv.visitFieldInsn(Opcodes.GETFIELD, slashedName, "nsctxt", "[Ljava/lang/String;");
+        mv.visitVarInsn(Opcodes.ILOAD, 3);
+        mv.visitInsn(Opcodes.AALOAD);
+        mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/List", "remove", "(Ljava/lang/Object;)Z", true);
+        mv.visitInsn(Opcodes.POP);
+        ASMHelper.Label l8 = helper.createLabel();
+        mv.visitLabel(l8);
+        mv.visitLineNumber(1041, l8);
+        mv.visitIincInsn(3, 2);
+        mv.visitLabel(l6);
+        mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
+        mv.visitVarInsn(Opcodes.ILOAD, 3);
+        mv.visitVarInsn(Opcodes.ALOAD, 0);
+        mv.visitFieldInsn(Opcodes.GETFIELD,
+                slashedName,
+                "nsctxt", "[Ljava/lang/String;");
+        mv.visitInsn(Opcodes.ARRAYLENGTH);
+        mv.visitJumpInsn(Opcodes.IF_ICMPLT, l7);
+        ASMHelper.Label l9 = helper.createLabel();
+        mv.visitLabel(l9);
+        mv.visitLineNumber(1044, l9);
+        mv.visitVarInsn(Opcodes.ALOAD, 2);
+        mv.visitVarInsn(Opcodes.ALOAD, 2);
+        mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/List", "size", "()I", true);
+        mv.visitTypeInsn(Opcodes.ANEWARRAY, "java/lang/String");
+        mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/List",
+                "toArray", "([Ljava/lang/Object;)[Ljava/lang/Object;", true);
+        mv.visitTypeInsn(Opcodes.CHECKCAST, "[Ljava/lang/String;");
+        mv.visitInsn(Opcodes.ARETURN);
+        ASMHelper.Label l10 = helper.createLabel();
+        mv.visitLabel(l10);
+        mv.visitLocalVariable("this", "L" + slashedName + ";",
+                null, l0, l10, 0);
+        mv.visitLocalVariable("sup", "[Ljava/lang/String;", null, l1, l10, 1);
+        mv.visitLocalVariable("s", "Ljava/util/List;", "Ljava/util/List<Ljava/lang/String;>;", l4, l10, 2);
+        mv.visitLocalVariable("x", "I", null, l5, l9, 3);
+        mv.visitMaxs(0, 0);
+        mv.visitEnd();
+
+        cw.visitEnd();
+
+        byte[] bts = cw.toByteArray();
+        return bts;
+    }
+
+    private byte[] createNamespaceWrapperInternal(String postFix) {
+
+        String superName = "com/sun/xml/"
+                + ("RI".equals(postFix) ? "" : "internal/")
+                + "bind/marshaller/NamespacePrefixMapper";
+        String postFixedName = "org/apache/cxf/jaxb/NamespaceMapper" + postFix;
+        ASMHelper.ClassWriter cw = helper.createClassWriter();
+        if (cw == null) {
+            return null;
+        }
+        ASMHelper.FieldVisitor fv;
+        ASMHelper.MethodVisitor mv;
+        OpcodesProxy Opcodes= helper.getOpCodes();
+        cw.visit(Opcodes.V1_6,
+                Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL + Opcodes.ACC_SUPER,
+                postFixedName, null,
+                superName, null);
+
+        cw.visitSource("NamespaceMapper.java", null);
+
+        fv = cw.visitField(Opcodes.ACC_PRIVATE + Opcodes.ACC_FINAL,
+                "nspref", "Ljava/util/Map;",
+                "Ljava/util/Map<Ljava/lang/String;Ljava/lang/String;>;", null);
+        fv.visitEnd();
+
+        fv = cw.visitField(Opcodes.ACC_PRIVATE, "nsctxt", "[Ljava/lang/String;", null, null);
+        fv.visitEnd();
+
+        fv = cw.visitField(Opcodes.ACC_PRIVATE + Opcodes.ACC_FINAL + Opcodes.ACC_STATIC,
+                "EMPTY_STRING", "[Ljava/lang/String;", null, null);
+        fv.visitEnd();
+
+        mv = cw.visitMethod(Opcodes.ACC_STATIC, "<clinit>", "()V", null, null);
+        mv.visitCode();
+        ASMHelper.Label l0 = helper.createLabel();
+        mv.visitLabel(l0);
+        mv.visitLineNumber(30, l0);
+        mv.visitInsn(Opcodes.ICONST_0);
+        mv.visitTypeInsn(Opcodes.ANEWARRAY, "java/lang/String");
+        mv.visitFieldInsn(Opcodes.PUTSTATIC, postFixedName, "EMPTY_STRING", "[Ljava/lang/String;");
+        mv.visitInsn(Opcodes.RETURN);
+        mv.visitMaxs(0, 0);
+        mv.visitEnd();
+
+        mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>",
+                "(Ljava/util/Map;)V",
+                "(Ljava/util/Map<Ljava/lang/String;Ljava/lang/String;>;)V", null);
+        mv.visitCode();
+        l0 = helper.createLabel();
+        mv.visitLabel(l0);
+        mv.visitLineNumber(32, l0);
+        mv.visitVarInsn(Opcodes.ALOAD, 0);
+        mv.visitMethodInsn(Opcodes.INVOKESPECIAL, superName, "<init>", "()V", false);
+        ASMHelper.Label l1 = helper.createLabel();
+        mv.visitLabel(l1);
+        mv.visitLineNumber(29, l1);
+        mv.visitVarInsn(Opcodes.ALOAD, 0);
+        mv.visitFieldInsn(Opcodes.GETSTATIC, postFixedName, "EMPTY_STRING", "[Ljava/lang/String;");
+        mv.visitFieldInsn(Opcodes.PUTFIELD, postFixedName, "nsctxt", "[Ljava/lang/String;");
+        ASMHelper.Label l2 = helper.createLabel();
+        mv.visitLabel(l2);
+        mv.visitLineNumber(33, l2);
+        mv.visitVarInsn(Opcodes.ALOAD, 0);
+        mv.visitVarInsn(Opcodes.ALOAD, 1);
+        mv.visitFieldInsn(Opcodes.PUTFIELD, postFixedName, "nspref", "Ljava/util/Map;");
+        ASMHelper.Label l3 = helper.createLabel();
+        mv.visitLabel(l3);
+        mv.visitLineNumber(34, l3);
+        mv.visitInsn(Opcodes.RETURN);
+        ASMHelper.Label l4 = helper.createLabel();
+        mv.visitLabel(l4);
+        mv.visitLocalVariable("this", "L" + postFixedName + ";", null, l0, l4, 0);
+        mv.visitLocalVariable("nspref",
+                "Ljava/util/Map;", "Ljava/util/Map<Ljava/lang/String;Ljava/lang/String;>;",
+                l0, l4, 1);
+        mv.visitMaxs(0, 0);
+        mv.visitEnd();
+
+        mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "getPreferredPrefix",
+                "(Ljava/lang/String;Ljava/lang/String;Z)Ljava/lang/String;",
+                null, null);
+        mv.visitCode();
+        l0 = helper.createLabel();
+        mv.visitLabel(l0);
+        mv.visitLineNumber(39, l0);
+        mv.visitVarInsn(Opcodes.ALOAD, 0);
+        mv.visitFieldInsn(Opcodes.GETFIELD, postFixedName, "nspref", "Ljava/util/Map;");
+        mv.visitVarInsn(Opcodes.ALOAD, 1);
+        mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/Map",
+                "get", "(Ljava/lang/Object;)Ljava/lang/Object;", true);
+        mv.visitTypeInsn(Opcodes.CHECKCAST, "java/lang/String");
+        mv.visitVarInsn(Opcodes.ASTORE, 4);
+        l1 = helper.createLabel();
+        mv.visitLabel(l1);
+        mv.visitLineNumber(40, l1);
+        mv.visitVarInsn(Opcodes.ALOAD, 4);
+        l2 = helper.createLabel();
+        mv.visitJumpInsn(Opcodes.IFNULL, l2);
+        l3 = helper.createLabel();
+        mv.visitLabel(l3);
+        mv.visitLineNumber(41, l3);
+        mv.visitVarInsn(Opcodes.ALOAD, 4);
+        mv.visitInsn(Opcodes.ARETURN);
+        mv.visitLabel(l2);
+        mv.visitLineNumber(43, l2);
+        mv.visitFrame(Opcodes.F_APPEND, 1, new Object[] {"java/lang/String"}, 0, null);
+        mv.visitVarInsn(Opcodes.ALOAD, 2);
+        mv.visitInsn(Opcodes.ARETURN);
+        l4 = helper.createLabel();
+        mv.visitLabel(l4);
+        mv.visitLocalVariable("this", "L" + postFixedName + ";", null, l0, l4, 0);
+        mv.visitLocalVariable("namespaceUri", "Ljava/lang/String;", null, l0, l4, 1);
+        mv.visitLocalVariable("suggestion", "Ljava/lang/String;", null, l0, l4, 2);
+        mv.visitLocalVariable("requirePrefix", "Z", null, l0, l4, 3);
+        mv.visitLocalVariable("prefix", "Ljava/lang/String;", null, l1, l4, 4);
+        mv.visitMaxs(0, 0);
+        mv.visitEnd();
+
+        mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "setContextualNamespaceDecls", "([Ljava/lang/String;)V", null, null);
+        mv.visitCode();
+        l0 = helper.createLabel();
+        mv.visitLabel(l0);
+        mv.visitLineNumber(47, l0);
+        mv.visitVarInsn(Opcodes.ALOAD, 0);
+        mv.visitVarInsn(Opcodes.ALOAD, 1);
+        mv.visitFieldInsn(Opcodes.PUTFIELD, postFixedName, "nsctxt", "[Ljava/lang/String;");
+        l1 = helper.createLabel();
+        mv.visitLabel(l1);
+        mv.visitLineNumber(48, l1);
+        mv.visitInsn(Opcodes.RETURN);
+        l2 = helper.createLabel();
+        mv.visitLabel(l2);
+        mv.visitLocalVariable("this", "L" + postFixedName + ";", null, l0, l2, 0);
+        mv.visitLocalVariable("contextualNamespaceDecls", "[Ljava/lang/String;", null, l0, l2, 1);
+        mv.visitMaxs(0, 0);
+        mv.visitEnd();
+
+        mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "getContextualNamespaceDecls", "()[Ljava/lang/String;", null, null);
+        mv.visitCode();
+        l0 = helper.createLabel();
+        mv.visitLabel(l0);
+        mv.visitLineNumber(51, l0);
+        mv.visitVarInsn(Opcodes.ALOAD, 0);
+        mv.visitFieldInsn(Opcodes.GETFIELD, postFixedName, "nsctxt", "[Ljava/lang/String;");
+        mv.visitInsn(Opcodes.ARETURN);
+        l1 = helper.createLabel();
+
+        mv.visitLabel(l1);
+        mv.visitLocalVariable("this", "L" + postFixedName + ";", null, l0, l1, 0);
+
+        mv.visitMaxs(0, 0);
+        mv.visitEnd();
+
+        cw.visitEnd();
+
+        return cw.toByteArray();
+    }
+    //CHECKSTYLE:ON
+}
diff --git a/core/src/main/java/org/apache/cxf/common/util/ASMHelper.java b/core/src/main/java/org/apache/cxf/common/util/ASMHelper.java
index b08974b..16a79d9 100644
--- a/core/src/main/java/org/apache/cxf/common/util/ASMHelper.java
+++ b/core/src/main/java/org/apache/cxf/common/util/ASMHelper.java
@@ -19,447 +19,28 @@
 
 package org.apache.cxf.common.util;
 
-import java.lang.ref.WeakReference;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Field;
-import java.lang.reflect.GenericArrayType;
 import java.lang.reflect.Method;
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.TypeVariable;
-import java.lang.reflect.WildcardType;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
 
-import org.apache.cxf.common.classloader.ClassLoaderUtils;
 import org.apache.cxf.common.util.ReflectionInvokationHandler.Optional;
 import org.apache.cxf.common.util.ReflectionInvokationHandler.UnwrapParam;
 import org.apache.cxf.common.util.ReflectionInvokationHandler.WrapReturn;
 
-public class ASMHelper {
-    protected static final Map<Class<?>, String> PRIMITIVE_MAP = new HashMap<>();
-    protected static final Map<Class<?>, String> NONPRIMITIVE_MAP = new HashMap<>();
-    protected static final Map<Class<?>, Integer> PRIMITIVE_ZERO_MAP = new HashMap<>();
 
-    protected static final Map<ClassLoader, WeakReference<TypeHelperClassLoader>> LOADER_MAP
-        = new WeakIdentityHashMap<>();
-    protected static final Map<Class<?>, WeakReference<TypeHelperClassLoader>> CLASS_MAP
-        = new WeakIdentityHashMap<>();
+public interface ASMHelper {
+    String getClassCode(Class<?> cl);
+    String getClassCode(java.lang.reflect.Type type);
+    ClassWriter createClassWriter();
+    ASMType getType(String type);
+    Label createLabel();
+    OpcodesProxy getOpCodes();
+    Class<?> getASMClass() throws ClassNotFoundException;
+    String getMethodSignature(Method m);
+    String getNonPrimitive(Class<?> tp);
+    String getPrimitive(Class<?> tp);
 
-    protected static boolean badASM;
-    private static Class<?> cwClass;
-
-    static {
-        PRIMITIVE_MAP.put(Byte.TYPE, "B");
-        PRIMITIVE_MAP.put(Boolean.TYPE, "Z");
-        PRIMITIVE_MAP.put(Long.TYPE, "J");
-        PRIMITIVE_MAP.put(Integer.TYPE, "I");
-        PRIMITIVE_MAP.put(Short.TYPE, "S");
-        PRIMITIVE_MAP.put(Character.TYPE, "C");
-        PRIMITIVE_MAP.put(Float.TYPE, "F");
-        PRIMITIVE_MAP.put(Double.TYPE, "D");
-
-        NONPRIMITIVE_MAP.put(Byte.TYPE, Byte.class.getName().replaceAll("\\.", "/"));
-        NONPRIMITIVE_MAP.put(Boolean.TYPE, Boolean.class.getName().replaceAll("\\.", "/"));
-        NONPRIMITIVE_MAP.put(Long.TYPE, Long.class.getName().replaceAll("\\.", "/"));
-        NONPRIMITIVE_MAP.put(Integer.TYPE, Integer.class.getName().replaceAll("\\.", "/"));
-        NONPRIMITIVE_MAP.put(Short.TYPE, Short.class.getName().replaceAll("\\.", "/"));
-        NONPRIMITIVE_MAP.put(Character.TYPE, Character.class.getName().replaceAll("\\.", "/"));
-        NONPRIMITIVE_MAP.put(Float.TYPE, Float.class.getName().replaceAll("\\.", "/"));
-        NONPRIMITIVE_MAP.put(Double.TYPE, Double.class.getName().replaceAll("\\.", "/"));
-    }
-
-    private static void tryClass(String s) {
-        if (cwClass == null) {
-            try {
-                Class<?> c2 = ClassLoaderUtils.loadClass(s, ASMHelper.class);
-
-                //old versions don't have this, but we need it
-                Class<?> cls = ClassLoaderUtils.loadClass(c2.getPackage().getName() + ".MethodVisitor", c2);
-                cls.getMethod("visitFrame", Integer.TYPE, Integer.TYPE,
-                              Object[].class,  Integer.TYPE, Object[].class);
-                cwClass = c2;
-            } catch (Throwable t) {
-                //ignore
-            }
-        }
-    }
-    private static Class<?> getASMClassWriterClass() {
-        //force this to make sure the proper OSGi import is generated
-        return org.objectweb.asm.ClassWriter.class;
-    }
-
-    private static synchronized Class<?> getASMClass() throws ClassNotFoundException {
-        if (cwClass == null) {
-            //try the "real" asm first, then the others
-            tryClass("org.objectweb.asm.ClassWriter");
-            tryClass("org.apache.xbean.asm9.ClassWriter");
-            tryClass("org.apache.xbean.asm8.ClassWriter");
-            tryClass("org.apache.xbean.asm7.ClassWriter");
-            tryClass("org.apache.xbean.asm5.ClassWriter");
-            tryClass("org.apache.xbean.asm6.ClassWriter");
-            tryClass("org.apache.xbean.asm4.ClassWriter");
-            tryClass("org.apache.xbean.asm.ClassWriter");
-            tryClass("org.springframework.asm.ClassWriter");
-            if (cwClass == null) {
-                cwClass = getASMClassWriterClass();
-            }
-        }
-        return cwClass;
-    }
-
-    public static class Opcodes {
-        //CHECKSTYLE:OFF
-        //Will use reflection to set these based on the package name and such
-        //so we don't want them "final" or the compiler will optimize them out
-        //to just "0" which we really don't want
-        public static int ARETURN = 0;
-        public static int ALOAD = 0;
-        public static int IFNULL = 0;
-        public static int CHECKCAST = 0;
-        public static int INVOKEINTERFACE = 0;
-        public static int GETFIELD = 0;
-        public static int GETSTATIC = 0;
-        public static int ASTORE = 0;
-        public static int PUTFIELD = 0;
-        public static int PUTSTATIC = 0;
-        public static int RETURN = 0;
-        public static int F_APPEND = 0;
-        public static int F_SAME = 0;
-        public static int F_SAME1 = 0;
-        public static int INVOKESPECIAL = 0;
-        public static int ACC_PUBLIC = 0;
-        public static int ACC_FINAL = 0;
-        public static int ACC_SUPER = 0;
-        public static int ACC_PRIVATE = 0;
-        public static int ACC_STATIC = 0;
-        public static int V1_5 = 0;
-        public static int V1_6 = 0;
-        public static int V1_7 = 0;
-        public static int ACC_ABSTRACT = 0;
-        public static int ACC_INTERFACE = 0;
-        public static int ACC_SYNTHETIC = 0;
-        public static int ILOAD = 0;
-        public static int ISTORE = 0;
-        public static int AALOAD = 0;
-        public static int ARRAYLENGTH = 0;
-        public static int IRETURN = 0;
-        public static int NEW = 0;
-        public static int ANEWARRAY = 0;
-        public static int DUP = 0;
-        public static int ATHROW = 0;
-        public static int INVOKEVIRTUAL = 0;
-        public static int GOTO = 0;
-        public static int POP = 0;
-        public static int ACONST_NULL = 0;
-        public static int IFNONNULL = 0;
-        public static int SIPUSH = 0;
-        public static int INVOKESTATIC = 0;
-        public static int ICONST_0;
-        public static int ICONST_1;
-        public static int LCONST_0;
-        public static int FCONST_0;
-        public static int DCONST_0;
-        public static int IF_ICMPLT = 0;
-        public static java.lang.Integer INTEGER;
-
-        //CHECKSTYLE:ON
-        static {
-            try {
-                Class<?> cls = getASMClass();
-                cls = ClassLoaderUtils.loadClass(cls.getPackage().getName() + ".Opcodes", cls);
-                for (Field f1 : Opcodes.class.getDeclaredFields()) {
-                    Field f = cls.getDeclaredField(f1.getName());
-                    ReflectionUtil.setAccessible(f1).set(null, ReflectionUtil.setAccessible(f).get(null));
-                }
-            } catch (Throwable e) {
-                //ignore
-            }
-
-            PRIMITIVE_ZERO_MAP.put(Byte.TYPE, Opcodes.ICONST_0);
-            PRIMITIVE_ZERO_MAP.put(Boolean.TYPE, Opcodes.ICONST_0);
-            PRIMITIVE_ZERO_MAP.put(Long.TYPE, Opcodes.LCONST_0);
-            PRIMITIVE_ZERO_MAP.put(Integer.TYPE, Opcodes.ICONST_0);
-            PRIMITIVE_ZERO_MAP.put(Short.TYPE, Opcodes.ICONST_0);
-            PRIMITIVE_ZERO_MAP.put(Character.TYPE, Opcodes.ICONST_0);
-            PRIMITIVE_ZERO_MAP.put(Float.TYPE, Opcodes.FCONST_0);
-            PRIMITIVE_ZERO_MAP.put(Double.TYPE, Opcodes.DCONST_0);
-        }
-    }
-
-    protected static String getMethodSignature(Method m) {
-        StringBuilder buf = new StringBuilder("(");
-        for (Class<?> cl : m.getParameterTypes()) {
-            buf.append(getClassCode(cl));
-        }
-        buf.append(')');
-        buf.append(getClassCode(m.getReturnType()));
-
-        return buf.toString();
-    }
-
-    public static String periodToSlashes(String s) {
-        char[] ch = s.toCharArray();
-        for (int x = 0; x < ch.length; x++) {
-            if (ch[x] == '.') {
-                ch[x] = '/';
-            }
-        }
-        return new String(ch);
-    }
-
-
-    public static String getClassCode(Class<?> cl) {
-        if (cl == Void.TYPE) {
-            return "V";
-        }
-        if (cl.isPrimitive()) {
-            return PRIMITIVE_MAP.get(cl);
-        }
-        if (cl.isArray()) {
-            return "[" + getClassCode(cl.getComponentType());
-        }
-        return "L" + periodToSlashes(cl.getName()) + ";";
-    }
-    public static String getClassCode(java.lang.reflect.Type type) {
-        if (type instanceof Class) {
-            return getClassCode((Class<?>)type);
-        } else if (type instanceof GenericArrayType) {
-            GenericArrayType at = (GenericArrayType)type;
-            return "[" + getClassCode(at.getGenericComponentType());
-        } else if (type instanceof TypeVariable) {
-            TypeVariable<?> tv = (TypeVariable<?>)type;
-            java.lang.reflect.Type[] bounds = tv.getBounds();
-            if (bounds != null && bounds.length == 1) {
-                return getClassCode(bounds[0]);
-            }
-            throw new IllegalArgumentException("Unable to determine type for: " + tv);
-        } else if (type instanceof ParameterizedType) {
-            ParameterizedType pt = (ParameterizedType)type;
-            StringBuilder a = new StringBuilder(getClassCode(pt.getRawType()));
-            if (!pt.getRawType().equals(Enum.class)) {
-                a.setLength(a.length() - 1);
-                a.append('<');
-
-                for (java.lang.reflect.Type t : pt.getActualTypeArguments()) {
-                    a.append(getClassCode(t));
-                }
-                a.append(">;");
-            }
-            return a.toString();
-        } else if (type instanceof WildcardType) {
-            WildcardType wt = (WildcardType)type;
-            StringBuilder a = new StringBuilder();
-            java.lang.reflect.Type[] lowBounds = wt.getLowerBounds();
-            java.lang.reflect.Type[] upBounds = wt.getUpperBounds();
-            for (java.lang.reflect.Type t : upBounds) {
-                a.append('+');
-                a.append(getClassCode(t));
-            }
-            for (java.lang.reflect.Type t : lowBounds) {
-                a.append('-');
-                a.append(getClassCode(t));
-            }
-            return a.toString();
-        }
-        return null;
-    }
-
-
-    public ClassWriter createClassWriter() {
-        Object newCw = null;
-        if (!badASM) {
-            if (cwClass == null) {
-                try {
-                    cwClass = getASMClass();
-                } catch (Throwable error) {
-                    badASM = true;
-                    throw new RuntimeException("No ASM ClassWriterFound", error);
-                }
-            }
-            try {
-                // ASM 1.5.x/2.x
-                Constructor<?> cons
-                    = cwClass.getConstructor(new Class<?>[] {Boolean.TYPE});
-
-                try {
-                    // got constructor, now check if it's 1.x which is very
-                    // different from 2.x and 3.x
-                    cwClass.getMethod("newConstInt", new Class<?>[] {Integer.TYPE});
-                    // newConstInt was removed in 2.x, if we get this far, we're
-                    // using 1.5.x,
-                    // set to null so we don't attempt to use it.
-                    badASM = true;
-                } catch (Throwable t) {
-                    newCw = cons.newInstance(new Object[] {Boolean.TRUE});
-                }
-
-            } catch (Throwable e) {
-                // ASM 3.x/4.x
-                try {
-                    Constructor<?> cons
-                        = cwClass.getConstructor(new Class<?>[] {Integer.TYPE});
-                    int i = cwClass.getField("COMPUTE_MAXS").getInt(null);
-                    i |= cwClass.getField("COMPUTE_FRAMES").getInt(null);
-                    newCw = cons.newInstance(new Object[] {Integer.valueOf(i)});
-                } catch (Throwable e1) {
-                    // ignore
-                }
-            }
-        }
-        if (newCw != null) {
-            return ReflectionInvokationHandler.createProxyWrapper(newCw, ClassWriter.class);
-        }
-        return null;
-    }
-
-
-    public Class<?> loadClass(String className, Class<?> clz, byte[] bytes) {
-        TypeHelperClassLoader loader = getTypeHelperClassLoader(clz);
-        synchronized (loader) {
-            Class<?> cls = loader.lookupDefinedClass(className);
-            if (cls == null) {
-                return loader.defineClass(className, bytes);
-            }
-            return cls;
-        }
-    }
-    public Class<?> loadClass(String className, ClassLoader l, byte[] bytes) {
-        TypeHelperClassLoader loader = getTypeHelperClassLoader(l);
-        synchronized (loader) {
-            Class<?> cls = loader.lookupDefinedClass(className);
-            if (cls == null) {
-                return loader.defineClass(className, bytes);
-            }
-            return cls;
-        }
-    }
-    public Class<?> findClass(String className, Class<?> clz) {
-        TypeHelperClassLoader loader = getTypeHelperClassLoader(clz);
-        return loader.lookupDefinedClass(className);
-    }
-    public Class<?> findClass(String className, ClassLoader l) {
-        TypeHelperClassLoader loader = getTypeHelperClassLoader(l);
-        return loader.lookupDefinedClass(className);
-    }
-
-    private static synchronized TypeHelperClassLoader getTypeHelperClassLoader(ClassLoader l) {
-        WeakReference<TypeHelperClassLoader> ref = LOADER_MAP.get(l);
-        TypeHelperClassLoader ret;
-        if (ref == null || ref.get() == null) {
-            ret = new TypeHelperClassLoader(l);
-            LOADER_MAP.put(l, new WeakReference<TypeHelperClassLoader>(ret));
-        } else {
-            ret = ref.get();
-        }
-        return ret;
-    }
-    private static synchronized TypeHelperClassLoader getTypeHelperClassLoader(Class<?> cls) {
-        WeakReference<TypeHelperClassLoader> ref = CLASS_MAP.get(cls);
-        TypeHelperClassLoader ret;
-        if (ref == null || ref.get() == null) {
-            ret = new TypeHelperClassLoader(cls.getClassLoader());
-            CLASS_MAP.put(cls, new WeakReference<TypeHelperClassLoader>(ret));
-        } else {
-            ret = ref.get();
-        }
-        return ret;
-    }
-
-    public static class TypeHelperClassLoader extends ClassLoader {
-        ConcurrentHashMap<String, Class<?>> defined = new ConcurrentHashMap<>();
-
-        TypeHelperClassLoader(ClassLoader parent) {
-            super(parent);
-        }
-        public Class<?> lookupDefinedClass(String name) {
-            return defined.get(name.replace('/', '.'));
-        }
-
-        @Override
-        protected Class<?> findClass(String name) throws ClassNotFoundException {
-            if (name.endsWith("package-info")) {
-                return getParent().loadClass(name);
-            }
-            return super.findClass(name);
-        }
-
-        public Class<?> defineClass(String name, byte[] bytes) {
-            Class<?> ret = defined.get(name.replace('/', '.'));
-            if (ret != null) {
-                return ret;
-            }
-            if (name.endsWith("package-info")) {
-                Package p = super.getPackage(name.substring(0, name.length() - 13));
-                if (p == null) {
-                    definePackage(name.substring(0, name.length() - 13).replace('/', '.'),
-                                    null,
-                                    null,
-                                    null,
-                                    null,
-                                    null,
-                                    null,
-                                    null);
-                }
-            }
-
-            ret = super.defineClass(name.replace('/', '.'), bytes, 0, bytes.length);
-            Class<?> tmpRet = defined.putIfAbsent(name.replace('/', '.'), ret);
-            if (tmpRet != null) {
-                ret = tmpRet;
-            }
-            return ret;
-        }
-    }
-    public ASMType getType(final String type) {
-        try {
-            final Class<?> cls = ClassLoaderUtils.loadClass(cwClass.getPackage().getName() + ".Type", cwClass);
-            final Method m = cls.getMethod("getType", String.class);
-            final Method m2 = cls.getMethod("getOpcode", Integer.TYPE);
-            @SuppressWarnings("unused")
-            ASMType t = new ASMType() {
-                Object tp = ReflectionUtil.setAccessible(m).invoke(null, type);
-                public Object getValue() {
-                    return tp;
-                }
-                public Class<?> realType() {
-                    return cls;
-                }
-                public int getOpcode(int ireturn) {
-                    try {
-                        return (Integer)ReflectionUtil.setAccessible(m2).invoke(tp, ireturn);
-                    } catch (Exception e) {
-                        throw new RuntimeException(e);
-                    }
-                }
-            };
-            return t;
-        } catch (Exception ex) {
-            throw new RuntimeException(ex);
-        }
-    }
     public interface ASMType {
         int getOpcode(int ireturn);
     }
-    public Label createLabel() {
-        try {
-            final Class<?> cls = ClassLoaderUtils.loadClass(cwClass.getPackage().getName() + ".Label",
-                                                      cwClass);
-            @SuppressWarnings("unused")
-            Label l = new Label() {
-                Object l = cls.newInstance();
-                public Object getValue() {
-                    return l;
-                }
-                public Class<?> realType() {
-                    return cls;
-                }
-            };
-            return l;
-        } catch (Exception e) {
-            throw new RuntimeException(e);
-        }
-    }
 
     public interface ClassWriter {
         @WrapReturn(AnnotationVisitor.class)
diff --git a/core/src/main/java/org/apache/cxf/common/util/ASMHelperImpl.java b/core/src/main/java/org/apache/cxf/common/util/ASMHelperImpl.java
new file mode 100644
index 0000000..f67a06d
--- /dev/null
+++ b/core/src/main/java/org/apache/cxf/common/util/ASMHelperImpl.java
@@ -0,0 +1,274 @@
+/**
+ * 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.cxf.common.util;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.GenericArrayType;
+import java.lang.reflect.Method;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.TypeVariable;
+import java.lang.reflect.WildcardType;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.cxf.common.classloader.ClassLoaderUtils;
+
+
+public class ASMHelperImpl implements ASMHelper {
+    protected static final Map<Class<?>, String> PRIMITIVE_MAP = new HashMap<>();
+    protected static final Map<Class<?>, String> NONPRIMITIVE_MAP = new HashMap<>();
+    protected static final Map<Class<?>, Integer> PRIMITIVE_ZERO_MAP = new HashMap<>();
+
+    protected boolean badASM;
+    private Class<?> cwClass;
+
+    public ASMHelperImpl() {
+
+    }
+
+    static {
+        PRIMITIVE_MAP.put(Byte.TYPE, "B");
+        PRIMITIVE_MAP.put(Boolean.TYPE, "Z");
+        PRIMITIVE_MAP.put(Long.TYPE, "J");
+        PRIMITIVE_MAP.put(Integer.TYPE, "I");
+        PRIMITIVE_MAP.put(Short.TYPE, "S");
+        PRIMITIVE_MAP.put(Character.TYPE, "C");
+        PRIMITIVE_MAP.put(Float.TYPE, "F");
+        PRIMITIVE_MAP.put(Double.TYPE, "D");
+
+        NONPRIMITIVE_MAP.put(Byte.TYPE, Byte.class.getName().replaceAll("\\.", "/"));
+        NONPRIMITIVE_MAP.put(Boolean.TYPE, Boolean.class.getName().replaceAll("\\.", "/"));
+        NONPRIMITIVE_MAP.put(Long.TYPE, Long.class.getName().replaceAll("\\.", "/"));
+        NONPRIMITIVE_MAP.put(Integer.TYPE, Integer.class.getName().replaceAll("\\.", "/"));
+        NONPRIMITIVE_MAP.put(Short.TYPE, Short.class.getName().replaceAll("\\.", "/"));
+        NONPRIMITIVE_MAP.put(Character.TYPE, Character.class.getName().replaceAll("\\.", "/"));
+        NONPRIMITIVE_MAP.put(Float.TYPE, Float.class.getName().replaceAll("\\.", "/"));
+        NONPRIMITIVE_MAP.put(Double.TYPE, Double.class.getName().replaceAll("\\.", "/"));
+    }
+
+    private void tryClass(String s) {
+        if (cwClass == null) {
+            try {
+                Class<?> c2 = ClassLoaderUtils.loadClass(s, ASMHelperImpl.class);
+
+                //old versions don't have this, but we need it
+                Class<?> cls = ClassLoaderUtils.loadClass(c2.getPackage().getName() + ".MethodVisitor", c2);
+                cls.getMethod("visitFrame", Integer.TYPE, Integer.TYPE,
+                        Object[].class,  Integer.TYPE, Object[].class);
+                cwClass = c2;
+            } catch (Throwable t) {
+                //ignore
+            }
+        }
+    }
+    private Class<?> getASMClassWriterClass() {
+        //force this to make sure the proper OSGi import is generated
+        return org.objectweb.asm.ClassWriter.class;
+    }
+
+    public synchronized Class<?> getASMClass() throws ClassNotFoundException {
+        if (cwClass == null) {
+            //try the "real" asm first, then the others
+            tryClass("org.objectweb.asm.ClassWriter");
+            tryClass("org.apache.xbean.asm9.ClassWriter");
+            tryClass("org.apache.xbean.asm8.ClassWriter");
+            tryClass("org.apache.xbean.asm7.ClassWriter");
+            tryClass("org.apache.xbean.asm5.ClassWriter");
+            tryClass("org.apache.xbean.asm6.ClassWriter");
+            tryClass("org.apache.xbean.asm4.ClassWriter");
+            tryClass("org.apache.xbean.asm.ClassWriter");
+            tryClass("org.springframework.asm.ClassWriter");
+            if (cwClass == null) {
+                cwClass = getASMClassWriterClass();
+            }
+        }
+        return cwClass;
+    }
+    public OpcodesProxy getOpCodes() {
+        OpcodesProxy ops = new OpcodesProxy(this);
+        PRIMITIVE_ZERO_MAP.put(Byte.TYPE, ops.ICONST_0);
+        PRIMITIVE_ZERO_MAP.put(Boolean.TYPE, ops.ICONST_0);
+        PRIMITIVE_ZERO_MAP.put(Long.TYPE, ops.LCONST_0);
+        PRIMITIVE_ZERO_MAP.put(Integer.TYPE, ops.ICONST_0);
+        PRIMITIVE_ZERO_MAP.put(Short.TYPE, ops.ICONST_0);
+        PRIMITIVE_ZERO_MAP.put(Character.TYPE, ops.ICONST_0);
+        PRIMITIVE_ZERO_MAP.put(Float.TYPE, ops.FCONST_0);
+        PRIMITIVE_ZERO_MAP.put(Double.TYPE, ops.DCONST_0);
+        return ops;
+    }
+    public void setBadASM(boolean b) {
+        badASM = b;
+    }
+
+    public String getMethodSignature(Method m) {
+        StringBuilder buf = new StringBuilder("(");
+        for (Class<?> cl : m.getParameterTypes()) {
+            buf.append(getClassCode(cl));
+        }
+        buf.append(')');
+        buf.append(getClassCode(m.getReturnType()));
+
+        return buf.toString();
+    }
+
+    @Override
+    public String getNonPrimitive(Class<?> tp) {
+        return NONPRIMITIVE_MAP.get(tp);
+    }
+    @Override
+    public String getPrimitive(Class<?> tp) {
+        return PRIMITIVE_MAP.get(tp);
+    }
+
+
+
+
+    public String getClassCode(Class<?> cl) {
+        if (cl == Void.TYPE) {
+            return "V";
+        }
+        if (cl.isPrimitive()) {
+            return PRIMITIVE_MAP.get(cl);
+        }
+        if (cl.isArray()) {
+            return "[" + getClassCode(cl.getComponentType());
+        }
+        return "L" + StringUtils.periodToSlashes(cl.getName()) + ";";
+    }
+    public String getClassCode(java.lang.reflect.Type type) {
+        if (type instanceof Class) {
+            return getClassCode((Class<?>)type);
+        } else if (type instanceof GenericArrayType) {
+            GenericArrayType at = (GenericArrayType)type;
+            return "[" + getClassCode(at.getGenericComponentType());
+        } else if (type instanceof TypeVariable) {
+            TypeVariable<?> tv = (TypeVariable<?>)type;
+            java.lang.reflect.Type[] bounds = tv.getBounds();
+            if (bounds != null && bounds.length == 1) {
+                return getClassCode(bounds[0]);
+            }
+            throw new IllegalArgumentException("Unable to determine type for: " + tv);
+        } else if (type instanceof ParameterizedType) {
+            ParameterizedType pt = (ParameterizedType)type;
+            StringBuilder a = new StringBuilder(getClassCode(pt.getRawType()));
+            if (!pt.getRawType().equals(Enum.class)) {
+                a.setLength(a.length() - 1);
+                a.append('<');
+
+                for (java.lang.reflect.Type t : pt.getActualTypeArguments()) {
+                    a.append(getClassCode(t));
+                }
+                a.append(">;");
+            }
+            return a.toString();
+        } else if (type instanceof WildcardType) {
+            WildcardType wt = (WildcardType)type;
+            StringBuilder a = new StringBuilder();
+            java.lang.reflect.Type[] lowBounds = wt.getLowerBounds();
+            java.lang.reflect.Type[] upBounds = wt.getUpperBounds();
+            for (java.lang.reflect.Type t : upBounds) {
+                a.append('+');
+                a.append(getClassCode(t));
+            }
+            for (java.lang.reflect.Type t : lowBounds) {
+                a.append('-');
+                a.append(getClassCode(t));
+            }
+            return a.toString();
+        }
+        return null;
+    }
+
+    public ClassWriter createClassWriter() {
+        Object newCw = null;
+        if (!badASM) {
+            if (cwClass == null) {
+                try {
+                    cwClass = getASMClass();
+                } catch (Throwable error) {
+                    badASM = true;
+                    throw new RuntimeException("No ASM ClassWriterFound", error);
+                }
+            }
+            // ASM >= 3.x (since cxf is java 8 min we don't care of asm 1/2)
+            try {
+                Constructor<?> cons
+                        = cwClass.getConstructor(new Class<?>[] {Integer.TYPE});
+                int i = cwClass.getField("COMPUTE_MAXS").getInt(null);
+                i |= cwClass.getField("COMPUTE_FRAMES").getInt(null);
+                newCw = cons.newInstance(new Object[] {Integer.valueOf(i)});
+            } catch (Throwable e1) {
+                // ignore
+            }
+        }
+        if (newCw != null) {
+            return ReflectionInvokationHandler.createProxyWrapper(newCw, ClassWriter.class);
+        }
+        return null;
+    }
+
+
+    public ASMType getType(final String type) {
+        try {
+            final Class<?> cls = ClassLoaderUtils.loadClass(cwClass.getPackage().getName() + ".Type", cwClass);
+            final Method m = cls.getMethod("getType", String.class);
+            final Method m2 = cls.getMethod("getOpcode", Integer.TYPE);
+            @SuppressWarnings("unused")
+            ASMType t = new ASMType() {
+                Object tp = ReflectionUtil.setAccessible(m).invoke(null, type);
+                public Object getValue() {
+                    return tp;
+                }
+                public Class<?> realType() {
+                    return cls;
+                }
+                public int getOpcode(int ireturn) {
+                    try {
+                        return (Integer)ReflectionUtil.setAccessible(m2).invoke(tp, ireturn);
+                    } catch (Exception e) {
+                        throw new RuntimeException(e);
+                    }
+                }
+            };
+            return t;
+        } catch (Exception ex) {
+            throw new RuntimeException(ex);
+        }
+    }
+    public Label createLabel() {
+        try {
+            final Class<?> cls = ClassLoaderUtils.loadClass(cwClass.getPackage().getName() + ".Label",
+                    cwClass);
+            @SuppressWarnings("unused")
+            Label l = new Label() {
+                Object l = cls.newInstance();
+                public Object getValue() {
+                    return l;
+                }
+                public Class<?> realType() {
+                    return cls;
+                }
+            };
+            return l;
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+}
diff --git a/core/src/main/java/org/apache/cxf/common/util/OpcodesProxy.java b/core/src/main/java/org/apache/cxf/common/util/OpcodesProxy.java
new file mode 100644
index 0000000..9e6fc72
--- /dev/null
+++ b/core/src/main/java/org/apache/cxf/common/util/OpcodesProxy.java
@@ -0,0 +1,94 @@
+/**
+ * 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.cxf.common.util;
+
+import java.lang.reflect.Field;
+
+import org.apache.cxf.common.classloader.ClassLoaderUtils;
+
+public class OpcodesProxy {
+    //CHECKSTYLE:OFF
+    //Will use reflection to set these based on the package name and such
+    //so we don't want them "final" or the compiler will optimize them out
+    //to just "0" which we really don't want
+    public int ARETURN = 0;
+    public int ALOAD = 0;
+    public int IFNULL = 0;
+    public int CHECKCAST = 0;
+    public int INVOKEINTERFACE = 0;
+    public int GETFIELD = 0;
+    public int GETSTATIC = 0;
+    public int ASTORE = 0;
+    public int PUTFIELD = 0;
+    public int PUTSTATIC = 0;
+    public int RETURN = 0;
+    public int F_APPEND = 0;
+    public int F_SAME = 0;
+    public int F_SAME1 = 0;
+    public int INVOKESPECIAL = 0;
+    public int ACC_PUBLIC = 0;
+    public int ACC_FINAL = 0;
+    public int ACC_SUPER = 0;
+    public int ACC_PRIVATE = 0;
+    public int ACC_STATIC = 0;
+    public int V1_5 = 0;
+    public int V1_6 = 0;
+    public int V1_7 = 0;
+    public int ACC_ABSTRACT = 0;
+    public int ACC_INTERFACE = 0;
+    public int ACC_SYNTHETIC = 0;
+    public int ILOAD = 0;
+    public int ISTORE = 0;
+    public int AALOAD = 0;
+    public int ARRAYLENGTH = 0;
+    public int IRETURN = 0;
+    public int NEW = 0;
+    public int ANEWARRAY = 0;
+    public int DUP = 0;
+    public int ATHROW = 0;
+    public int INVOKEVIRTUAL = 0;
+    public int GOTO = 0;
+    public int POP = 0;
+    public int ACONST_NULL = 0;
+    public int IFNONNULL = 0;
+    public int SIPUSH = 0;
+    public int INVOKESTATIC = 0;
+    public int ICONST_0;
+    public int ICONST_1;
+    public int LCONST_0;
+    public int FCONST_0;
+    public int DCONST_0;
+    public int IF_ICMPLT = 0;
+    public java.lang.Integer INTEGER;
+
+    public OpcodesProxy(ASMHelper helper) {
+        try {
+            Class<?> cls = helper.getASMClass();
+            cls = ClassLoaderUtils.loadClass(cls.getPackage().getName() + ".Opcodes", cls);
+            for (Field f1 : OpcodesProxy.class.getDeclaredFields()) {
+                Field f = cls.getDeclaredField(f1.getName());
+                ReflectionUtil.setAccessible(f1).set(this, ReflectionUtil.setAccessible(f).get(null));
+            }
+        } catch (Throwable e) {
+            //ignore
+        }
+    }
+    //CHECKSTYLE:ON
+}
diff --git a/core/src/main/java/org/apache/cxf/common/util/StringUtils.java b/core/src/main/java/org/apache/cxf/common/util/StringUtils.java
index 2da80a9..9f7c012 100644
--- a/core/src/main/java/org/apache/cxf/common/util/StringUtils.java
+++ b/core/src/main/java/org/apache/cxf/common/util/StringUtils.java
@@ -160,4 +160,18 @@ public final class StringUtils {
         sb.append(HEX[(0xF0 & b) >> 4]);
         sb.append(HEX[0x0F & b]);
     }
+
+    public static String periodToSlashes(String s) {
+        char[] ch = s.toCharArray();
+        for (int x = 0; x < ch.length; x++) {
+            if (ch[x] == '.') {
+                ch[x] = '/';
+            }
+        }
+        return new String(ch);
+    }
+    public static String slashesToPeriod(String s) {
+        return s.replace('/', '.');
+    }
+
 }
diff --git a/core/src/main/resources/META-INF/cxf/bus-extensions.txt b/core/src/main/resources/META-INF/cxf/bus-extensions.txt
index f8e394b..3677c28 100644
--- a/core/src/main/resources/META-INF/cxf/bus-extensions.txt
+++ b/core/src/main/resources/META-INF/cxf/bus-extensions.txt
@@ -9,4 +9,6 @@ org.apache.cxf.bus.managers.ServerLifeCycleManagerImpl:org.apache.cxf.endpoint.S
 org.apache.cxf.bus.managers.ClientLifeCycleManagerImpl:org.apache.cxf.endpoint.ClientLifeCycleManager:true
 org.apache.cxf.bus.resource.ResourceManagerImpl:org.apache.cxf.resource.ResourceManager:true
 org.apache.cxf.catalog.OASISCatalogManager:org.apache.cxf.catalog.OASISCatalogManager:true
+org.apache.cxf.common.util.ASMHelperImpl:org.apache.cxf.common.util.ASMHelper:true
+org.apache.cxf.common.spi.ClassLoaderProxyService:org.apache.cxf.common.spi.ClassLoaderService:true
 
diff --git a/core/src/test/java/org/apache/cxf/common/util/ASMHelperTest.java b/core/src/test/java/org/apache/cxf/common/util/ASMHelperTest.java
index a565ff1..a87b8d5 100644
--- a/core/src/test/java/org/apache/cxf/common/util/ASMHelperTest.java
+++ b/core/src/test/java/org/apache/cxf/common/util/ASMHelperTest.java
@@ -21,9 +21,15 @@ package org.apache.cxf.common.util;
 import java.lang.reflect.Method;
 import java.lang.reflect.Type;
 
+import org.apache.cxf.Bus;
+import org.apache.cxf.bus.extension.ExtensionManagerBus;
+import org.apache.cxf.common.spi.ClassGeneratorClassLoader;
+
 import org.junit.Test;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
 
 public class ASMHelperTest {
     @Test
@@ -32,10 +38,37 @@ public class ASMHelperTest {
             EnumObject.class
         });
         Type[] types = method.getGenericParameterTypes();
-        String classCode = ASMHelper.getClassCode(types[0]);
+        ASMHelper helper = new ASMHelperImpl();
+        String classCode = helper.getClassCode(types[0]);
         assertEquals("Lorg/apache/cxf/common/util/ASMHelperTest$EnumObject<Ljava/lang/Enum;>;", classCode);
     }
 
+    @Test
+    public void testLoader() throws Exception {
+        CustomLoader cl = new CustomLoader(new ExtensionManagerBus());
+        Class<?> clz = cl.createCustom();
+        assertNotNull(clz);
+        assertTrue(cl.isFound());
+    }
+    public class CustomLoader extends ClassGeneratorClassLoader {
+        public CustomLoader(Bus bus) {
+            super(bus);
+        }
+        public Class<?> createCustom() {
+            ASMHelper helper = new ASMHelperImpl();
+            ASMHelper.ClassWriter cw = helper.createClassWriter();
+            OpcodesProxy opCodes = helper.getOpCodes();
+            cw.visit(opCodes.V1_5, opCodes.ACC_PUBLIC + opCodes.ACC_SUPER, "test/testClass", null,
+                    "java/lang/Object", null);
+            cw.visitEnd();
+
+            return loadClass("test.testClass", ASMHelperTest.class, cw.toByteArray());
+        }
+        public boolean isFound() {
+            Class<?> cls = findClass("test.testClass", ASMHelperTest.class);
+            return cls != null;
+        }
+    }
     public class EnumObject<E extends Enum<E>> {
         private String name;
 
diff --git a/parent/pom.xml b/parent/pom.xml
index 219b3ad..666d203 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -54,8 +54,8 @@
         <!-- stuff related to ASM -->
         <cxf.asm.groupId>org.ow2.asm</cxf.asm.groupId>
         <cxf.asm.artifactId>asm</cxf.asm.artifactId>
-        <cxf.asm.version>8.0.1</cxf.asm.version>
-        <cxf.osgi.asm.version>[3.0,9)</cxf.osgi.asm.version>
+        <cxf.asm.version>9.0</cxf.asm.version>
+        <cxf.osgi.asm.version>[3.0,10)</cxf.osgi.asm.version>
         <cxf.easymock.version>4.2</cxf.easymock.version>
         <!-- OSGi related properties -->
         <cxf.fragment.host />
diff --git a/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/CorbaConduit.java b/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/CorbaConduit.java
index 5cc2e0c..f735624 100644
--- a/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/CorbaConduit.java
+++ b/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/CorbaConduit.java
@@ -238,7 +238,7 @@ public class CorbaConduit implements Conduit {
             list = orb.create_list(arguments.length);
 
             for (CorbaStreamable argument : arguments) {
-                Any value = CorbaAnyHelper.createAny(orb);
+                Any value = CorbaAnyHelper.createAny(orb, message.getExchange().getBus());
                 argument.getObject().setIntoAny(value, argument, true);
                 list.add_value(argument.getName(), value, argument.getMode());
             }
@@ -256,7 +256,7 @@ public class CorbaConduit implements Conduit {
         CorbaStreamable retVal = message.getStreamableReturn();
         NamedValue ret = null;
         if (retVal != null) {
-            Any returnAny = CorbaAnyHelper.createAny(orb);
+            Any returnAny = CorbaAnyHelper.createAny(orb, message.getExchange().getBus());
             retVal.getObject().setIntoAny(returnAny, retVal, false);
             ret = orb.create_named_value(retVal.getName(), returnAny, org.omg.CORBA.ARG_OUT.value);
         } else {
diff --git a/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/CorbaServerConduit.java b/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/CorbaServerConduit.java
index cfae928..d67f81b 100644
--- a/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/CorbaServerConduit.java
+++ b/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/CorbaServerConduit.java
@@ -120,7 +120,7 @@ public class CorbaServerConduit implements Conduit {
                 NVList list = inMsg.getList();
 
                 if (msg.getStreamableException() != null) {
-                    Any exAny = CorbaAnyHelper.createAny(orb);
+                    Any exAny = CorbaAnyHelper.createAny(orb, exg.getBus());
                     CorbaStreamable exception = msg.getStreamableException();
                     exAny.insert_Streamable(exception);
                     request.set_exception(exAny);
@@ -140,7 +140,7 @@ public class CorbaServerConduit implements Conduit {
 
                     CorbaStreamable resultValue = msg.getStreamableReturn();
                     if (resultValue != null) {
-                        Any resultAny = CorbaAnyHelper.createAny(orb);
+                        Any resultAny = CorbaAnyHelper.createAny(orb, exg.getBus());
                         resultValue.getObject().setIntoAny(resultAny, resultValue, true);
                         request.set_result(resultAny);
                     }
diff --git a/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/interceptors/CorbaStreamInInterceptor.java b/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/interceptors/CorbaStreamInInterceptor.java
index a237bcf..98defae 100644
--- a/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/interceptors/CorbaStreamInInterceptor.java
+++ b/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/interceptors/CorbaStreamInInterceptor.java
@@ -87,6 +87,7 @@ public class CorbaStreamInInterceptor extends AbstractPhaseInterceptor<Message>
         } else {
             destination = (CorbaDestination)msg.getExchange().getDestination();
         }
+
         service = destination.getBindingInfo().getService();
 
         CorbaMessage message = (CorbaMessage)msg;
@@ -298,7 +299,7 @@ public class CorbaStreamInInterceptor extends AbstractPhaseInterceptor<Message>
                     CorbaHandlerUtils.initializeObjectHandler(orb, paramName, paramIdlType, map, service);
                 streamables[i] = corbaMsg.createStreamableObject(obj, paramName);
 
-                Any value = CorbaAnyHelper.createAny(orb);
+                Any value = CorbaAnyHelper.createAny(orb, corbaMsg.getExchange().getBus());
                 if ("in".equals(paramMode.value())) {
                     streamables[i].setMode(org.omg.CORBA.ARG_IN.value);
                     streamables[i].getObject().setIntoAny(value, streamables[i], false);
diff --git a/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/utils/CorbaAnyHelper.java b/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/utils/CorbaAnyHelper.java
index fe50c1b..5337193 100644
--- a/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/utils/CorbaAnyHelper.java
+++ b/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/utils/CorbaAnyHelper.java
@@ -26,16 +26,11 @@ import java.util.Map;
 
 import javax.xml.namespace.QName;
 
+import org.apache.cxf.Bus;
 import org.apache.cxf.binding.corba.CorbaBindingException;
 import org.apache.cxf.binding.corba.types.CorbaPrimitiveHandler;
 import org.apache.cxf.binding.corba.wsdl.CorbaConstants;
 import org.apache.cxf.binding.corba.wsdl.W3CConstants;
-import org.apache.cxf.common.util.ASMHelper;
-import org.apache.cxf.common.util.ASMHelper.ClassWriter;
-import org.apache.cxf.common.util.ASMHelper.FieldVisitor;
-import org.apache.cxf.common.util.ASMHelper.Label;
-import org.apache.cxf.common.util.ASMHelper.MethodVisitor;
-import org.apache.cxf.common.util.ASMHelper.Opcodes;
 import org.omg.CORBA.Any;
 import org.omg.CORBA.ORB;
 import org.omg.CORBA.TCKind;
@@ -52,10 +47,10 @@ public final class CorbaAnyHelper {
         //utility class
     }
 
-    public static Any createAny(ORB orb) {
+    public static Any createAny(ORB orb, Bus bus) {
         Any value = orb.create_any();
         if ("com.sun.corba.se.impl.corba.AnyImpl".equals(value.getClass().getName())) {
-            value = createFixedAny(orb, value);
+            value = createFixedAny(orb, value, bus);
         }
         return value;
     }
@@ -272,258 +267,21 @@ public final class CorbaAnyHelper {
         IDL_TO_SCHEMA_TYPES.put(CorbaConstants.NT_CORBA_ANY, W3CConstants.NT_SCHEMA_ANYTYPE);
     }
 
-    private static Any createFixedAny(ORB orb, Any any) {
-        createFixedAnyConstructor();
+    private static synchronized Any createFixedAny(ORB orb, Any any, Bus bus) {
+        if (fixedAnyConstructor == null) {
+            CorbaFixedAnyImplClassCreator corbaFixedAnyImplClassCreator =
+                    bus.getExtension(CorbaFixedAnyImplClassCreator.class);
+            Class<?> c = corbaFixedAnyImplClassCreator.createFixedAnyClass();
+            try {
+                fixedAnyConstructor = c.getConstructor(ORB.class, Any.class);
+            } catch (Exception e) {
+                //shouldn't happen since we generated that constructor
+            }
+        }
         try {
             return (Any)fixedAnyConstructor.newInstance(orb, any);
         } catch (Exception e) {
             return any;
         }
     }
-    private static synchronized void createFixedAnyConstructor() {
-        if (fixedAnyConstructor != null) {
-            return;
-        }
-
-        ASMHelper helper = new ASMHelper();
-        ClassWriter cw = helper.createClassWriter();
-        FieldVisitor fv;
-
-        cw.visit(Opcodes.V1_6, Opcodes.ACC_PUBLIC + Opcodes.ACC_SUPER,
-                 "org/apache/cxf/binding/corba/utils/FixedAnyImpl",
-                 null, "com/sun/corba/se/impl/corba/AnyImpl", null);
-
-        cw.visitSource("FixedAnyImpl.java", null);
-
-        fv = cw.visitField(0, "obj", "Lorg/omg/CORBA/portable/Streamable;", null, null);
-        fv.visitEnd();
-        addFixedAnyConstructor(helper, cw);
-        addInsertOverride(helper, cw);
-        addExtractOverride(helper, cw);
-        addWriteOverride(helper, cw);
-        addReadOverride(helper, cw);
-
-        cw.visitEnd();
-
-        byte[] b = cw.toByteArray();
-        Class<?> c = helper.loadClass("org.apache.cxf.binding.corba.utils.FixedAnyImpl",
-                                      CorbaAnyHelper.class, b);
-        try {
-            fixedAnyConstructor = c.getConstructor(ORB.class, Any.class);
-        } catch (Exception e) {
-            //shouldn't happen since we generated that constructor
-        }
-    }
-
-    private static void addReadOverride(ASMHelper helper, ClassWriter cw) {
-        MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "read_value",
-                            "(Lorg/omg/CORBA/portable/InputStream;Lorg/omg/CORBA/TypeCode;)V",
-                            null, null);
-        mv.visitCode();
-        Label l0 = helper.createLabel();
-        mv.visitLabel(l0);
-        mv.visitLineNumber(54, l0);
-        mv.visitVarInsn(Opcodes.ALOAD, 0);
-        mv.visitFieldInsn(Opcodes.GETFIELD, "org/apache/cxf/binding/corba/utils/FixedAnyImpl",
-                          "obj", "Lorg/omg/CORBA/portable/Streamable;");
-        Label l1 = helper.createLabel();
-        mv.visitJumpInsn(Opcodes.IFNULL, l1);
-        Label l2 = helper.createLabel();
-        mv.visitLabel(l2);
-        mv.visitLineNumber(55, l2);
-        mv.visitVarInsn(Opcodes.ALOAD, 0);
-        mv.visitFieldInsn(Opcodes.GETFIELD, "org/apache/cxf/binding/corba/utils/FixedAnyImpl",
-                          "obj", "Lorg/omg/CORBA/portable/Streamable;");
-        mv.visitVarInsn(Opcodes.ALOAD, 1);
-        mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "org/omg/CORBA/portable/Streamable",
-                           "_read", "(Lorg/omg/CORBA/portable/InputStream;)V", true);
-        Label l3 = helper.createLabel();
-        mv.visitJumpInsn(Opcodes.GOTO, l3);
-        mv.visitLabel(l1);
-        mv.visitLineNumber(57, l1);
-        mv.visitVarInsn(Opcodes.ALOAD, 0);
-        mv.visitVarInsn(Opcodes.ALOAD, 1);
-        mv.visitVarInsn(Opcodes.ALOAD, 2);
-        mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "com/sun/corba/se/impl/corba/AnyImpl",
-                           "read_value",
-                           "(Lorg/omg/CORBA/portable/InputStream;Lorg/omg/CORBA/TypeCode;)V", false);
-        mv.visitLabel(l3);
-        mv.visitLineNumber(59, l3);
-        mv.visitInsn(Opcodes.RETURN);
-        Label l4 = helper.createLabel();
-        mv.visitLabel(l4);
-        mv.visitLocalVariable("this", "Lorg/apache/cxf/binding/corba/utils/FixedAnyImpl;",
-                              null, l0, l4, 0);
-        mv.visitLocalVariable("is", "Lorg/omg/CORBA/portable/InputStream;", null, l0, l4, 1);
-        mv.visitLocalVariable("t", "Lorg/omg/CORBA/TypeCode;", null, l0, l4, 2);
-        mv.visitMaxs(3, 3);
-        mv.visitEnd();
-    }
-
-    private static void addWriteOverride(ASMHelper helper, ClassWriter cw) {
-        MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "write_value",
-                            "(Lorg/omg/CORBA/portable/OutputStream;)V", null, null);
-        mv.visitCode();
-        Label l0 = helper.createLabel();
-        mv.visitLabel(l0);
-        mv.visitLineNumber(61, l0);
-        mv.visitVarInsn(Opcodes.ALOAD, 0);
-        mv.visitFieldInsn(Opcodes.GETFIELD, "org/apache/cxf/binding/corba/utils/FixedAnyImpl",
-                          "obj", "Lorg/omg/CORBA/portable/Streamable;");
-        Label l1 = helper.createLabel();
-        mv.visitJumpInsn(Opcodes.IFNULL, l1);
-        Label l2 = helper.createLabel();
-        mv.visitLabel(l2);
-        mv.visitLineNumber(62, l2);
-        mv.visitVarInsn(Opcodes.ALOAD, 0);
-        mv.visitFieldInsn(Opcodes.GETFIELD, "org/apache/cxf/binding/corba/utils/FixedAnyImpl",
-                          "obj", "Lorg/omg/CORBA/portable/Streamable;");
-
-        Label l3 = helper.createLabel();
-        mv.visitVarInsn(Opcodes.ALOAD, 1);
-        mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "org/omg/CORBA/portable/Streamable",
-                           "_write", "(Lorg/omg/CORBA/portable/OutputStream;)V", true);
-        mv.visitJumpInsn(Opcodes.GOTO, l3);
-        mv.visitLabel(l1);
-        mv.visitLineNumber(64, l1);
-        mv.visitVarInsn(Opcodes.ALOAD, 0);
-        mv.visitVarInsn(Opcodes.ALOAD, 1);
-        mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "com/sun/corba/se/impl/corba/AnyImpl",
-                           "write_value", "(Lorg/omg/CORBA/portable/OutputStream;)V", false);
-        mv.visitLabel(l3);
-        mv.visitLineNumber(66, l3);
-        mv.visitInsn(Opcodes.RETURN);
-        Label l4 = helper.createLabel();
-        mv.visitLabel(l4);
-        mv.visitLocalVariable("this", "Lorg/apache/cxf/binding/corba/utils/FixedAnyImpl;",
-                              null, l0, l4, 0);
-        mv.visitLocalVariable("os", "Lorg/omg/CORBA/portable/OutputStream;", null, l0, l4, 1);
-        mv.visitMaxs(2, 2);
-        mv.visitEnd();
-
-    }
-
-    private static void addExtractOverride(ASMHelper helper, ClassWriter cw) {
-        MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "extract_Streamable",
-                            "()Lorg/omg/CORBA/portable/Streamable;", null, null);
-        mv.visitCode();
-        Label l0 = helper.createLabel();
-        mv.visitLabel(l0);
-        mv.visitLineNumber(47, l0);
-        mv.visitVarInsn(Opcodes.ALOAD, 0);
-        mv.visitFieldInsn(Opcodes.GETFIELD, "org/apache/cxf/binding/corba/utils/FixedAnyImpl",
-                          "obj", "Lorg/omg/CORBA/portable/Streamable;");
-        Label l1 = helper.createLabel();
-        mv.visitJumpInsn(Opcodes.IFNULL, l1);
-        Label l2 = helper.createLabel();
-        mv.visitLabel(l2);
-        mv.visitLineNumber(48, l2);
-        mv.visitVarInsn(Opcodes.ALOAD, 0);
-        mv.visitFieldInsn(Opcodes.GETFIELD, "org/apache/cxf/binding/corba/utils/FixedAnyImpl",
-                          "obj", "Lorg/omg/CORBA/portable/Streamable;");
-        mv.visitInsn(Opcodes.ARETURN);
-        mv.visitLabel(l1);
-        mv.visitLineNumber(50, l1);
-        mv.visitVarInsn(Opcodes.ALOAD, 0);
-        mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "com/sun/corba/se/impl/corba/AnyImpl",
-                           "extract_Streamable", "()Lorg/omg/CORBA/portable/Streamable;", false);
-        mv.visitInsn(Opcodes.ARETURN);
-        Label l3 = helper.createLabel();
-        mv.visitLabel(l3);
-        mv.visitLocalVariable("this", "Lorg/apache/cxf/binding/corba/utils/FixedAnyImpl;", null, l0, l3, 0);
-        mv.visitMaxs(1, 1);
-        mv.visitEnd();
-
-    }
-
-    private static void addInsertOverride(ASMHelper helper, ClassWriter cw) {
-        MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC,
-                            "insert_Streamable",
-                            "(Lorg/omg/CORBA/portable/Streamable;)V", null, null);
-        mv.visitCode();
-        Label l0 = helper.createLabel();
-        mv.visitLabel(l0);
-        mv.visitLineNumber(43, l0);
-        mv.visitVarInsn(Opcodes.ALOAD, 0);
-        mv.visitVarInsn(Opcodes.ALOAD, 1);
-        mv.visitMethodInsn(Opcodes.INVOKESPECIAL,
-                           "com/sun/corba/se/impl/corba/AnyImpl",
-                           "insert_Streamable",
-                           "(Lorg/omg/CORBA/portable/Streamable;)V", false);
-        Label l1 = helper.createLabel();
-        mv.visitLabel(l1);
-        mv.visitLineNumber(44, l1);
-        mv.visitVarInsn(Opcodes.ALOAD, 0);
-        mv.visitVarInsn(Opcodes.ALOAD, 1);
-        mv.visitFieldInsn(Opcodes.PUTFIELD,
-                          "org/apache/cxf/binding/corba/utils/FixedAnyImpl", "obj",
-                          "Lorg/omg/CORBA/portable/Streamable;");
-        Label l2 = helper.createLabel();
-        mv.visitLabel(l2);
-        mv.visitLineNumber(45, l2);
-        mv.visitInsn(Opcodes.RETURN);
-        Label l3 = helper.createLabel();
-        mv.visitLabel(l3);
-        mv.visitLocalVariable("this", "Lorg/apache/cxf/binding/corba/utils/FixedAnyImpl;",
-                              null, l0, l3, 0);
-        mv.visitLocalVariable("s", "Lorg/omg/CORBA/portable/Streamable;", null, l0, l3, 1);
-        mv.visitMaxs(2, 2);
-        mv.visitEnd();
-    }
-
-    private static void addFixedAnyConstructor(ASMHelper helper, ClassWriter cw) {
-        MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "(Lorg/omg/CORBA/ORB;)V", null, null);
-        mv.visitCode();
-        Label l0 = helper.createLabel();
-        mv.visitLabel(l0);
-        mv.visitLineNumber(36, l0);
-        mv.visitVarInsn(Opcodes.ALOAD, 0);
-        mv.visitVarInsn(Opcodes.ALOAD, 1);
-        mv.visitTypeInsn(Opcodes.CHECKCAST, "com/sun/corba/se/spi/orb/ORB");
-        mv.visitMethodInsn(Opcodes.INVOKESPECIAL,
-                           "com/sun/corba/se/impl/corba/AnyImpl",
-                           "<init>", "(Lcom/sun/corba/se/spi/orb/ORB;)V", false);
-        Label l1 = helper.createLabel();
-        mv.visitLabel(l1);
-        mv.visitLineNumber(37, l1);
-        mv.visitInsn(Opcodes.RETURN);
-        Label l2 = helper.createLabel();
-        mv.visitLabel(l2);
-        mv.visitLocalVariable("this",
-                              "Lorg/apache/cxf/binding/corba/utils/FixedAnyImpl;",
-                              null, l0, l2, 0);
-        mv.visitLocalVariable("orb", "Lorg/omg/CORBA/ORB;", null, l0, l2, 1);
-        mv.visitMaxs(2, 2);
-        mv.visitEnd();
-
-
-        mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>",
-                            "(Lorg/omg/CORBA/ORB;Lorg/omg/CORBA/Any;)V",
-                            null, null);
-        mv.visitCode();
-        l0 = helper.createLabel();
-        mv.visitLabel(l0);
-        mv.visitLineNumber(39, l0);
-        mv.visitVarInsn(Opcodes.ALOAD, 0);
-        mv.visitVarInsn(Opcodes.ALOAD, 1);
-        mv.visitTypeInsn(Opcodes.CHECKCAST, "com/sun/corba/se/spi/orb/ORB");
-        mv.visitVarInsn(Opcodes.ALOAD, 2);
-        mv.visitMethodInsn(Opcodes.INVOKESPECIAL,
-                           "com/sun/corba/se/impl/corba/AnyImpl",
-                           "<init>",
-                           "(Lcom/sun/corba/se/spi/orb/ORB;Lorg/omg/CORBA/Any;)V", false);
-        l1 = helper.createLabel();
-        mv.visitLabel(l1);
-        mv.visitLineNumber(40, l1);
-        mv.visitInsn(Opcodes.RETURN);
-        l2 = helper.createLabel();
-        mv.visitLabel(l2);
-        mv.visitLocalVariable("this", "Lorg/apache/cxf/binding/corba/utils/FixedAnyImpl;",
-                              null, l0, l2, 0);
-        mv.visitLocalVariable("orb", "Lorg/omg/CORBA/ORB;", null, l0, l2, 1);
-        mv.visitLocalVariable("any", "Lorg/omg/CORBA/Any;", null, l0, l2, 2);
-        mv.visitMaxs(3, 3);
-        mv.visitEnd();
-
-    }
 }
diff --git a/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/utils/CorbaFixedAnyImplClassCreator.java b/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/utils/CorbaFixedAnyImplClassCreator.java
new file mode 100644
index 0000000..6134f09
--- /dev/null
+++ b/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/utils/CorbaFixedAnyImplClassCreator.java
@@ -0,0 +1,23 @@
+/**
+ * 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.cxf.binding.corba.utils;
+
+public interface CorbaFixedAnyImplClassCreator {
+    Class<?> createFixedAnyClass();
+}
diff --git a/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/utils/CorbaFixedAnyImplClassCreatorProxyService.java b/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/utils/CorbaFixedAnyImplClassCreatorProxyService.java
new file mode 100644
index 0000000..bcdb1ca
--- /dev/null
+++ b/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/utils/CorbaFixedAnyImplClassCreatorProxyService.java
@@ -0,0 +1,48 @@
+/**
+ * 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.cxf.binding.corba.utils;
+
+import org.apache.cxf.Bus;
+
+public class CorbaFixedAnyImplClassCreatorProxyService implements CorbaFixedAnyImplClassCreator {
+    private final CorbaFixedAnyImplClassCreator srv;
+    public CorbaFixedAnyImplClassCreatorProxyService(Bus bus) {
+        this(new CorbaFixedAnyImplGenerator(bus));
+    }
+    public CorbaFixedAnyImplClassCreatorProxyService(CorbaFixedAnyImplClassCreator srv) {
+        super();
+        this.srv = srv;
+    }
+
+    @Override
+    public Class<?> createFixedAnyClass() {
+        return srv.createFixedAnyClass();
+    }
+
+    public class LoadFirst extends CorbaFixedAnyImplClassCreatorProxyService {
+        public LoadFirst(Bus bus) {
+            super(new CorbaFixedAnyImplClassLoader(bus));
+        }
+    }
+    public class GenerateJustInTime extends CorbaFixedAnyImplClassCreatorProxyService {
+        public GenerateJustInTime(Bus bus) {
+            super(new CorbaFixedAnyImplGenerator(bus));
+        }
+    }
+}
\ No newline at end of file
diff --git a/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/utils/CorbaFixedAnyImplClassLoader.java b/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/utils/CorbaFixedAnyImplClassLoader.java
new file mode 100644
index 0000000..b56b666
--- /dev/null
+++ b/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/utils/CorbaFixedAnyImplClassLoader.java
@@ -0,0 +1,35 @@
+/**
+ * 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.cxf.binding.corba.utils;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.common.spi.GeneratedClassClassLoader;
+
+public class CorbaFixedAnyImplClassLoader extends GeneratedClassClassLoader implements CorbaFixedAnyImplClassCreator {
+
+    public CorbaFixedAnyImplClassLoader(Bus bus) {
+        super(bus);
+    }
+
+    @Override
+    public Class<?> createFixedAnyClass() {
+        String newClassName = "org.apache.cxf.binding.corba.utils.FixedAnyImpl";
+        return findClass(newClassName, CorbaFixedAnyImplClassLoader.class);
+    }
+}
diff --git a/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/utils/CorbaFixedAnyImplGenerator.java b/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/utils/CorbaFixedAnyImplGenerator.java
new file mode 100644
index 0000000..36b3205
--- /dev/null
+++ b/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/utils/CorbaFixedAnyImplGenerator.java
@@ -0,0 +1,276 @@
+/**
+ * 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.cxf.binding.corba.utils;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.common.spi.ClassGeneratorClassLoader;
+import org.apache.cxf.common.util.ASMHelper;
+import org.apache.cxf.common.util.OpcodesProxy;
+
+public class CorbaFixedAnyImplGenerator extends ClassGeneratorClassLoader implements CorbaFixedAnyImplClassCreator {
+
+    public CorbaFixedAnyImplGenerator(Bus bus) {
+        super(bus);
+    }
+    public Class<?> createFixedAnyClass() {
+        ASMHelper helper = bus.getExtension(ASMHelper.class);
+        OpcodesProxy opCodes = helper.getOpCodes();
+        ASMHelper.ClassWriter cw = helper.createClassWriter();
+        ASMHelper.FieldVisitor fv;
+
+        cw.visit(opCodes.V1_6, opCodes.ACC_PUBLIC + opCodes.ACC_SUPER,
+                "org/apache/cxf/binding/corba/utils/FixedAnyImpl",
+                null, "com/sun/corba/se/impl/corba/AnyImpl", null);
+
+        cw.visitSource("FixedAnyImpl.java", null);
+
+        fv = cw.visitField(0, "obj", "Lorg/omg/CORBA/portable/Streamable;", null, null);
+        fv.visitEnd();
+        addFixedAnyConstructor(helper, cw);
+        addInsertOverride(helper, cw);
+        addExtractOverride(helper, cw);
+        addWriteOverride(helper, cw);
+        addReadOverride(helper, cw);
+
+        cw.visitEnd();
+
+        byte[] b = cw.toByteArray();
+        Class<?> c = loadClass("org.apache.cxf.binding.corba.utils.FixedAnyImpl",
+                CorbaFixedAnyImplGenerator.class, b);
+        return c;
+    }
+
+    private void addReadOverride(ASMHelper helper, ASMHelper.ClassWriter cw) {
+        OpcodesProxy opCodes = helper.getOpCodes();
+        ASMHelper.MethodVisitor mv = cw.visitMethod(opCodes.ACC_PUBLIC, "read_value",
+                "(Lorg/omg/CORBA/portable/InputStream;Lorg/omg/CORBA/TypeCode;)V",
+                null, null);
+        mv.visitCode();
+        ASMHelper.Label l0 = helper.createLabel();
+        mv.visitLabel(l0);
+        mv.visitLineNumber(54, l0);
+        mv.visitVarInsn(opCodes.ALOAD, 0);
+        mv.visitFieldInsn(opCodes.GETFIELD, "org/apache/cxf/binding/corba/utils/FixedAnyImpl",
+                "obj", "Lorg/omg/CORBA/portable/Streamable;");
+        ASMHelper.Label l1 = helper.createLabel();
+        mv.visitJumpInsn(opCodes.IFNULL, l1);
+        ASMHelper.Label l2 = helper.createLabel();
+        mv.visitLabel(l2);
+        mv.visitLineNumber(55, l2);
+        mv.visitVarInsn(opCodes.ALOAD, 0);
+        mv.visitFieldInsn(opCodes.GETFIELD, "org/apache/cxf/binding/corba/utils/FixedAnyImpl",
+                "obj", "Lorg/omg/CORBA/portable/Streamable;");
+        mv.visitVarInsn(opCodes.ALOAD, 1);
+        mv.visitMethodInsn(opCodes.INVOKEINTERFACE, "org/omg/CORBA/portable/Streamable",
+                "_read", "(Lorg/omg/CORBA/portable/InputStream;)V", true);
+        ASMHelper.Label l3 = helper.createLabel();
+        mv.visitJumpInsn(opCodes.GOTO, l3);
+        mv.visitLabel(l1);
+        mv.visitLineNumber(57, l1);
+        mv.visitVarInsn(opCodes.ALOAD, 0);
+        mv.visitVarInsn(opCodes.ALOAD, 1);
+        mv.visitVarInsn(opCodes.ALOAD, 2);
+        mv.visitMethodInsn(opCodes.INVOKESPECIAL, "com/sun/corba/se/impl/corba/AnyImpl",
+                "read_value",
+                "(Lorg/omg/CORBA/portable/InputStream;Lorg/omg/CORBA/TypeCode;)V", false);
+        mv.visitLabel(l3);
+        mv.visitLineNumber(59, l3);
+        mv.visitInsn(opCodes.RETURN);
+        ASMHelper.Label l4 = helper.createLabel();
+        mv.visitLabel(l4);
+        mv.visitLocalVariable("this", "Lorg/apache/cxf/binding/corba/utils/FixedAnyImpl;",
+                null, l0, l4, 0);
+        mv.visitLocalVariable("is", "Lorg/omg/CORBA/portable/InputStream;", null, l0, l4, 1);
+        mv.visitLocalVariable("t", "Lorg/omg/CORBA/TypeCode;", null, l0, l4, 2);
+        mv.visitMaxs(0, 0);
+        mv.visitEnd();
+    }
+
+    private void addWriteOverride(ASMHelper helper, ASMHelper.ClassWriter cw) {
+        OpcodesProxy opCodes = helper.getOpCodes();
+        ASMHelper.MethodVisitor mv = cw.visitMethod(opCodes.ACC_PUBLIC, "write_value",
+                "(Lorg/omg/CORBA/portable/OutputStream;)V", null, null);
+        mv.visitCode();
+        ASMHelper.Label l0 = helper.createLabel();
+        mv.visitLabel(l0);
+        mv.visitLineNumber(61, l0);
+        mv.visitVarInsn(opCodes.ALOAD, 0);
+        mv.visitFieldInsn(opCodes.GETFIELD, "org/apache/cxf/binding/corba/utils/FixedAnyImpl",
+                "obj", "Lorg/omg/CORBA/portable/Streamable;");
+        ASMHelper.Label l1 = helper.createLabel();
+        mv.visitJumpInsn(opCodes.IFNULL, l1);
+        ASMHelper.Label l2 = helper.createLabel();
+        mv.visitLabel(l2);
+        mv.visitLineNumber(62, l2);
+        mv.visitVarInsn(opCodes.ALOAD, 0);
+        mv.visitFieldInsn(opCodes.GETFIELD, "org/apache/cxf/binding/corba/utils/FixedAnyImpl",
+                "obj", "Lorg/omg/CORBA/portable/Streamable;");
+
+        ASMHelper.Label l3 = helper.createLabel();
+        mv.visitVarInsn(opCodes.ALOAD, 1);
+        mv.visitMethodInsn(opCodes.INVOKEINTERFACE, "org/omg/CORBA/portable/Streamable",
+                "_write", "(Lorg/omg/CORBA/portable/OutputStream;)V", true);
+        mv.visitJumpInsn(opCodes.GOTO, l3);
+        mv.visitLabel(l1);
+        mv.visitLineNumber(64, l1);
+        mv.visitVarInsn(opCodes.ALOAD, 0);
+        mv.visitVarInsn(opCodes.ALOAD, 1);
+        mv.visitMethodInsn(opCodes.INVOKESPECIAL, "com/sun/corba/se/impl/corba/AnyImpl",
+                "write_value", "(Lorg/omg/CORBA/portable/OutputStream;)V", false);
+        mv.visitLabel(l3);
+        mv.visitLineNumber(66, l3);
+        mv.visitInsn(opCodes.RETURN);
+        ASMHelper.Label l4 = helper.createLabel();
+        mv.visitLabel(l4);
+        mv.visitLocalVariable("this", "Lorg/apache/cxf/binding/corba/utils/FixedAnyImpl;",
+                null, l0, l4, 0);
+        mv.visitLocalVariable("os", "Lorg/omg/CORBA/portable/OutputStream;", null, l0, l4, 1);
+        mv.visitMaxs(0, 0);
+        mv.visitEnd();
+
+    }
+
+    private void addExtractOverride(ASMHelper helper, ASMHelper.ClassWriter cw) {
+        OpcodesProxy opCodes = helper.getOpCodes();
+        ASMHelper.MethodVisitor mv = cw.visitMethod(opCodes.ACC_PUBLIC, "extract_Streamable",
+                "()Lorg/omg/CORBA/portable/Streamable;", null, null);
+        mv.visitCode();
+        ASMHelper.Label l0 = helper.createLabel();
+        mv.visitLabel(l0);
+        mv.visitLineNumber(47, l0);
+        mv.visitVarInsn(opCodes.ALOAD, 0);
+        mv.visitFieldInsn(opCodes.GETFIELD, "org/apache/cxf/binding/corba/utils/FixedAnyImpl",
+                "obj", "Lorg/omg/CORBA/portable/Streamable;");
+        ASMHelper.Label l1 = helper.createLabel();
+        mv.visitJumpInsn(opCodes.IFNULL, l1);
+        ASMHelper.Label l2 = helper.createLabel();
+        mv.visitLabel(l2);
+        mv.visitLineNumber(48, l2);
+        mv.visitVarInsn(opCodes.ALOAD, 0);
+        mv.visitFieldInsn(opCodes.GETFIELD, "org/apache/cxf/binding/corba/utils/FixedAnyImpl",
+                "obj", "Lorg/omg/CORBA/portable/Streamable;");
+        mv.visitInsn(opCodes.ARETURN);
+        mv.visitLabel(l1);
+        mv.visitLineNumber(50, l1);
+        mv.visitVarInsn(opCodes.ALOAD, 0);
+        mv.visitMethodInsn(opCodes.INVOKESPECIAL, "com/sun/corba/se/impl/corba/AnyImpl",
+                "extract_Streamable", "()Lorg/omg/CORBA/portable/Streamable;", false);
+        mv.visitInsn(opCodes.ARETURN);
+        ASMHelper.Label l3 = helper.createLabel();
+        mv.visitLabel(l3);
+        mv.visitLocalVariable("this", "Lorg/apache/cxf/binding/corba/utils/FixedAnyImpl;", null, l0, l3, 0);
+        mv.visitMaxs(0, 0);
+        mv.visitEnd();
+
+    }
+
+    private void addInsertOverride(ASMHelper helper, ASMHelper.ClassWriter cw) {
+        OpcodesProxy opCodes = helper.getOpCodes();
+        ASMHelper.MethodVisitor mv = cw.visitMethod(opCodes.ACC_PUBLIC,
+                "insert_Streamable",
+                "(Lorg/omg/CORBA/portable/Streamable;)V", null, null);
+        mv.visitCode();
+        ASMHelper.Label l0 = helper.createLabel();
+        mv.visitLabel(l0);
+        mv.visitLineNumber(43, l0);
+        mv.visitVarInsn(opCodes.ALOAD, 0);
+        mv.visitVarInsn(opCodes.ALOAD, 1);
+        mv.visitMethodInsn(opCodes.INVOKESPECIAL,
+                "com/sun/corba/se/impl/corba/AnyImpl",
+                "insert_Streamable",
+                "(Lorg/omg/CORBA/portable/Streamable;)V", false);
+        ASMHelper.Label l1 = helper.createLabel();
+        mv.visitLabel(l1);
+        mv.visitLineNumber(44, l1);
+        mv.visitVarInsn(opCodes.ALOAD, 0);
+        mv.visitVarInsn(opCodes.ALOAD, 1);
+        mv.visitFieldInsn(opCodes.PUTFIELD,
+                "org/apache/cxf/binding/corba/utils/FixedAnyImpl", "obj",
+                "Lorg/omg/CORBA/portable/Streamable;");
+        ASMHelper.Label l2 = helper.createLabel();
+        mv.visitLabel(l2);
+        mv.visitLineNumber(45, l2);
+        mv.visitInsn(opCodes.RETURN);
+        ASMHelper.Label l3 = helper.createLabel();
+        mv.visitLabel(l3);
+        mv.visitLocalVariable("this", "Lorg/apache/cxf/binding/corba/utils/FixedAnyImpl;",
+                null, l0, l3, 0);
+        mv.visitLocalVariable("s", "Lorg/omg/CORBA/portable/Streamable;", null, l0, l3, 1);
+        mv.visitMaxs(0, 0);
+        mv.visitEnd();
+    }
+
+    private void addFixedAnyConstructor(ASMHelper helper, ASMHelper.ClassWriter cw) {
+        OpcodesProxy opCodes = helper.getOpCodes();
+        ASMHelper.MethodVisitor mv = cw.visitMethod(opCodes.ACC_PUBLIC, "<init>", "(Lorg/omg/CORBA/ORB;)V", null, null);
+        mv.visitCode();
+        ASMHelper.Label l0 = helper.createLabel();
+        mv.visitLabel(l0);
+        mv.visitLineNumber(36, l0);
+        mv.visitVarInsn(opCodes.ALOAD, 0);
+        mv.visitVarInsn(opCodes.ALOAD, 1);
+        mv.visitTypeInsn(opCodes.CHECKCAST, "com/sun/corba/se/spi/orb/ORB");
+        mv.visitMethodInsn(opCodes.INVOKESPECIAL,
+                "com/sun/corba/se/impl/corba/AnyImpl",
+                "<init>", "(Lcom/sun/corba/se/spi/orb/ORB;)V", false);
+        ASMHelper.Label l1 = helper.createLabel();
+        mv.visitLabel(l1);
+        mv.visitLineNumber(37, l1);
+        mv.visitInsn(opCodes.RETURN);
+        ASMHelper.Label l2 = helper.createLabel();
+        mv.visitLabel(l2);
+        mv.visitLocalVariable("this",
+                "Lorg/apache/cxf/binding/corba/utils/FixedAnyImpl;",
+                null, l0, l2, 0);
+        mv.visitLocalVariable("orb", "Lorg/omg/CORBA/ORB;", null, l0, l2, 1);
+        mv.visitMaxs(0, 0);
+        mv.visitEnd();
+
+
+        mv = cw.visitMethod(opCodes.ACC_PUBLIC, "<init>",
+                "(Lorg/omg/CORBA/ORB;Lorg/omg/CORBA/Any;)V",
+                null, null);
+        mv.visitCode();
+        l0 = helper.createLabel();
+        mv.visitLabel(l0);
+        mv.visitLineNumber(39, l0);
+        mv.visitVarInsn(opCodes.ALOAD, 0);
+        mv.visitVarInsn(opCodes.ALOAD, 1);
+        mv.visitTypeInsn(opCodes.CHECKCAST, "com/sun/corba/se/spi/orb/ORB");
+        mv.visitVarInsn(opCodes.ALOAD, 2);
+        mv.visitMethodInsn(opCodes.INVOKESPECIAL,
+                "com/sun/corba/se/impl/corba/AnyImpl",
+                "<init>",
+                "(Lcom/sun/corba/se/spi/orb/ORB;Lorg/omg/CORBA/Any;)V", false);
+        l1 = helper.createLabel();
+        mv.visitLabel(l1);
+        mv.visitLineNumber(40, l1);
+        mv.visitInsn(opCodes.RETURN);
+        l2 = helper.createLabel();
+        mv.visitLabel(l2);
+        mv.visitLocalVariable("this", "Lorg/apache/cxf/binding/corba/utils/FixedAnyImpl;",
+                null, l0, l2, 0);
+        mv.visitLocalVariable("orb", "Lorg/omg/CORBA/ORB;", null, l0, l2, 1);
+        mv.visitLocalVariable("any", "Lorg/omg/CORBA/Any;", null, l0, l2, 2);
+        mv.visitMaxs(0, 0);
+        mv.visitEnd();
+
+    }
+}
diff --git a/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/wsdl/WSDLExtensionRegister.java b/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/wsdl/WSDLExtensionRegister.java
index 2365d1c..b07c611 100644
--- a/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/wsdl/WSDLExtensionRegister.java
+++ b/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/wsdl/WSDLExtensionRegister.java
@@ -33,8 +33,10 @@ import org.apache.cxf.wsdl.WSDLManager;
 @NoJSR250Annotations
 public final class WSDLExtensionRegister implements WSDLExtensionLoader {
     private static final String YOKO_NAMESPACE = "http://schemas.apache.org/yoko/bindings/corba";
+    private final Bus bus;
 
     public WSDLExtensionRegister(Bus b) {
+        this.bus = b;
         WSDLManager manager = b.getExtension(WSDLManager.class);
         registerCXFExtensors(manager);
         registerYokoCompatibleExtensors(manager);
@@ -68,7 +70,7 @@ public final class WSDLExtensionRegister implements WSDLExtensionLoader {
                                 Class<?> parentType,
                                 Class<?> elementType) {
         try {
-            JAXBExtensionHelper.addExtensions(manager.getExtensionRegistry(),
+            JAXBExtensionHelper.addExtensions(bus, manager.getExtensionRegistry(),
                                               parentType,
                                               elementType,
                                               null,
@@ -83,7 +85,7 @@ public final class WSDLExtensionRegister implements WSDLExtensionLoader {
                                       Class<?> parentType,
                                       Class<?> elementType) {
         try {
-            JAXBExtensionHelper.addExtensions(manager.getExtensionRegistry(),
+            JAXBExtensionHelper.addExtensions(bus, manager.getExtensionRegistry(),
                                               parentType,
                                               elementType,
                                               YOKO_NAMESPACE);
diff --git a/rt/bindings/corba/src/main/resources/META-INF/cxf/bus-extensions.txt b/rt/bindings/corba/src/main/resources/META-INF/cxf/bus-extensions.txt
index 7cd5d2e..c26c985 100644
--- a/rt/bindings/corba/src/main/resources/META-INF/cxf/bus-extensions.txt
+++ b/rt/bindings/corba/src/main/resources/META-INF/cxf/bus-extensions.txt
@@ -1,2 +1,3 @@
 org.apache.cxf.binding.corba.CorbaBindingFactory::true
 org.apache.cxf.binding.corba.wsdl.WSDLExtensionRegister::true
+org.apache.cxf.binding.corba.utils.CorbaFixedAnyImplClassCreatorProxyService:org.apache.cxf.binding.corba.utils.CorbaFixedAnyImplClassCreator:true
diff --git a/rt/bindings/corba/src/test/java/org/apache/cxf/binding/corba/CorbaConduitTest.java b/rt/bindings/corba/src/test/java/org/apache/cxf/binding/corba/CorbaConduitTest.java
index d413e77..3fc47fc 100644
--- a/rt/bindings/corba/src/test/java/org/apache/cxf/binding/corba/CorbaConduitTest.java
+++ b/rt/bindings/corba/src/test/java/org/apache/cxf/binding/corba/CorbaConduitTest.java
@@ -35,6 +35,7 @@ import org.apache.cxf.binding.corba.wsdl.OperationType;
 import org.apache.cxf.binding.corba.wsdl.RaisesType;
 import org.apache.cxf.binding.corba.wsdl.TypeMappingType;
 import org.apache.cxf.message.Exchange;
+import org.apache.cxf.message.ExchangeImpl;
 import org.apache.cxf.message.Message;
 import org.apache.cxf.message.MessageImpl;
 import org.apache.cxf.service.Service;
@@ -251,6 +252,9 @@ public class CorbaConduitTest {
     public void testBuildArguments() throws Exception {
         Message msg = new MessageImpl();
         CorbaMessage message = new CorbaMessage(msg);
+        Exchange exchange = new ExchangeImpl();
+        exchange.put(Bus.class, bus);
+        message.setExchange(exchange);
         CorbaStreamable[] arguments = new CorbaStreamable[1];
         QName objName = new QName("object");
         QName objIdlType = new QName(CorbaConstants.NU_WSDL_CORBA, "short", CorbaConstants.NP_WSDL_CORBA);
@@ -277,6 +281,9 @@ public class CorbaConduitTest {
     public void testBuildReturn() throws Exception {
         Message msg = new MessageImpl();
         CorbaMessage message = new CorbaMessage(msg);
+        Exchange exchange = new ExchangeImpl();
+        exchange.put(Bus.class, bus);
+        message.setExchange(exchange);
 
         QName objName = new QName("returnName");
         QName objIdlType = new QName(CorbaConstants.NU_WSDL_CORBA, "short", CorbaConstants.NP_WSDL_CORBA);
diff --git a/rt/bindings/corba/src/test/java/org/apache/cxf/binding/corba/CorbaServerConduitTest.java b/rt/bindings/corba/src/test/java/org/apache/cxf/binding/corba/CorbaServerConduitTest.java
index e89f7a6..cefef33 100644
--- a/rt/bindings/corba/src/test/java/org/apache/cxf/binding/corba/CorbaServerConduitTest.java
+++ b/rt/bindings/corba/src/test/java/org/apache/cxf/binding/corba/CorbaServerConduitTest.java
@@ -235,9 +235,12 @@ public class CorbaServerConduitTest {
         EasyMock.expect(exchange.get(ServerRequest.class)).andReturn(request);
 
         EasyMock.expect(exchange.isOneWay()).andReturn(false);
+
         CorbaMessage inMsg = EasyMock.createMock(CorbaMessage.class);
         EasyMock.expect(msg.getExchange()).andReturn(exchange);
         EasyMock.expect(exchange.getInMessage()).andReturn(inMsg);
+        EasyMock.expect(exchange.getBus()).andReturn(bus);
+
 
         EasyMock.expect(inMsg.getList()).andReturn(list);
         QName objName = new QName("object");
@@ -274,6 +277,7 @@ public class CorbaServerConduitTest {
         CorbaMessage msg = control.createMock(CorbaMessage.class);
         Exchange exchange = control.createMock(Exchange.class);
         ServerRequest request = control.createMock(ServerRequest.class);
+        EasyMock.expect(exchange.getBus()).andReturn(bus);
 
         EasyMock.expect(msg.getExchange()).andReturn(exchange);
         EasyMock.expect(exchange.get(ServerRequest.class)).andReturn(request);
diff --git a/rt/bindings/xml/src/main/java/org/apache/cxf/binding/xml/wsdl11/XMLWSDLExtensionLoader.java b/rt/bindings/xml/src/main/java/org/apache/cxf/binding/xml/wsdl11/XMLWSDLExtensionLoader.java
index 8d30118..7171680 100644
--- a/rt/bindings/xml/src/main/java/org/apache/cxf/binding/xml/wsdl11/XMLWSDLExtensionLoader.java
+++ b/rt/bindings/xml/src/main/java/org/apache/cxf/binding/xml/wsdl11/XMLWSDLExtensionLoader.java
@@ -33,15 +33,18 @@ import org.apache.cxf.wsdl.WSDLManager;
 @NoJSR250Annotations
 public final class XMLWSDLExtensionLoader implements WSDLExtensionLoader {
 
+    private Bus bus;
+
     public XMLWSDLExtensionLoader(Bus b) {
         setupBus(b);
     }
     public void setupBus(Bus b) {
+        this.bus = b;
         WSDLManager manager = b.getExtension(WSDLManager.class);
         registerExtensors(manager);
     }
 
-    public static void registerExtensors(WSDLManager manager) {
+    public void registerExtensors(WSDLManager manager) {
         createExtensor(manager, javax.wsdl.BindingInput.class,
                        org.apache.cxf.bindings.xformat.XMLBindingMessageFormat.class);
         createExtensor(manager, javax.wsdl.BindingOutput.class,
@@ -50,11 +53,11 @@ public final class XMLWSDLExtensionLoader implements WSDLExtensionLoader {
                        org.apache.cxf.bindings.xformat.XMLFormatBinding.class);
     }
 
-    public static void createExtensor(WSDLManager manager,
+    public void createExtensor(WSDLManager manager,
                                 Class<?> parentType,
                                 Class<?> elementType) {
         try {
-            JAXBExtensionHelper.addExtensions(manager.getExtensionRegistry(),
+            JAXBExtensionHelper.addExtensions(bus, manager.getExtensionRegistry(),
                                               parentType,
                                               elementType,
                                               null,
diff --git a/rt/bindings/xml/src/test/java/org/apache/cxf/binding/xml/interceptor/TestBase.java b/rt/bindings/xml/src/test/java/org/apache/cxf/binding/xml/interceptor/TestBase.java
index c07071a..8c65242 100644
--- a/rt/bindings/xml/src/test/java/org/apache/cxf/binding/xml/interceptor/TestBase.java
+++ b/rt/bindings/xml/src/test/java/org/apache/cxf/binding/xml/interceptor/TestBase.java
@@ -77,7 +77,8 @@ public class TestBase {
         Bus bus = BusFactory.getDefaultBus();
 
         WSDLManagerImpl manager = new WSDLManagerImpl();
-        XMLWSDLExtensionLoader.registerExtensors(manager);
+        XMLWSDLExtensionLoader loader = new XMLWSDLExtensionLoader(bus);
+        loader.registerExtensors(manager);
 
         assertNotNull(bus.getExtension(WSDLManager.class));
 
diff --git a/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/FactoryClassCreator.java b/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/FactoryClassCreator.java
new file mode 100644
index 0000000..e3ba1ab
--- /dev/null
+++ b/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/FactoryClassCreator.java
@@ -0,0 +1,24 @@
+/**
+ * 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.cxf.jaxb;
+
+public interface FactoryClassCreator {
+    Class<?> createFactory(Class<?> cls);
+}
diff --git a/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/FactoryClassGenerator.java b/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/FactoryClassGenerator.java
new file mode 100644
index 0000000..c69b2b4
--- /dev/null
+++ b/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/FactoryClassGenerator.java
@@ -0,0 +1,86 @@
+/**
+ * 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.cxf.jaxb;
+
+import java.lang.reflect.Constructor;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.common.spi.ClassGeneratorClassLoader;
+import org.apache.cxf.common.util.ASMHelper;
+import org.apache.cxf.common.util.OpcodesProxy;
+import org.apache.cxf.common.util.ReflectionUtil;
+import org.apache.cxf.common.util.StringUtils;
+
+
+public class FactoryClassGenerator extends ClassGeneratorClassLoader implements FactoryClassCreator {
+    private final ASMHelper helper;
+    FactoryClassGenerator(Bus bus) {
+        super(bus);
+        helper = bus.getExtension(ASMHelper.class);
+    }
+    @SuppressWarnings("unused")
+    public Class<?> createFactory(Class<?> cls) {
+        String newClassName = cls.getName() + "Factory";
+        Class<?> factoryClass = findClass(newClassName, cls);
+        if (factoryClass != null) {
+            return factoryClass;
+        }
+        Constructor<?> contructor = ReflectionUtil.getDeclaredConstructors(cls)[0];
+        OpcodesProxy opcodes = helper.getOpCodes();
+        ASMHelper.ClassWriter cw = helper.createClassWriter();
+        ASMHelper.MethodVisitor mv;
+
+        cw.visit(opcodes.V1_6, opcodes.ACC_PUBLIC + opcodes.ACC_SUPER,
+                StringUtils.periodToSlashes(newClassName), null, "java/lang/Object", null);
+
+        cw.visitSource(cls.getSimpleName() + "Factory" + ".java", null);
+
+        mv = cw.visitMethod(opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
+        mv.visitCode();
+        mv.visitVarInsn(opcodes.ALOAD, 0);
+        mv.visitMethodInsn(opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
+        mv.visitInsn(opcodes.RETURN);
+        mv.visitMaxs(0, 0);
+        mv.visitEnd();
+
+        mv = cw.visitMethod(opcodes.ACC_PUBLIC, "create" + cls.getSimpleName(),
+                "()L" + StringUtils.periodToSlashes(cls.getName()) + ";", null, null);
+        mv.visitCode();
+        String name = cls.getName().replace(".", "/");
+        mv.visitTypeInsn(opcodes.NEW, name);
+        mv.visitInsn(opcodes.DUP);
+        StringBuilder paraString = new StringBuilder(32).append("(");
+
+        for (Class<?> paraClass : contructor.getParameterTypes()) {
+            mv.visitInsn(opcodes.ACONST_NULL);
+            paraString.append("Ljava/lang/Object;");
+        }
+        paraString.append(")V");
+
+        mv.visitMethodInsn(opcodes.INVOKESPECIAL, name, "<init>", paraString.toString(), false);
+
+        mv.visitInsn(opcodes.ARETURN);
+        mv.visitMaxs(0, 0);
+        mv.visitEnd();
+
+        cw.visitEnd();
+        return loadClass(newClassName, cls, cw.toByteArray());
+    }
+}
diff --git a/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/FactoryClassLoader.java b/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/FactoryClassLoader.java
new file mode 100644
index 0000000..5cbfd16
--- /dev/null
+++ b/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/FactoryClassLoader.java
@@ -0,0 +1,40 @@
+/**
+ * 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.cxf.jaxb;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.common.spi.GeneratedClassClassLoader;
+
+/** If class has been generated during build time
+ *  (use @see org.apache.cxf.common.spi.GeneratedClassClassLoaderCapture capture to save bytes)
+ *  you can set class loader to avoid class generation during runtime:
+ *  bus.setExtension(new FactoryClassLoader(bus), FactoryClassCreator.class);
+ * @author olivier dufour
+ */
+public class FactoryClassLoader extends GeneratedClassClassLoader implements FactoryClassCreator {
+    public FactoryClassLoader(Bus bus) {
+        super(bus);
+    }
+    @Override
+    public Class<?> createFactory(Class<?> cls) {
+        String newClassName = cls.getName() + "Factory";
+        return findClass(newClassName, cls);
+    }
+}
diff --git a/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/FactoryClassProxyService.java b/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/FactoryClassProxyService.java
new file mode 100644
index 0000000..0d82b78
--- /dev/null
+++ b/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/FactoryClassProxyService.java
@@ -0,0 +1,48 @@
+/**
+ * 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.cxf.jaxb;
+
+import org.apache.cxf.Bus;
+
+public class FactoryClassProxyService implements FactoryClassCreator {
+    private final FactoryClassCreator srv;
+    public FactoryClassProxyService(Bus bus) {
+        this(new FactoryClassGenerator(bus));
+    }
+    public FactoryClassProxyService(FactoryClassCreator srv) {
+        super();
+        this.srv = srv;
+    }
+
+    @Override
+    public Class<?> createFactory(Class<?> cls) {
+        return srv.createFactory(cls);
+    }
+
+    public class LoadFirst extends FactoryClassProxyService {
+        public LoadFirst(Bus bus) {
+            super(new FactoryClassLoader(bus));
+        }
+    }
+    public class GenerateJustInTime extends FactoryClassProxyService {
+        public GenerateJustInTime(Bus bus) {
+            super(new FactoryClassGenerator(bus));
+        }
+    }
+}
diff --git a/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/JAXBContextInitializer.java b/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/JAXBContextInitializer.java
index 1038b7f..0dd420b 100644
--- a/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/JAXBContextInitializer.java
+++ b/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/JAXBContextInitializer.java
@@ -21,7 +21,6 @@ package org.apache.cxf.jaxb;
 
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Array;
-import java.lang.reflect.Constructor;
 import java.lang.reflect.Field;
 import java.lang.reflect.GenericArrayType;
 import java.lang.reflect.Method;
@@ -48,13 +47,10 @@ import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
 import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapters;
 import javax.xml.namespace.QName;
 
+import org.apache.cxf.Bus;
 import org.apache.cxf.common.classloader.ClassLoaderUtils;
 import org.apache.cxf.common.jaxb.JAXBUtils;
 import org.apache.cxf.common.logging.LogUtils;
-import org.apache.cxf.common.util.ASMHelper;
-import org.apache.cxf.common.util.ASMHelper.ClassWriter;
-import org.apache.cxf.common.util.ASMHelper.MethodVisitor;
-import org.apache.cxf.common.util.ASMHelper.Opcodes;
 import org.apache.cxf.common.util.ReflectionUtil;
 import org.apache.cxf.common.util.StringUtils;
 import org.apache.cxf.service.ServiceModelVisitor;
@@ -73,15 +69,17 @@ class JAXBContextInitializer extends ServiceModelVisitor {
     private Collection<Object> typeReferences;
     private Set<Class<?>> globalAdapters = new HashSet<>();
     private Map<String, Object> unmarshallerProperties;
+    private Bus bus;
 
-    JAXBContextInitializer(ServiceInfo serviceInfo,
-                                  Set<Class<?>> classes,
-                                  Collection<Object> typeReferences,
-                                  Map<String, Object> unmarshallerProperties) {
+    JAXBContextInitializer(Bus bus, ServiceInfo serviceInfo,
+                           Set<Class<?>> classes,
+                           Collection<Object> typeReferences,
+                           Map<String, Object> unmarshallerProperties) {
         super(serviceInfo);
         this.classes = classes;
         this.typeReferences = typeReferences;
         this.unmarshallerProperties = unmarshallerProperties;
+        this.bus = bus;
     }
 
     @Override
@@ -328,8 +326,7 @@ class JAXBContextInitializer extends ServiceModelVisitor {
                 if (LOG.isLoggable(Level.INFO)) {
                     LOG.info("Class " + claz.getName() + " does not have a default constructor which JAXB requires.");
                 }
-                //there is no init(), but other constructors
-                Object factory = createFactory(claz, ReflectionUtil.getDeclaredConstructors(claz)[0]);
+                Object factory = createFactory(claz);
                 unmarshallerProperties.put("com.sun.xml.bind.ObjectFactory", factory);
                 cls = claz;
             }
@@ -556,47 +553,10 @@ class JAXBContextInitializer extends ServiceModelVisitor {
     }
 
     @SuppressWarnings("unused")
-    private Object createFactory(Class<?> cls, Constructor<?> contructor) {
-        String newClassName = cls.getName() + "Factory";
-        ASMHelper helper = new ASMHelper();
-        ClassWriter cw = helper.createClassWriter();
-        MethodVisitor mv;
-
-        cw.visit(Opcodes.V1_6, Opcodes.ACC_PUBLIC + Opcodes.ACC_SUPER,
-                 ASMHelper.periodToSlashes(newClassName), null, "java/lang/Object", null);
-
-        cw.visitSource(cls.getSimpleName() + "Factory" + ".java", null);
-
-        mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
-        mv.visitCode();
-        mv.visitVarInsn(Opcodes.ALOAD, 0);
-        mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
-        mv.visitInsn(Opcodes.RETURN);
-        mv.visitMaxs(1, 1);
-        mv.visitEnd();
-
-        mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "create" + cls.getSimpleName(),
-                            "()L" + ASMHelper.periodToSlashes(cls.getName()) + ";", null, null);
-        mv.visitCode();
-        String name = cls.getName().replace(".", "/");
-        mv.visitTypeInsn(Opcodes.NEW, name);
-        mv.visitInsn(Opcodes.DUP);
-        StringBuilder paraString = new StringBuilder(32).append("(");
-
-        for (Class<?> paraClass : contructor.getParameterTypes()) {
-            mv.visitInsn(Opcodes.ACONST_NULL);
-            paraString.append("Ljava/lang/Object;");
-        }
-        paraString.append(")V");
-
-        mv.visitMethodInsn(Opcodes.INVOKESPECIAL, name, "<init>", paraString.toString(), false);
-
-        mv.visitInsn(Opcodes.ARETURN);
-        mv.visitMaxs(1, 1);
-        mv.visitEnd();
+    private Object createFactory(Class<?> cls) {
+        FactoryClassCreator creator = bus.getExtension(FactoryClassCreator.class);
 
-        cw.visitEnd();
-        Class<?> factoryClass = helper.loadClass(newClassName, cls, cw.toByteArray());
+        Class<?> factoryClass = creator.createFactory(cls);
         try {
             return factoryClass.newInstance();
         } catch (Exception e) {
diff --git a/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/JAXBDataBinding.java b/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/JAXBDataBinding.java
index 1c0c92d..df435cd 100644
--- a/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/JAXBDataBinding.java
+++ b/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/JAXBDataBinding.java
@@ -63,6 +63,7 @@ import org.w3c.dom.Node;
 
 import org.xml.sax.InputSource;
 
+import org.apache.cxf.Bus;
 import org.apache.cxf.common.injection.NoJSR250Annotations;
 import org.apache.cxf.common.jaxb.JAXBBeanInfo;
 import org.apache.cxf.common.jaxb.JAXBContextCache;
@@ -279,19 +280,19 @@ public class JAXBDataBinding extends AbstractInterceptorProvidingDataBinding
         Integer mtomThresholdInt = Integer.valueOf(getMtomThreshold());
         if (c == XMLStreamWriter.class) {
             DataWriterImpl<XMLStreamWriter> r
-                = new DataWriterImpl<>(this, true);
+                = new DataWriterImpl<>(getBus(), this, true);
             r.setMtomThreshold(mtomThresholdInt);
             return (DataWriter<T>)r;
         } else if (c == OutputStream.class) {
-            DataWriterImpl<OutputStream> r = new DataWriterImpl<>(this, false);
+            DataWriterImpl<OutputStream> r = new DataWriterImpl<>(getBus(), this, false);
             r.setMtomThreshold(mtomThresholdInt);
             return (DataWriter<T>)r;
         } else if (c == XMLEventWriter.class) {
-            DataWriterImpl<XMLEventWriter> r = new DataWriterImpl<>(this, true);
+            DataWriterImpl<XMLEventWriter> r = new DataWriterImpl<>(getBus(), this, true);
             r.setMtomThreshold(mtomThresholdInt);
             return (DataWriter<T>)r;
         } else if (c == Node.class) {
-            DataWriterImpl<Node> r = new DataWriterImpl<>(this, false);
+            DataWriterImpl<Node> r = new DataWriterImpl<>(getBus(), this, false);
             r.setMtomThreshold(mtomThresholdInt);
             return (DataWriter<T>)r;
         }
@@ -334,8 +335,8 @@ public class JAXBDataBinding extends AbstractInterceptorProvidingDataBinding
         contextClasses = new LinkedHashSet<>();
 
         for (ServiceInfo serviceInfo : service.getServiceInfos()) {
-            JAXBContextInitializer initializer
-                = new JAXBContextInitializer(serviceInfo, contextClasses, typeRefs, this.getUnmarshallerProperties());
+            JAXBContextInitializer initializer = new JAXBContextInitializer(getBus(), serviceInfo, contextClasses,
+                    typeRefs, this.getUnmarshallerProperties());
             initializer.walk();
             if (serviceInfo.getProperty("extra.class") != null) {
                 Set<Class<?>> exClasses = serviceInfo.getProperty("extra.class", Set.class);
@@ -801,7 +802,7 @@ public class JAXBDataBinding extends AbstractInterceptorProvidingDataBinding
 
         }
 
-        return createWrapperHelper(wrapperType,
+        return createWrapperHelper(getBus(), wrapperType,
                                  setMethods.toArray(new Method[0]),
                                  getMethods.toArray(new Method[0]),
                                  jaxbMethods.toArray(new Method[0]),
@@ -832,11 +833,11 @@ public class JAXBDataBinding extends AbstractInterceptorProvidingDataBinding
     }
 
 
-    private static WrapperHelper createWrapperHelper(Class<?> wrapperType, Method[] setMethods,
+    private static WrapperHelper createWrapperHelper(Bus bus, Class<?> wrapperType, Method[] setMethods,
                                                      Method[] getMethods, Method[] jaxbMethods,
                                                      Field[] fields, Object objectFactory) {
 
-        WrapperHelper wh = compileWrapperHelper(wrapperType, setMethods, getMethods, jaxbMethods, fields,
+        WrapperHelper wh = compileWrapperHelper(bus, wrapperType, setMethods, getMethods, jaxbMethods, fields,
                                                 objectFactory);
 
         if (wh == null) {
@@ -846,11 +847,17 @@ public class JAXBDataBinding extends AbstractInterceptorProvidingDataBinding
         return wh;
     }
 
-    private static WrapperHelper compileWrapperHelper(Class<?> wrapperType, Method[] setMethods,
+    private static WrapperHelper compileWrapperHelper(Bus bus, Class<?> wrapperType, Method[] setMethods,
                                                       Method[] getMethods, Method[] jaxbMethods,
                                                       Field[] fields, Object objectFactory) {
-        return WrapperHelperCompiler.compileWrapperHelper(wrapperType, setMethods, getMethods,
-                                                          jaxbMethods, fields, objectFactory);
+        try {
+            WrapperHelperCreator creator = bus.getExtension(WrapperHelperCreator.class);
+            return creator.compile(wrapperType, setMethods, getMethods,
+                    jaxbMethods, fields, objectFactory);
+        } catch (Throwable t) {
+            // Some error - probably a bad version of ASM or similar
+            return null;
+        }
     }
 
 }
diff --git a/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/WrapperHelperClassGenerator.java b/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/WrapperHelperClassGenerator.java
new file mode 100644
index 0000000..c01d6c4
--- /dev/null
+++ b/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/WrapperHelperClassGenerator.java
@@ -0,0 +1,451 @@
+/**
+ * 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.cxf.jaxb;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.List;
+
+import javax.xml.bind.JAXBElement;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.common.spi.ClassGeneratorClassLoader;
+import org.apache.cxf.common.util.ASMHelper;
+import org.apache.cxf.common.util.OpcodesProxy;
+import org.apache.cxf.common.util.StringUtils;
+import org.apache.cxf.databinding.WrapperHelper;
+
+public final class WrapperHelperClassGenerator extends ClassGeneratorClassLoader implements WrapperHelperCreator {
+
+    WrapperHelperClassGenerator(Bus bus) {
+        super(bus);
+    }
+
+    public WrapperHelper compile(Class<?> wrapperType, Method[] setMethods,
+                                 Method[] getMethods, Method[] jaxbMethods,
+                                 Field[] fields, Object objectFactory) {
+        ASMHelper asmhelper = bus.getExtension(ASMHelper.class);
+        ASMHelper.ClassWriter cw = asmhelper.createClassWriter();
+
+        if (cw == null) {
+            return null;
+        }
+        int count = 1;
+        String newClassName = wrapperType.getName() + "_WrapperTypeHelper" + count;
+        newClassName = newClassName.replaceAll("\\$", ".");
+        newClassName = StringUtils.periodToSlashes(newClassName);
+
+        Class<?> cls = findClass(StringUtils.slashesToPeriod(newClassName), wrapperType);
+        while (cls != null) {
+            try {
+                WrapperHelper helper = WrapperHelper.class.cast(cls.newInstance());
+                if (!helper.getSignature().equals(computeSignature(setMethods, getMethods))) {
+                    count++;
+                    newClassName = wrapperType.getName() + "_WrapperTypeHelper" + count;
+                    newClassName = newClassName.replaceAll("\\$", ".");
+                    newClassName = StringUtils.periodToSlashes(newClassName);
+                    cls = findClass(StringUtils.slashesToPeriod(newClassName), wrapperType);
+                } else {
+                    return helper;
+                }
+            } catch (Exception e) {
+                return null;
+            }
+        }
+
+        OpcodesProxy opCodes = asmhelper.getOpCodes();
+
+        cw.visit(opCodes.V1_5,
+                 opCodes.ACC_PUBLIC | opCodes.ACC_SUPER,
+                 newClassName,
+                 null,
+                 "java/lang/Object",
+                 new String[] {StringUtils.periodToSlashes(WrapperHelper.class.getName())});
+
+        addConstructor(newClassName, objectFactory == null ? null : objectFactory.getClass(), asmhelper, cw);
+        boolean b = addSignature(setMethods, getMethods, asmhelper, cw);
+        if (b) {
+            b = addCreateWrapperObject(newClassName,
+                                       objectFactory == null ? null : objectFactory.getClass(),
+                                       wrapperType, setMethods, getMethods, jaxbMethods, fields, asmhelper, cw);
+        }
+        if (b) {
+            b = addGetWrapperParts(newClassName, wrapperType, getMethods, fields, asmhelper, cw);
+        }
+
+        try {
+            if (b) {
+                cw.visitEnd();
+                byte[] bt = cw.toByteArray();
+                Class<?> cl = loadClass(StringUtils.slashesToPeriod(newClassName), wrapperType, bt);
+                Object o = cl.newInstance();
+                return WrapperHelper.class.cast(o);
+            }
+        } catch (Throwable e) {
+            // ignore, we'll just fall down to reflection based
+        }
+        return null;
+    }
+
+    public static String computeSignature(Method[] setMethods, Method[] getMethods) {
+        StringBuilder b = new StringBuilder();
+        b.append(setMethods.length).append(':');
+        for (int x = 0; x < setMethods.length; x++) {
+            if (getMethods[x] == null) {
+                b.append("null,");
+            } else {
+                b.append(getMethods[x].getName()).append('/');
+                b.append(getMethods[x].getReturnType().getName()).append(',');
+            }
+        }
+        return b.toString();
+    }
+
+    private boolean addSignature(Method[] setMethods, Method[] getMethods,
+                                 ASMHelper asmhelper, ASMHelper.ClassWriter cw) {
+        OpcodesProxy opCodes = asmhelper.getOpCodes();
+        String sig = computeSignature(setMethods, getMethods);
+        ASMHelper.MethodVisitor mv = cw.visitMethod(opCodes.ACC_PUBLIC,
+                                          "getSignature", "()Ljava/lang/String;", null, null);
+        mv.visitCode();
+        mv.visitLdcInsn(sig);
+        ASMHelper.Label l0 = asmhelper.createLabel();
+        mv.visitLabel(l0);
+        mv.visitLineNumber(100, l0);
+        mv.visitInsn(opCodes.ARETURN);
+        mv.visitMaxs(0, 0);
+        mv.visitEnd();
+        return true;
+    }
+
+    private void addConstructor(String newClassName, Class<?> objectFactoryCls,
+                                ASMHelper asmhelper, ASMHelper.ClassWriter cw) {
+
+        if (objectFactoryCls != null) {
+            String ofName = "L" + StringUtils.periodToSlashes(objectFactoryCls.getName()) + ";";
+            ASMHelper.FieldVisitor fv = cw.visitField(0, "factory",
+                                            ofName,
+                                            null, null);
+            fv.visitEnd();
+        }
+        OpcodesProxy opCodes = asmhelper.getOpCodes();
+
+        ASMHelper.MethodVisitor mv = cw.visitMethod(opCodes.ACC_PUBLIC, "<init>", "()V", null, null);
+        mv.visitCode();
+        ASMHelper.Label l0 = asmhelper.createLabel();
+        mv.visitLabel(l0);
+        mv.visitLineNumber(102, l0);
+
+        mv.visitVarInsn(opCodes.ALOAD, 0);
+        mv.visitMethodInsn(opCodes.INVOKESPECIAL,
+                           "java/lang/Object",
+                           "<init>",
+                           "()V", false);
+        if (objectFactoryCls != null) {
+            mv.visitVarInsn(opCodes.ALOAD, 0);
+            mv.visitTypeInsn(opCodes.NEW, StringUtils.periodToSlashes(objectFactoryCls.getName()));
+            mv.visitInsn(opCodes.DUP);
+            mv.visitMethodInsn(opCodes.INVOKESPECIAL,
+                    StringUtils.periodToSlashes(objectFactoryCls.getName()),
+                               "<init>", "()V", false);
+            mv.visitFieldInsn(opCodes.PUTFIELD, StringUtils.periodToSlashes(newClassName),
+                              "factory", "L" + StringUtils.periodToSlashes(objectFactoryCls.getName()) + ";");
+        }
+
+        mv.visitInsn(opCodes.RETURN);
+
+        ASMHelper.Label l1 = asmhelper.createLabel();
+        mv.visitLabel(l1);
+        mv.visitLineNumber(103, l0);
+
+        mv.visitLocalVariable("this", "L" + newClassName + ";", null, l0, l1, 0);
+        mv.visitMaxs(0, 0);
+        mv.visitEnd();
+    }
+    //CHECKSTYLE:OFF
+    private boolean addCreateWrapperObject(String newClassName, Class<?> objectFactoryClass,
+                                           Class<?> wrapperType, Method[] setMethods,
+                                           Method[] getMethods, Method[] jaxbMethods,
+                                           Field[] fields, ASMHelper asmhelper, ASMHelper.ClassWriter cw) {
+
+        OpcodesProxy opCodes = asmhelper.getOpCodes();
+        ASMHelper.MethodVisitor mv = cw.visitMethod(opCodes.ACC_PUBLIC,
+                                          "createWrapperObject",
+                                          "(Ljava/util/List;)Ljava/lang/Object;",
+                                          "(Ljava/util/List<*>;)Ljava/lang/Object;",
+                                          new String[] {
+                                              "org/apache/cxf/interceptor/Fault"
+                                          });
+        mv.visitCode();
+        ASMHelper.Label lBegin = asmhelper.createLabel();
+        mv.visitLabel(lBegin);
+        mv.visitLineNumber(104, lBegin);
+
+        mv.visitTypeInsn(opCodes.NEW, StringUtils.periodToSlashes(wrapperType.getName()));
+        mv.visitInsn(opCodes.DUP);
+        mv.visitMethodInsn(opCodes.INVOKESPECIAL, StringUtils.periodToSlashes(wrapperType.getName()),
+                           "<init>", "()V", false);
+        mv.visitVarInsn(opCodes.ASTORE, 2);
+
+        for (int x = 0; x < setMethods.length; x++) {
+            if (getMethods[x] == null) {
+                if (setMethods[x] == null
+                    && fields[x] == null) {
+                    // null placeholder
+                    continue;
+                }
+                return false;
+            }
+            Class<?> tp = getMethods[x].getReturnType();
+            mv.visitVarInsn(opCodes.ALOAD, 2);
+
+            if (List.class.isAssignableFrom(tp)) {
+                doCollection(mv, x, wrapperType, setMethods, getMethods, asmhelper);
+            } else {
+                if (JAXBElement.class.isAssignableFrom(tp)) {
+                    mv.visitVarInsn(opCodes.ALOAD, 0);
+                    mv.visitFieldInsn(opCodes.GETFIELD, StringUtils.periodToSlashes(newClassName),
+                                      "factory",
+                                      "L" + StringUtils.periodToSlashes(objectFactoryClass.getName()) + ";");
+                }
+                mv.visitVarInsn(opCodes.ALOAD, 1);
+                mv.visitIntInsn(opCodes.SIPUSH, x);
+                mv.visitMethodInsn(opCodes.INVOKEINTERFACE, "java/util/List", "get", "(I)Ljava/lang/Object;", true);
+
+                if (tp.isPrimitive()) {
+                    mv.visitTypeInsn(opCodes.CHECKCAST, asmhelper.getNonPrimitive(tp));
+                    ASMHelper.Label l45 = asmhelper.createLabel();
+                    ASMHelper.Label l46 = asmhelper.createLabel();
+                    mv.visitInsn(opCodes.DUP);
+                    mv.visitJumpInsn(opCodes.IFNULL, l45);
+                    mv.visitMethodInsn(opCodes.INVOKEVIRTUAL, asmhelper.getNonPrimitive(tp),
+                                       tp.getName() + "Value", "()" + asmhelper.getPrimitive(tp), false);
+                    mv.visitMethodInsn(opCodes.INVOKEVIRTUAL,
+                            StringUtils.periodToSlashes(wrapperType.getName()),
+                                       setMethods[x].getName(), "(" + asmhelper.getClassCode(tp) + ")V", false);
+                    mv.visitJumpInsn(opCodes.GOTO, l46);
+                    mv.visitLabel(l45);
+                    mv.visitInsn(opCodes.POP);
+                    mv.visitLabel(l46);
+                } else if (JAXBElement.class.isAssignableFrom(tp)) {
+                    mv.visitTypeInsn(opCodes.CHECKCAST,
+                                     StringUtils.periodToSlashes(jaxbMethods[x].getParameterTypes()[0].getName()));
+                    mv.visitMethodInsn(opCodes.INVOKEVIRTUAL, StringUtils.periodToSlashes(objectFactoryClass.getName()),
+                                       jaxbMethods[x].getName(),
+                                       asmhelper.getMethodSignature(jaxbMethods[x]), false);
+                    mv.visitMethodInsn(opCodes.INVOKEVIRTUAL,
+                                       StringUtils.periodToSlashes(wrapperType.getName()),
+                                       setMethods[x].getName(), "(" + asmhelper.getClassCode(tp) + ")V", false);
+                } else if (tp.isArray()) {
+                    mv.visitTypeInsn(opCodes.CHECKCAST, asmhelper.getClassCode(tp));
+                    mv.visitMethodInsn(opCodes.INVOKEVIRTUAL,
+                                       StringUtils.periodToSlashes(wrapperType.getName()),
+                                       setMethods[x].getName(), "(" + asmhelper.getClassCode(tp) + ")V", false);
+                } else {
+                    mv.visitTypeInsn(opCodes.CHECKCAST, StringUtils.periodToSlashes(tp.getName()));
+                    mv.visitMethodInsn(opCodes.INVOKEVIRTUAL,
+                                       StringUtils.periodToSlashes(wrapperType.getName()),
+                                       setMethods[x].getName(), "(" + asmhelper.getClassCode(tp) + ")V", false);
+                }
+            }
+        }
+
+        mv.visitVarInsn(opCodes.ALOAD, 2);
+        mv.visitInsn(opCodes.ARETURN);
+
+        ASMHelper.Label lEnd = asmhelper.createLabel();
+        mv.visitLabel(lEnd);
+        mv.visitLocalVariable("this", "L" + newClassName + ";", null, lBegin, lEnd, 0);
+        mv.visitLocalVariable("lst", "Ljava/util/List;", "Ljava/util/List<*>;", lBegin, lEnd, 1);
+        mv.visitLocalVariable("ok", "L" + StringUtils.periodToSlashes(wrapperType.getName()) + ";",
+                              null, lBegin, lEnd, 2);
+        mv.visitMaxs(0, 0);
+        mv.visitEnd();
+        return true;
+    }
+    //CHECKSTYLE:ON
+    private void doCollection(ASMHelper.MethodVisitor mv, int x, Class<?> wrapperType, Method[] setMethods,
+                              Method[] getMethods, ASMHelper asmhelper) {
+        // List aVal = obj.getA();
+        // List newA = (List)lst.get(99);
+        // if (aVal == null) {
+        // obj.setA(newA);
+        // } else if (newA != null) {
+        // aVal.addAll(newA);
+        // }
+
+        OpcodesProxy opCodes = asmhelper.getOpCodes();
+        ASMHelper.Label l3 = asmhelper.createLabel();
+        mv.visitLabel(l3);
+        mv.visitLineNumber(114, l3);
+
+        mv.visitMethodInsn(opCodes.INVOKEVIRTUAL,
+                           StringUtils.periodToSlashes(wrapperType.getName()),
+                           getMethods[x].getName(),
+                           asmhelper.getMethodSignature(getMethods[x]), false);
+        mv.visitVarInsn(opCodes.ASTORE, 3);
+        mv.visitVarInsn(opCodes.ALOAD, 1);
+        mv.visitIntInsn(opCodes.SIPUSH, x);
+        mv.visitMethodInsn(opCodes.INVOKEINTERFACE, "java/util/List",
+                           "get", "(I)Ljava/lang/Object;", true);
+        mv.visitTypeInsn(opCodes.CHECKCAST, "java/util/List");
+        mv.visitVarInsn(opCodes.ASTORE, 4);
+        mv.visitVarInsn(opCodes.ALOAD, 3);
+        ASMHelper.Label nonNullLabel = asmhelper.createLabel();
+        mv.visitJumpInsn(opCodes.IFNONNULL, nonNullLabel);
+
+        if (setMethods[x] == null) {
+            mv.visitTypeInsn(opCodes.NEW, "java/lang/RuntimeException");
+            mv.visitInsn(opCodes.DUP);
+            mv.visitLdcInsn(getMethods[x].getName() + " returned null and there isn't a set method.");
+            mv.visitMethodInsn(opCodes.INVOKESPECIAL,
+                               "java/lang/RuntimeException",
+                               "<init>", "(Ljava/lang/String;)V", false);
+            mv.visitInsn(opCodes.ATHROW);
+        } else {
+            mv.visitVarInsn(opCodes.ALOAD, 2);
+            mv.visitVarInsn(opCodes.ALOAD, 4);
+            mv.visitTypeInsn(opCodes.CHECKCAST,
+                             getMethods[x].getReturnType().getName().replace('.', '/'));
+            mv.visitMethodInsn(opCodes.INVOKEVIRTUAL,
+                               StringUtils.periodToSlashes(wrapperType.getName()),
+                               setMethods[x].getName(),
+                               asmhelper.getMethodSignature(setMethods[x]), false);
+        }
+        ASMHelper.Label jumpOverLabel = asmhelper.createLabel();
+        mv.visitJumpInsn(opCodes.GOTO, jumpOverLabel);
+        mv.visitLabel(nonNullLabel);
+        mv.visitLineNumber(106, nonNullLabel);
+
+        mv.visitVarInsn(opCodes.ALOAD, 4);
+        mv.visitJumpInsn(opCodes.IFNULL, jumpOverLabel);
+        mv.visitVarInsn(opCodes.ALOAD, 3);
+        mv.visitVarInsn(opCodes.ALOAD, 4);
+        mv.visitMethodInsn(opCodes.INVOKEINTERFACE,
+                           "java/util/List", "addAll", "(Ljava/util/Collection;)Z", true);
+        mv.visitInsn(opCodes.POP);
+        mv.visitLabel(jumpOverLabel);
+        mv.visitLineNumber(107, jumpOverLabel);
+    }
+
+    private boolean addGetWrapperParts(String newClassName, Class<?> wrapperClass, Method[] getMethods, Field[] fields,
+                                       ASMHelper asmhelper, ASMHelper.ClassWriter cw) {
+        OpcodesProxy opCodes = asmhelper.getOpCodes();
+        ASMHelper.MethodVisitor mv = cw.visitMethod(opCodes.ACC_PUBLIC,
+                                          "getWrapperParts",
+                                          "(Ljava/lang/Object;)Ljava/util/List;",
+                                          "(Ljava/lang/Object;)Ljava/util/List<Ljava/lang/Object;>;",
+                                          new String[] {
+                                              "org/apache/cxf/interceptor/Fault"
+                                          });
+        mv.visitCode();
+        ASMHelper.Label lBegin = asmhelper.createLabel();
+        mv.visitLabel(lBegin);
+        mv.visitLineNumber(108, lBegin);
+
+        // the ret List
+        mv.visitTypeInsn(opCodes.NEW, "java/util/ArrayList");
+        mv.visitInsn(opCodes.DUP);
+        mv.visitMethodInsn(opCodes.INVOKESPECIAL, "java/util/ArrayList", "<init>", "()V", false);
+        mv.visitVarInsn(opCodes.ASTORE, 2);
+
+        // cast the Object to the wrapperType type
+        mv.visitVarInsn(opCodes.ALOAD, 1);
+        mv.visitTypeInsn(opCodes.CHECKCAST, StringUtils.periodToSlashes(wrapperClass.getName()));
+        mv.visitVarInsn(opCodes.ASTORE, 3);
+
+        for (int x = 0; x < getMethods.length; x++) {
+            Method method = getMethods[x];
+            if (method == null && fields[x] != null) {
+                // fallback to reflection mode
+                return false;
+            }
+
+            if (method == null) {
+                ASMHelper.Label l3 = asmhelper.createLabel();
+                mv.visitLabel(l3);
+                mv.visitLineNumber(200 + x, l3);
+
+                mv.visitVarInsn(opCodes.ALOAD, 2);
+                mv.visitInsn(opCodes.ACONST_NULL);
+                mv.visitMethodInsn(opCodes.INVOKEINTERFACE, "java/util/List",
+                                   "add", "(Ljava/lang/Object;)Z", true);
+                mv.visitInsn(opCodes.POP);
+            } else {
+                ASMHelper.Label l3 = asmhelper.createLabel();
+                mv.visitLabel(l3);
+                mv.visitLineNumber(250 + x, l3);
+
+                mv.visitVarInsn(opCodes.ALOAD, 2);
+                mv.visitVarInsn(opCodes.ALOAD, 3);
+                mv.visitMethodInsn(opCodes.INVOKEVIRTUAL,
+                                   StringUtils.periodToSlashes(wrapperClass.getName()),
+                                   method.getName(),
+                        asmhelper.getMethodSignature(method), false);
+                if (method.getReturnType().isPrimitive()) {
+                    // wrap into Object type
+                    createObjectWrapper(mv, method.getReturnType(), asmhelper);
+                }
+                if (JAXBElement.class.isAssignableFrom(method.getReturnType())) {
+                    ASMHelper.Label jumpOverLabel = asmhelper.createLabel();
+                    mv.visitInsn(opCodes.DUP);
+                    mv.visitJumpInsn(opCodes.IFNULL, jumpOverLabel);
+
+                    mv.visitMethodInsn(opCodes.INVOKEVIRTUAL,
+                                       "javax/xml/bind/JAXBElement",
+                                       "getValue", "()Ljava/lang/Object;", false);
+                    mv.visitLabel(jumpOverLabel);
+                }
+
+                mv.visitMethodInsn(opCodes.INVOKEINTERFACE, "java/util/List", "add", "(Ljava/lang/Object;)Z", true);
+                mv.visitInsn(opCodes.POP);
+            }
+        }
+
+        // return the list
+        ASMHelper.Label l2 = asmhelper.createLabel();
+        mv.visitLabel(l2);
+        mv.visitLineNumber(108, l2);
+        mv.visitVarInsn(opCodes.ALOAD, 2);
+        mv.visitInsn(opCodes.ARETURN);
+
+
+        ASMHelper.Label lEnd = asmhelper.createLabel();
+        mv.visitLabel(lEnd);
+        mv.visitLocalVariable("this", "L" + newClassName + ";", null, lBegin, lEnd, 0);
+        mv.visitLocalVariable("o", "Ljava/lang/Object;", null, lBegin, lEnd, 1);
+        mv.visitLocalVariable("ret", "Ljava/util/List;", "Ljava/util/List<Ljava/lang/Object;>;",
+                              lBegin, lEnd, 2);
+        mv.visitLocalVariable("ok", "L" + StringUtils.periodToSlashes(wrapperClass.getName()) + ";",
+                              null, lBegin, lEnd, 3);
+        mv.visitMaxs(0, 0);
+        mv.visitEnd();
+        return true;
+    }
+
+
+
+
+    private void createObjectWrapper(ASMHelper.MethodVisitor mv, Class<?> cl, ASMHelper asmhelper) {
+        OpcodesProxy opCodes = asmhelper.getOpCodes();
+        mv.visitMethodInsn(opCodes.INVOKESTATIC, asmhelper.getNonPrimitive(cl),
+                           "valueOf", "(" + asmhelper.getPrimitive(cl) + ")L"
+                           + asmhelper.getNonPrimitive(cl) + ";", false);
+    }
+}
diff --git a/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/WrapperHelperClassLoader.java b/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/WrapperHelperClassLoader.java
new file mode 100644
index 0000000..ab8a585
--- /dev/null
+++ b/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/WrapperHelperClassLoader.java
@@ -0,0 +1,64 @@
+/**
+ * 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.cxf.jaxb;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.common.spi.GeneratedClassClassLoader;
+import org.apache.cxf.databinding.WrapperHelper;
+
+/** If class has been generated during build time
+ *  (use @see org.apache.cxf.common.spi.GeneratedClassClassLoaderCapture capture to save bytes)
+ *  you can set class loader to avoid class generation during runtime:
+ *  bus.setExtension(new WrapperHelperClassLoader(bus), WrapperHelperCreator.class);
+ * @author olivier dufour
+ */
+public class WrapperHelperClassLoader extends GeneratedClassClassLoader implements WrapperHelperCreator {
+    public WrapperHelperClassLoader(Bus bus) {
+        super(bus);
+    }
+
+    @Override
+    public WrapperHelper compile(Class<?> wrapperType, Method[] setMethods, Method[] getMethods,
+                                 Method[] jaxbMethods, Field[] fields, Object objectFactory) {
+
+        int count = 1;
+        String newClassName = wrapperType.getName() + "_WrapperTypeHelper" + count;
+
+        Class<?> cls = findClass(newClassName, wrapperType);
+        while (cls != null) {
+            try {
+                WrapperHelper helper = WrapperHelper.class.cast(cls.getDeclaredConstructor().newInstance());
+                if (!helper.getSignature().equals(
+                        WrapperHelperClassGenerator.computeSignature(setMethods, getMethods))) {
+                    count++;
+                    newClassName = wrapperType.getName() + "_WrapperTypeHelper" + count;
+                    cls = findClass(newClassName, wrapperType);
+                } else {
+                    return helper;
+                }
+            } catch (Exception e) {
+                return null;
+            }
+        }
+        return null;
+    }
+}
diff --git a/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/WrapperHelperCompiler.java b/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/WrapperHelperCompiler.java
deleted file mode 100644
index 540e0b4..0000000
--- a/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/WrapperHelperCompiler.java
+++ /dev/null
@@ -1,475 +0,0 @@
-/**
- * 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.cxf.jaxb;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.util.List;
-
-import javax.xml.bind.JAXBElement;
-
-import org.apache.cxf.common.util.ASMHelper;
-import org.apache.cxf.databinding.WrapperHelper;
-
-final class WrapperHelperCompiler extends ASMHelper {
-
-
-    final Class<?> wrapperType;
-    final Method[] setMethods;
-    final Method[] getMethods;
-    final Method[] jaxbMethods;
-    final Field[] fields;
-    final Object objectFactory;
-    final ClassWriter cw;
-
-    private WrapperHelperCompiler(Class<?> wrapperType,
-                                  Method[] setMethods,
-                                  Method[] getMethods,
-                                  Method[] jaxbMethods,
-                                  Field[] fields,
-                                  Object objectFactory) {
-        this.wrapperType = wrapperType;
-        this.setMethods = setMethods;
-        this.getMethods = getMethods;
-        this.jaxbMethods = jaxbMethods;
-        this.fields = fields;
-        this.objectFactory = objectFactory;
-        cw = createClassWriter();
-    }
-
-    static WrapperHelper compileWrapperHelper(Class<?> wrapperType,
-                                              Method[] setMethods,
-                                              Method[] getMethods,
-                                              Method[] jaxbMethods,
-                                              Field[] fields,
-                                              Object objectFactory) {
-        try {
-            return new WrapperHelperCompiler(wrapperType,
-                                        setMethods,
-                                        getMethods,
-                                        jaxbMethods,
-                                        fields,
-                                        objectFactory).compile();
-
-        } catch (Throwable t) {
-            // Some error - probably a bad version of ASM or similar
-        }
-        return null;
-    }
-
-
-
-
-
-    public WrapperHelper compile() {
-        if (cw == null) {
-            return null;
-        }
-        int count = 1;
-        String newClassName = wrapperType.getName() + "_WrapperTypeHelper" + count;
-        newClassName = newClassName.replaceAll("\\$", ".");
-        newClassName = periodToSlashes(newClassName);
-
-        Class<?> cls = super.findClass(newClassName.replace('/', '.'), wrapperType);
-        while (cls != null) {
-            try {
-                WrapperHelper helper = WrapperHelper.class.cast(cls.newInstance());
-                if (!helper.getSignature().equals(computeSignature())) {
-                    count++;
-                    newClassName = wrapperType.getName() + "_WrapperTypeHelper" + count;
-                    newClassName = newClassName.replaceAll("\\$", ".");
-                    newClassName = periodToSlashes(newClassName);
-                    cls = super.findClass(newClassName.replace('/', '.'), wrapperType);
-                } else {
-                    return helper;
-                }
-            } catch (Exception e) {
-                return null;
-            }
-        }
-
-
-
-        cw.visit(Opcodes.V1_5,
-                 Opcodes.ACC_PUBLIC | Opcodes.ACC_SUPER,
-                 newClassName,
-                 null,
-                 "java/lang/Object",
-                 new String[] {periodToSlashes(WrapperHelper.class.getName())});
-
-        addConstructor(newClassName, objectFactory == null ? null : objectFactory.getClass());
-        boolean b = addSignature();
-        if (b) {
-            b = addCreateWrapperObject(newClassName,
-                                       objectFactory == null ? null : objectFactory.getClass());
-        }
-        if (b) {
-            b = addGetWrapperParts(newClassName, wrapperType);
-        }
-
-        try {
-            if (b) {
-                cw.visitEnd();
-                byte[] bt = cw.toByteArray();
-                Class<?> cl = loadClass(newClassName.replace('/', '.'), wrapperType, bt);
-                Object o = cl.newInstance();
-                return WrapperHelper.class.cast(o);
-            }
-        } catch (Throwable e) {
-            // ignore, we'll just fall down to reflection based
-        }
-        return null;
-    }
-
-    private String computeSignature() {
-        StringBuilder b = new StringBuilder();
-        b.append(setMethods.length).append(':');
-        for (int x = 0; x < setMethods.length; x++) {
-            if (getMethods[x] == null) {
-                b.append("null,");
-            } else {
-                b.append(getMethods[x].getName()).append('/');
-                b.append(getMethods[x].getReturnType().getName()).append(',');
-            }
-        }
-        return b.toString();
-    }
-
-    private boolean addSignature() {
-        String sig = computeSignature();
-        MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC,
-                                          "getSignature", "()Ljava/lang/String;", null, null);
-        mv.visitCode();
-        mv.visitLdcInsn(sig);
-        Label l0 = createLabel();
-        mv.visitLabel(l0);
-        mv.visitLineNumber(100, l0);
-        mv.visitInsn(Opcodes.ARETURN);
-        mv.visitMaxs(0, 0);
-        mv.visitEnd();
-        return true;
-    }
-
-    private void addConstructor(String newClassName,
-                                Class<?> objectFactoryCls) {
-
-        if (objectFactoryCls != null) {
-            String ofName = "L" + periodToSlashes(objectFactoryCls.getName()) + ";";
-            FieldVisitor fv = cw.visitField(0, "factory",
-                                            ofName,
-                                            null, null);
-            fv.visitEnd();
-        }
-
-        MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
-        mv.visitCode();
-        Label l0 = createLabel();
-        mv.visitLabel(l0);
-        mv.visitLineNumber(102, l0);
-
-        mv.visitVarInsn(Opcodes.ALOAD, 0);
-        mv.visitMethodInsn(Opcodes.INVOKESPECIAL,
-                           "java/lang/Object",
-                           "<init>",
-                           "()V", false);
-        if (objectFactoryCls != null) {
-            mv.visitVarInsn(Opcodes.ALOAD, 0);
-            mv.visitTypeInsn(Opcodes.NEW, periodToSlashes(objectFactoryCls.getName()));
-            mv.visitInsn(Opcodes.DUP);
-            mv.visitMethodInsn(Opcodes.INVOKESPECIAL,
-                               periodToSlashes(objectFactoryCls.getName()),
-                               "<init>", "()V", false);
-            mv.visitFieldInsn(Opcodes.PUTFIELD, periodToSlashes(newClassName),
-                              "factory", "L" + periodToSlashes(objectFactoryCls.getName()) + ";");
-        }
-
-        mv.visitInsn(Opcodes.RETURN);
-
-        Label l1 = createLabel();
-        mv.visitLabel(l1);
-        mv.visitLineNumber(103, l0);
-
-        mv.visitLocalVariable("this", "L" + newClassName + ";", null, l0, l1, 0);
-        mv.visitMaxs(0, 0);
-        mv.visitEnd();
-    }
-
-    private boolean addCreateWrapperObject(String newClassName,
-                                           Class<?> objectFactoryClass) {
-
-        MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC,
-                                          "createWrapperObject",
-                                          "(Ljava/util/List;)Ljava/lang/Object;",
-                                          "(Ljava/util/List<*>;)Ljava/lang/Object;",
-                                          new String[] {
-                                              "org/apache/cxf/interceptor/Fault"
-                                          });
-        mv.visitCode();
-        Label lBegin = createLabel();
-        mv.visitLabel(lBegin);
-        mv.visitLineNumber(104, lBegin);
-
-        mv.visitTypeInsn(Opcodes.NEW, periodToSlashes(wrapperType.getName()));
-        mv.visitInsn(Opcodes.DUP);
-        mv.visitMethodInsn(Opcodes.INVOKESPECIAL, periodToSlashes(wrapperType.getName()),
-                           "<init>", "()V", false);
-        mv.visitVarInsn(Opcodes.ASTORE, 2);
-
-        for (int x = 0; x < setMethods.length; x++) {
-            if (getMethods[x] == null) {
-                if (setMethods[x] == null
-                    && fields[x] == null) {
-                    // null placeholder
-                    continue;
-                }
-                return false;
-            }
-            Class<?> tp = getMethods[x].getReturnType();
-            mv.visitVarInsn(Opcodes.ALOAD, 2);
-
-            if (List.class.isAssignableFrom(tp)) {
-                doCollection(mv, x);
-            } else {
-                if (JAXBElement.class.isAssignableFrom(tp)) {
-                    mv.visitVarInsn(Opcodes.ALOAD, 0);
-                    mv.visitFieldInsn(Opcodes.GETFIELD, periodToSlashes(newClassName),
-                                      "factory",
-                                      "L" + periodToSlashes(objectFactoryClass.getName()) + ";");
-                }
-                mv.visitVarInsn(Opcodes.ALOAD, 1);
-                mv.visitIntInsn(Opcodes.SIPUSH, x);
-                mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/List", "get", "(I)Ljava/lang/Object;", true);
-
-                if (tp.isPrimitive()) {
-                    mv.visitTypeInsn(Opcodes.CHECKCAST, NONPRIMITIVE_MAP.get(tp));
-                    Label l45 = createLabel();
-                    Label l46 = createLabel();
-                    mv.visitInsn(Opcodes.DUP);
-                    mv.visitJumpInsn(Opcodes.IFNULL, l45);
-                    mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, NONPRIMITIVE_MAP.get(tp),
-                                       tp.getName() + "Value", "()" + PRIMITIVE_MAP.get(tp), false);
-                    mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL,
-                                       periodToSlashes(wrapperType.getName()),
-                                       setMethods[x].getName(), "(" + getClassCode(tp) + ")V", false);
-                    mv.visitJumpInsn(Opcodes.GOTO, l46);
-                    mv.visitLabel(l45);
-                    mv.visitInsn(Opcodes.POP);
-                    mv.visitLabel(l46);
-                } else if (JAXBElement.class.isAssignableFrom(tp)) {
-                    mv.visitTypeInsn(Opcodes.CHECKCAST,
-                                     periodToSlashes(jaxbMethods[x].getParameterTypes()[0].getName()));
-                    mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, periodToSlashes(objectFactoryClass.getName()),
-                                       jaxbMethods[x].getName(),
-                                       getMethodSignature(jaxbMethods[x]), false);
-                    mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL,
-                                       periodToSlashes(wrapperType.getName()),
-                                       setMethods[x].getName(), "(" + getClassCode(tp) + ")V", false);
-                } else if (tp.isArray()) {
-                    mv.visitTypeInsn(Opcodes.CHECKCAST, getClassCode(tp));
-                    mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL,
-                                       periodToSlashes(wrapperType.getName()),
-                                       setMethods[x].getName(), "(" + getClassCode(tp) + ")V", false);
-                } else {
-                    mv.visitTypeInsn(Opcodes.CHECKCAST, periodToSlashes(tp.getName()));
-                    mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL,
-                                       periodToSlashes(wrapperType.getName()),
-                                       setMethods[x].getName(), "(" + getClassCode(tp) + ")V", false);
-                }
-            }
-        }
-
-        mv.visitVarInsn(Opcodes.ALOAD, 2);
-        mv.visitInsn(Opcodes.ARETURN);
-
-        Label lEnd = createLabel();
-        mv.visitLabel(lEnd);
-        mv.visitLocalVariable("this", "L" + newClassName + ";", null, lBegin, lEnd, 0);
-        mv.visitLocalVariable("lst", "Ljava/util/List;", "Ljava/util/List<*>;", lBegin, lEnd, 1);
-        mv.visitLocalVariable("ok", "L" + periodToSlashes(wrapperType.getName()) + ";",
-                              null, lBegin, lEnd, 2);
-        mv.visitMaxs(0, 0);
-        mv.visitEnd();
-        return true;
-    }
-
-    private void doCollection(MethodVisitor mv, int x) {
-        // List aVal = obj.getA();
-        // List newA = (List)lst.get(99);
-        // if (aVal == null) {
-        // obj.setA(newA);
-        // } else if (newA != null) {
-        // aVal.addAll(newA);
-        // }
-
-        Label l3 = createLabel();
-        mv.visitLabel(l3);
-        mv.visitLineNumber(114, l3);
-
-        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL,
-                           periodToSlashes(wrapperType.getName()),
-                           getMethods[x].getName(),
-                           getMethodSignature(getMethods[x]), false);
-        mv.visitVarInsn(Opcodes.ASTORE, 3);
-        mv.visitVarInsn(Opcodes.ALOAD, 1);
-        mv.visitIntInsn(Opcodes.SIPUSH, x);
-        mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/List",
-                           "get", "(I)Ljava/lang/Object;", true);
-        mv.visitTypeInsn(Opcodes.CHECKCAST, "java/util/List");
-        mv.visitVarInsn(Opcodes.ASTORE, 4);
-        mv.visitVarInsn(Opcodes.ALOAD, 3);
-        Label nonNullLabel = createLabel();
-        mv.visitJumpInsn(Opcodes.IFNONNULL, nonNullLabel);
-
-        if (setMethods[x] == null) {
-            mv.visitTypeInsn(Opcodes.NEW, "java/lang/RuntimeException");
-            mv.visitInsn(Opcodes.DUP);
-            mv.visitLdcInsn(getMethods[x].getName() + " returned null and there isn't a set method.");
-            mv.visitMethodInsn(Opcodes.INVOKESPECIAL,
-                               "java/lang/RuntimeException",
-                               "<init>", "(Ljava/lang/String;)V", false);
-            mv.visitInsn(Opcodes.ATHROW);
-        } else {
-            mv.visitVarInsn(Opcodes.ALOAD, 2);
-            mv.visitVarInsn(Opcodes.ALOAD, 4);
-            mv.visitTypeInsn(Opcodes.CHECKCAST,
-                             getMethods[x].getReturnType().getName().replace('.', '/'));
-            mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL,
-                               periodToSlashes(wrapperType.getName()),
-                               setMethods[x].getName(),
-                               getMethodSignature(setMethods[x]), false);
-        }
-        Label jumpOverLabel = createLabel();
-        mv.visitJumpInsn(Opcodes.GOTO, jumpOverLabel);
-        mv.visitLabel(nonNullLabel);
-        mv.visitLineNumber(106, nonNullLabel);
-
-        mv.visitVarInsn(Opcodes.ALOAD, 4);
-        mv.visitJumpInsn(Opcodes.IFNULL, jumpOverLabel);
-        mv.visitVarInsn(Opcodes.ALOAD, 3);
-        mv.visitVarInsn(Opcodes.ALOAD, 4);
-        mv.visitMethodInsn(Opcodes.INVOKEINTERFACE,
-                           "java/util/List", "addAll", "(Ljava/util/Collection;)Z", true);
-        mv.visitInsn(Opcodes.POP);
-        mv.visitLabel(jumpOverLabel);
-        mv.visitLineNumber(107, jumpOverLabel);
-    }
-
-    private boolean addGetWrapperParts(String newClassName,
-                                       Class<?> wrapperClass) {
-        MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC,
-                                          "getWrapperParts",
-                                          "(Ljava/lang/Object;)Ljava/util/List;",
-                                          "(Ljava/lang/Object;)Ljava/util/List<Ljava/lang/Object;>;",
-                                          new String[] {
-                                              "org/apache/cxf/interceptor/Fault"
-                                          });
-        mv.visitCode();
-        Label lBegin = createLabel();
-        mv.visitLabel(lBegin);
-        mv.visitLineNumber(108, lBegin);
-
-        // the ret List
-        mv.visitTypeInsn(Opcodes.NEW, "java/util/ArrayList");
-        mv.visitInsn(Opcodes.DUP);
-        mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/util/ArrayList", "<init>", "()V", false);
-        mv.visitVarInsn(Opcodes.ASTORE, 2);
-
-        // cast the Object to the wrapperType type
-        mv.visitVarInsn(Opcodes.ALOAD, 1);
-        mv.visitTypeInsn(Opcodes.CHECKCAST, periodToSlashes(wrapperClass.getName()));
-        mv.visitVarInsn(Opcodes.ASTORE, 3);
-
-        for (int x = 0; x < getMethods.length; x++) {
-            Method method = getMethods[x];
-            if (method == null && fields[x] != null) {
-                // fallback to reflection mode
-                return false;
-            }
-
-            if (method == null) {
-                Label l3 = createLabel();
-                mv.visitLabel(l3);
-                mv.visitLineNumber(200 + x, l3);
-
-                mv.visitVarInsn(Opcodes.ALOAD, 2);
-                mv.visitInsn(Opcodes.ACONST_NULL);
-                mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/List",
-                                   "add", "(Ljava/lang/Object;)Z", true);
-                mv.visitInsn(Opcodes.POP);
-            } else {
-                Label l3 = createLabel();
-                mv.visitLabel(l3);
-                mv.visitLineNumber(250 + x, l3);
-
-                mv.visitVarInsn(Opcodes.ALOAD, 2);
-                mv.visitVarInsn(Opcodes.ALOAD, 3);
-                mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL,
-                                   periodToSlashes(wrapperClass.getName()),
-                                   method.getName(),
-                                   getMethodSignature(method), false);
-                if (method.getReturnType().isPrimitive()) {
-                    // wrap into Object type
-                    createObjectWrapper(mv, method.getReturnType());
-                }
-                if (JAXBElement.class.isAssignableFrom(method.getReturnType())) {
-                    Label jumpOverLabel = createLabel();
-                    mv.visitInsn(Opcodes.DUP);
-                    mv.visitJumpInsn(Opcodes.IFNULL, jumpOverLabel);
-
-                    mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL,
-                                       "javax/xml/bind/JAXBElement",
-                                       "getValue", "()Ljava/lang/Object;", false);
-                    mv.visitLabel(jumpOverLabel);
-                }
-
-                mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/List", "add", "(Ljava/lang/Object;)Z", true);
-                mv.visitInsn(Opcodes.POP);
-            }
-        }
-
-        // return the list
-        Label l2 = createLabel();
-        mv.visitLabel(l2);
-        mv.visitLineNumber(108, l2);
-        mv.visitVarInsn(Opcodes.ALOAD, 2);
-        mv.visitInsn(Opcodes.ARETURN);
-
-
-        Label lEnd = createLabel();
-        mv.visitLabel(lEnd);
-        mv.visitLocalVariable("this", "L" + newClassName + ";", null, lBegin, lEnd, 0);
-        mv.visitLocalVariable("o", "Ljava/lang/Object;", null, lBegin, lEnd, 1);
-        mv.visitLocalVariable("ret", "Ljava/util/List;", "Ljava/util/List<Ljava/lang/Object;>;",
-                              lBegin, lEnd, 2);
-        mv.visitLocalVariable("ok", "L" + periodToSlashes(wrapperClass.getName()) + ";",
-                              null, lBegin, lEnd, 3);
-        mv.visitMaxs(0, 0);
-        mv.visitEnd();
-        return true;
-    }
-
-
-
-
-    private static void createObjectWrapper(MethodVisitor mv, Class<?> cl) {
-        mv.visitMethodInsn(Opcodes.INVOKESTATIC, NONPRIMITIVE_MAP.get(cl),
-                           "valueOf", "(" + PRIMITIVE_MAP.get(cl) + ")L"
-                           + NONPRIMITIVE_MAP.get(cl) + ";", false);
-    }
-}
diff --git a/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/WrapperHelperCreator.java b/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/WrapperHelperCreator.java
new file mode 100644
index 0000000..188bf04
--- /dev/null
+++ b/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/WrapperHelperCreator.java
@@ -0,0 +1,31 @@
+/**
+ * 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.cxf.jaxb;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
+import org.apache.cxf.databinding.WrapperHelper;
+
+public interface WrapperHelperCreator {
+    WrapperHelper compile(Class<?> wrapperType, Method[] setMethods,
+                          Method[] getMethods, Method[] jaxbMethods,
+                          Field[] fields, Object objectFactory);
+}
diff --git a/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/WrapperHelperProxyService.java b/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/WrapperHelperProxyService.java
new file mode 100644
index 0000000..5205264
--- /dev/null
+++ b/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/WrapperHelperProxyService.java
@@ -0,0 +1,53 @@
+/**
+ * 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.cxf.jaxb;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.databinding.WrapperHelper;
+
+public class WrapperHelperProxyService implements WrapperHelperCreator {
+    private final WrapperHelperCreator srv;
+    public WrapperHelperProxyService(Bus bus) {
+        this(new WrapperHelperClassGenerator(bus));
+    }
+    public WrapperHelperProxyService(WrapperHelperCreator srv) {
+        super();
+        this.srv = srv;
+    }
+
+    @Override
+    public WrapperHelper compile(Class<?> wrapperType, Method[] setMethods, Method[] getMethods,
+                                 Method[] jaxbMethods, Field[] fields, Object objectFactory) {
+        return srv.compile(wrapperType, setMethods, getMethods, jaxbMethods, fields, objectFactory);
+    }
+
+    public class LoadFirst extends WrapperHelperProxyService {
+        public LoadFirst(Bus bus) {
+            super(new WrapperHelperClassLoader(bus));
+        }
+    }
+    public class GenerateJustInTime extends WrapperHelperProxyService {
+        public GenerateJustInTime(Bus bus) {
+            super(new WrapperHelperClassGenerator(bus));
+        }
+    }
+}
diff --git a/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/io/DataWriterImpl.java b/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/io/DataWriterImpl.java
index 3186c78..0db8a6e 100644
--- a/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/io/DataWriterImpl.java
+++ b/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/io/DataWriterImpl.java
@@ -39,6 +39,7 @@ import javax.xml.bind.ValidationEventHandler;
 import javax.xml.bind.annotation.adapters.XmlAdapter;
 import javax.xml.bind.attachment.AttachmentMarshaller;
 
+import org.apache.cxf.Bus;
 import org.apache.cxf.common.i18n.Message;
 import org.apache.cxf.common.jaxb.JAXBUtils;
 import org.apache.cxf.common.logging.LogUtils;
@@ -61,14 +62,16 @@ public class DataWriterImpl<T> extends JAXBDataBase implements DataWriter<T> {
     boolean setEventHandler = true;
     boolean noEscape;
     private JAXBDataBinding databinding;
+    private Bus bus;
 
-    public DataWriterImpl(JAXBDataBinding binding) {
-        this(binding, false);
+    public DataWriterImpl(Bus bus, JAXBDataBinding binding) {
+        this(bus, binding, false);
     }
-    public DataWriterImpl(JAXBDataBinding binding, boolean noEsc) {
+    public DataWriterImpl(Bus bus, JAXBDataBinding binding, boolean noEsc) {
         super(binding.getContext());
         databinding = binding;
         noEscape = noEsc;
+        this.bus = bus;
     }
 
     public void write(Object obj, T output) {
@@ -154,7 +157,7 @@ public class DataWriterImpl<T> extends JAXBDataBase implements DataWriter<T> {
             final Map<String, String> nsctxt = databinding.getContextualNamespaceMap();
             // set the prefix mapper if either of the prefix map is configured
             if (nspref != null || nsctxt != null) {
-                Object mapper = JAXBUtils.setNamespaceMapper(nspref != null ? nspref : nsctxt, marshaller);
+                Object mapper = JAXBUtils.setNamespaceMapper(bus, nspref != null ? nspref : nsctxt, marshaller);
                 if (nsctxt != null) {
                     setContextualNamespaceDecls(mapper, nsctxt);
                 }
diff --git a/rt/databinding/jaxb/src/main/resources/META-INF/cxf/bus-extensions.txt b/rt/databinding/jaxb/src/main/resources/META-INF/cxf/bus-extensions.txt
new file mode 100644
index 0000000..a1d4c21
--- /dev/null
+++ b/rt/databinding/jaxb/src/main/resources/META-INF/cxf/bus-extensions.txt
@@ -0,0 +1,2 @@
+org.apache.cxf.jaxb.WrapperHelperProxyService:org.apache.cxf.jaxb.WrapperHelperCreator:true
+org.apache.cxf.jaxb.FactoryClassProxyService:org.apache.cxf.jaxb.FactoryClassCreator:true
\ No newline at end of file
diff --git a/rt/databinding/jaxb/src/test/java/org/apache/cxf/jaxb/JAXBDataBindingTest.java b/rt/databinding/jaxb/src/test/java/org/apache/cxf/jaxb/JAXBDataBindingTest.java
index 22a49a8..2ed593f 100644
--- a/rt/databinding/jaxb/src/test/java/org/apache/cxf/jaxb/JAXBDataBindingTest.java
+++ b/rt/databinding/jaxb/src/test/java/org/apache/cxf/jaxb/JAXBDataBindingTest.java
@@ -54,8 +54,10 @@ import org.w3c.dom.Node;
 
 import org.apache.cxf.Bus;
 import org.apache.cxf.binding.BindingFactoryManager;
+import org.apache.cxf.bus.extension.ExtensionManagerBus;
 import org.apache.cxf.common.logging.LogUtils;
 import org.apache.cxf.common.util.ASMHelper;
+import org.apache.cxf.common.util.ASMHelperImpl;
 import org.apache.cxf.common.util.ReflectionUtil;
 import org.apache.cxf.databinding.DataReader;
 import org.apache.cxf.databinding.DataWriter;
@@ -247,10 +249,15 @@ public class JAXBDataBindingTest {
                 return;
             }
         }
+        Bus b = new ExtensionManagerBus();
+        ASMHelper helper = new ASMHelperImpl();
+        b.setExtension(helper, ASMHelper.class);
+        FactoryClassCreator extr = new FactoryClassProxyService(b);
+        b.setExtension(extr, FactoryClassCreator.class);
         try {
             if (!asm) {
-                ReflectionUtil.setAccessible(ReflectionUtil.getDeclaredField(ASMHelper.class, "badASM"))
-                    .set(null, Boolean.TRUE);
+                ReflectionUtil.setAccessible(ReflectionUtil.getDeclaredField(ASMHelperImpl.class, "badASM"))
+                    .set(helper, Boolean.TRUE);
             }
 
             JAXBDataBinding db = createJaxbContext(internal);
@@ -267,8 +274,8 @@ public class JAXBDataBindingTest {
             assertTrue("Failed to map namespace " + xml, xml.contains("greenland=\"uri:ultima:thule"));
         } finally {
             if (!asm) {
-                ReflectionUtil.setAccessible(ReflectionUtil.getDeclaredField(ASMHelper.class, "badASM"))
-                    .set(null, Boolean.FALSE);
+                ReflectionUtil.setAccessible(ReflectionUtil.getDeclaredField(ASMHelperImpl.class, "badASM"))
+                    .set(helper, Boolean.FALSE);
             }
         }
     }
@@ -300,7 +307,11 @@ public class JAXBDataBindingTest {
         Set<Class<?>> classes = new HashSet<>();
         Collection<Object> typeReferences = new ArrayList<>();
         Map<String, Object> props = new HashMap<>();
-        JAXBContextInitializer init = new JAXBContextInitializer(null, classes, typeReferences, props);
+        Bus b = new ExtensionManagerBus();
+        b.setExtension(new ASMHelperImpl(), ASMHelper.class);
+        FactoryClassCreator extr = new FactoryClassProxyService(b);
+        b.setExtension(extr, FactoryClassCreator.class);
+        JAXBContextInitializer init = new JAXBContextInitializer(b, null, classes, typeReferences, props);
         init.addClass(Type2.class);
         assertEquals(2, classes.size());
     }
@@ -344,7 +355,11 @@ public class JAXBDataBindingTest {
         Set<Class<?>> classes = new HashSet<>();
         Collection<Object> typeReferences = new ArrayList<>();
         Map<String, Object> props = new HashMap<>();
-        JAXBContextInitializer init = new JAXBContextInitializer(null, classes, typeReferences, props);
+        Bus b = new ExtensionManagerBus();
+        b.setExtension(new ASMHelperImpl(), ASMHelper.class);
+        FactoryClassCreator extr = new FactoryClassProxyService(b);
+        b.setExtension(extr, FactoryClassCreator.class);
+        JAXBContextInitializer init = new JAXBContextInitializer(b, null, classes, typeReferences, props);
         init.addClass(sampleClassInDefaultPackage);
         assertEquals(1, classes.size());
     }
diff --git a/rt/databinding/jaxb/src/test/java/org/apache/cxf/jaxb/JAXBEncoderDecoderTest.java b/rt/databinding/jaxb/src/test/java/org/apache/cxf/jaxb/JAXBEncoderDecoderTest.java
index 98e8d21..e19f798 100644
--- a/rt/databinding/jaxb/src/test/java/org/apache/cxf/jaxb/JAXBEncoderDecoderTest.java
+++ b/rt/databinding/jaxb/src/test/java/org/apache/cxf/jaxb/JAXBEncoderDecoderTest.java
@@ -50,6 +50,8 @@ import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
 
+import org.apache.cxf.Bus;
+import org.apache.cxf.bus.extension.ExtensionManagerBus;
 import org.apache.cxf.common.jaxb.JAXBUtils;
 import org.apache.cxf.helpers.DOMUtils;
 import org.apache.cxf.interceptor.Fault;
@@ -251,7 +253,8 @@ public class JAXBEncoderDecoderTest {
         opFactory.setProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES, Boolean.TRUE);
         XMLEventWriter writer = opFactory.createXMLEventWriter(stringWriter);
         Marshaller m = context.createMarshaller();
-        JAXBUtils.setNamespaceMapper(mapper, m);
+        Bus bus = new ExtensionManagerBus();
+        JAXBUtils.setNamespaceMapper(bus, mapper, m);
         JAXBEncoderDecoder.marshall(m, testObject, part, writer);
         writer.flush();
         writer.close();
diff --git a/rt/databinding/jaxb/src/test/java/org/apache/cxf/jaxb/JAXBUtilsTest.java b/rt/databinding/jaxb/src/test/java/org/apache/cxf/jaxb/JAXBUtilsTest.java
index 819ae32..78256f9 100644
--- a/rt/databinding/jaxb/src/test/java/org/apache/cxf/jaxb/JAXBUtilsTest.java
+++ b/rt/databinding/jaxb/src/test/java/org/apache/cxf/jaxb/JAXBUtilsTest.java
@@ -27,6 +27,8 @@ import java.util.Map;
 import javax.xml.bind.JAXBContext;
 import javax.xml.bind.Marshaller;
 
+import org.apache.cxf.Bus;
+import org.apache.cxf.bus.extension.ExtensionManagerBus;
 import org.apache.cxf.common.jaxb.JAXBUtils;
 import org.apache.cxf.common.util.ReflectionUtil;
 import org.apache.hello_world_soap_http.types.GreetMe;
@@ -172,7 +174,8 @@ public class JAXBUtilsTest {
         Marshaller marshaller = ctx.createMarshaller();
         Map<String, String> nspref = new HashMap<>();
         nspref.put("http://cxf.apache.org/hello_world_soap_http/types", "x");
-        JAXBUtils.setNamespaceMapper(nspref, marshaller);
+        Bus bus = new ExtensionManagerBus();
+        JAXBUtils.setNamespaceMapper(bus, nspref, marshaller);
         String mapperkey = null;
         if (marshaller.getClass().getName().contains(".internal.")) {
             mapperkey = "com.sun.xml.internal.bind.namespacePrefixMapper";
diff --git a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractJAXBProvider.java b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractJAXBProvider.java
index a9500e5..ff5353d 100644
--- a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractJAXBProvider.java
+++ b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractJAXBProvider.java
@@ -166,7 +166,7 @@ public abstract class AbstractJAXBProvider<T> extends AbstractConfigurableProvid
 
     protected void setNamespaceMapper(Marshaller ms,
                                       Map<String, String> map) throws Exception {
-        Object nsMapper = JAXBUtils.setNamespaceMapper(map, ms);
+        Object nsMapper = JAXBUtils.setNamespaceMapper(getBus(), map, ms);
         if (nsMapper != null && namespaceMapperPropertyName != null) {
             setMarshallerProp(ms, nsMapper, namespaceMapperPropertyName, null);
         }
diff --git a/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/WrapperClassGenerator.java b/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/WrapperClassGenerator.java
index bcd851e..d4b2ad2 100644
--- a/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/WrapperClassGenerator.java
+++ b/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/WrapperClassGenerator.java
@@ -19,7 +19,6 @@
 
 package org.apache.cxf.jaxws;
 
-
 import java.lang.annotation.Annotation;
 import java.lang.reflect.GenericArrayType;
 import java.lang.reflect.Method;
@@ -42,12 +41,16 @@ import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapters;
 import javax.xml.namespace.QName;
 import javax.xml.ws.Holder;
 
+import org.apache.cxf.Bus;
 import org.apache.cxf.common.jaxb.JAXBUtils;
 import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.common.spi.ClassGeneratorClassLoader;
 import org.apache.cxf.common.util.ASMHelper;
+import org.apache.cxf.common.util.OpcodesProxy;
 import org.apache.cxf.common.util.PackageUtils;
 import org.apache.cxf.common.util.StringUtils;
 import org.apache.cxf.helpers.JavaUtils;
+import org.apache.cxf.jaxws.spi.WrapperClassCreator;
 import org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean;
 import org.apache.cxf.service.model.InterfaceInfo;
 import org.apache.cxf.service.model.MessageInfo;
@@ -56,19 +59,15 @@ import org.apache.cxf.service.model.OperationInfo;
 import org.apache.cxf.service.model.SchemaInfo;
 import org.apache.cxf.wsdl.service.factory.ReflectionServiceFactoryBean;
 
-public final class WrapperClassGenerator extends ASMHelper {
+public final class WrapperClassGenerator extends ClassGeneratorClassLoader implements WrapperClassCreator {
     public static final String DEFAULT_PACKAGE_NAME = "defaultnamespace";
 
     private static final Logger LOG = LogUtils.getL7dLogger(WrapperClassGenerator.class);
-    private Set<Class<?>> wrapperBeans = new LinkedHashSet<>();
-    private InterfaceInfo interfaceInfo;
-    private boolean qualified;
-    private JaxWsServiceFactoryBean factory;
-
-    public WrapperClassGenerator(JaxWsServiceFactoryBean fact, InterfaceInfo inf, boolean q) {
-        factory = fact;
-        interfaceInfo = inf;
-        qualified = q;
+    private final ASMHelper helper;
+
+    public WrapperClassGenerator(Bus bus) {
+        super(bus);
+        helper = bus.getExtension(ASMHelper.class);
     }
 
     private String getPackageName(Method method) {
@@ -109,7 +108,8 @@ public final class WrapperClassGenerator extends ASMHelper {
         return list;
     }
 
-    public Set<Class<?>> generate() {
+    public Set<Class<?>> generate(JaxWsServiceFactoryBean factory, InterfaceInfo interfaceInfo, boolean qualified) {
+        Set<Class<?>> wrapperBeans = new LinkedHashSet<>();
         for (OperationInfo opInfo : interfaceInfo.getOperations()) {
             if (opInfo.isUnwrappedCapable()) {
                 Method method = (Method)opInfo.getProperty(ReflectionServiceFactoryBean.METHOD);
@@ -123,7 +123,11 @@ public final class WrapperClassGenerator extends ASMHelper {
                                        messageInfo,
                                        opInfo,
                                        method,
-                                       true);
+                                       true,
+                                       wrapperBeans,
+                                       factory,
+                                       interfaceInfo,
+                                       qualified);
                 }
                 MessageInfo messageInfo = opInfo.getUnwrappedOperation().getOutput();
                 if (messageInfo != null) {
@@ -133,22 +137,30 @@ public final class WrapperClassGenerator extends ASMHelper {
                                            messageInfo,
                                            opInfo,
                                            method,
-                                           false);
+                                           false,
+                                            wrapperBeans,
+                                            factory,
+                                            interfaceInfo,
+                                            qualified);
                     }
                 }
             }
         }
         return wrapperBeans;
     }
-
+    //CHECKSTYLE:OFF
     private void createWrapperClass(MessagePartInfo wrapperPart,
                                         MessageInfo messageInfo,
                                         OperationInfo op,
                                         Method method,
-                                        boolean isRequest) {
+                                        boolean isRequest,
+                                        Set<Class<?>> wrapperBeans,
+                                        JaxWsServiceFactoryBean factory,
+                                        InterfaceInfo interfaceInfo,
+                                        boolean qualified) {
 
 
-        ClassWriter cw = createClassWriter();
+        ASMHelper.ClassWriter cw = helper.createClassWriter();
         if (cw == null) {
             LOG.warning(op.getName() + " requires a wrapper bean but problems with"
                 + " ASM has prevented creating one. Operation may not work correctly.");
@@ -166,8 +178,8 @@ public final class WrapperClassGenerator extends ASMHelper {
         String pname = pkg + ".package-info";
         Class<?> def = findClass(pname, method.getDeclaringClass());
         if (def == null) {
-            generatePackageInfo(pname, wrapperElement.getNamespaceURI(),
-                                method.getDeclaringClass());
+            generatePackageInfo(pname, wrapperElement.getNamespaceURI(), method.getDeclaringClass(), method,
+                    interfaceInfo, qualified);
         }
 
         def = findClass(className, method.getDeclaringClass());
@@ -184,11 +196,12 @@ public final class WrapperClassGenerator extends ASMHelper {
                 return;
             }
         }
-        String classFileName = periodToSlashes(className);
-        cw.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC + Opcodes.ACC_SUPER, classFileName, null,
+        String classFileName = StringUtils.periodToSlashes(className);
+        OpcodesProxy opCodes = helper.getOpCodes();
+        cw.visit(opCodes.V1_5, opCodes.ACC_PUBLIC + opCodes.ACC_SUPER, classFileName, null,
                  "java/lang/Object", null);
 
-        AnnotationVisitor av0 = cw.visitAnnotation("Ljavax/xml/bind/annotation/XmlRootElement;", true);
+        ASMHelper.AnnotationVisitor av0 = cw.visitAnnotation("Ljavax/xml/bind/annotation/XmlRootElement;", true);
         av0.visit("name", wrapperElement.getLocalPart());
         av0.visit("namespace", wrapperElement.getNamespaceURI());
         av0.visitEnd();
@@ -207,21 +220,21 @@ public final class WrapperClassGenerator extends ASMHelper {
         av0.visitEnd();
 
         // add constructor
-        MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
+        ASMHelper.MethodVisitor mv = cw.visitMethod(opCodes.ACC_PUBLIC, "<init>", "()V", null, null);
         mv.visitCode();
-        Label lbegin = createLabel();
+        ASMHelper.Label lbegin = helper.createLabel();
         mv.visitLabel(lbegin);
-        mv.visitVarInsn(Opcodes.ALOAD, 0);
-        mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
-        mv.visitInsn(Opcodes.RETURN);
-        Label lend = createLabel();
+        mv.visitVarInsn(opCodes.ALOAD, 0);
+        mv.visitMethodInsn(opCodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
+        mv.visitInsn(opCodes.RETURN);
+        ASMHelper.Label lend = helper.createLabel();
         mv.visitLabel(lend);
         mv.visitLocalVariable("this", "L" + classFileName + ";", null, lbegin, lend, 0);
-        mv.visitMaxs(1, 1);
+        mv.visitMaxs(0, 0);
         mv.visitEnd();
 
         for (MessagePartInfo mpi : messageInfo.getMessageParts()) {
-            generateMessagePart(cw, mpi, method, classFileName);
+            generateMessagePart(cw, mpi, method, classFileName, factory);
         }
 
         cw.visitEnd();
@@ -230,11 +243,13 @@ public final class WrapperClassGenerator extends ASMHelper {
         wrapperPart.setTypeClass(clz);
         wrapperBeans.add(clz);
     }
-
-    private void generatePackageInfo(String className, String ns, Class<?> clz) {
-        ClassWriter cw = createClassWriter();
-        String classFileName = periodToSlashes(className);
-        cw.visit(Opcodes.V1_5, Opcodes.ACC_ABSTRACT + Opcodes.ACC_INTERFACE, classFileName, null,
+    //CHECKSTYLE:ON
+    private void generatePackageInfo(String className, String ns, Class<?> clz, Method method,
+                                    InterfaceInfo interfaceInfo, boolean qualified) {
+        ASMHelper.ClassWriter cw = helper.createClassWriter();
+        String classFileName = StringUtils.periodToSlashes(className);
+        OpcodesProxy opCodes = helper.getOpCodes();
+        cw.visit(opCodes.V1_5, opCodes.ACC_ABSTRACT + opCodes.ACC_INTERFACE, classFileName, null,
                  "java/lang/Object", null);
 
         boolean q = qualified;
@@ -242,10 +257,10 @@ public final class WrapperClassGenerator extends ASMHelper {
         if (si != null) {
             q = si.isElementFormQualified();
         }
-        AnnotationVisitor av0 = cw.visitAnnotation("Ljavax/xml/bind/annotation/XmlSchema;", true);
+        ASMHelper.AnnotationVisitor av0 = cw.visitAnnotation("Ljavax/xml/bind/annotation/XmlSchema;", true);
         av0.visit("namespace", ns);
         av0.visitEnum("elementFormDefault",
-                      getClassCode(XmlNsForm.class),
+                helper.getClassCode(XmlNsForm.class),
                       q ? "QUALIFIED" : "UNQUALIFIED");
         av0.visitEnd();
 
@@ -264,35 +279,36 @@ public final class WrapperClassGenerator extends ASMHelper {
         }
         cw.visitEnd();
 
-        loadClass(className, clz, cw.toByteArray());
+        loadClass(className, method.getDeclaringClass(), cw.toByteArray());
     }
 
-    private void generateXmlJavaTypeAdapters(AnnotationVisitor av, XmlJavaTypeAdapters adapters) {
-        AnnotationVisitor av1 = av.visitArray("value");
+    private void generateXmlJavaTypeAdapters(ASMHelper.AnnotationVisitor av, XmlJavaTypeAdapters adapters) {
+        ASMHelper.AnnotationVisitor av1 = av.visitArray("value");
 
         for (XmlJavaTypeAdapter adapter : adapters.value()) {
-            AnnotationVisitor av2
+            ASMHelper.AnnotationVisitor av2
                 = av1.visitAnnotation(null, "Ljavax/xml/bind/annotation/adapters/XmlJavaTypeAdapter;");
             generateXmlJavaTypeAdapter(av2, adapter);
             av2.visitEnd();
         }
         av1.visitEnd();
     }
-    private void generateXmlJavaTypeAdapter(AnnotationVisitor av, XmlJavaTypeAdapter adapter) {
+    private void generateXmlJavaTypeAdapter(ASMHelper.AnnotationVisitor av, XmlJavaTypeAdapter adapter) {
         if (adapter.value() != null) {
-            av.visit("value", getType(getClassCode(adapter.value())));
+            av.visit("value", helper.getType(helper.getClassCode(adapter.value())));
         }
         if (adapter.type() != javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter.DEFAULT.class) {
-            av.visit("type", getType(getClassCode(adapter.type())));
+            av.visit("type", helper.getType(helper.getClassCode(adapter.type())));
         }
     }
 
-    private void generateMessagePart(ClassWriter cw, MessagePartInfo mpi,
-                                     Method method, String className) {
+    private void generateMessagePart(ASMHelper.ClassWriter cw, MessagePartInfo mpi,
+                                     Method method, String className, JaxWsServiceFactoryBean factory) {
         if (Boolean.TRUE.equals(mpi.getProperty(ReflectionServiceFactoryBean.HEADER))) {
             return;
         }
-        String classFileName = periodToSlashes(className);
+        OpcodesProxy opCodes = helper.getOpCodes();
+        String classFileName = StringUtils.periodToSlashes(className);
         String name = mpi.getName().getLocalPart();
         Class<?> clz = mpi.getTypeClass();
         Object obj = mpi.getProperty(ReflectionServiceFactoryBean.RAW_CLASS);
@@ -307,7 +323,7 @@ public final class WrapperClassGenerator extends ASMHelper {
                 genericType = tp.getActualTypeArguments()[0];
             }
         }
-        String classCode = getClassCode(clz);
+        String classCode = helper.getClassCode(clz);
         String fieldDescriptor = null;
 
         if (genericType instanceof ParameterizedType) {
@@ -317,24 +333,24 @@ public final class WrapperClassGenerator extends ASMHelper {
                 java.lang.reflect.Type[] types = ptype.getActualTypeArguments();
                 if (types.length > 0) {
                     if (types[0] instanceof Class) {
-                        fieldDescriptor = getClassCode(genericType);
+                        fieldDescriptor = helper.getClassCode(genericType);
                     } else if (types[0] instanceof GenericArrayType) {
-                        fieldDescriptor = getClassCode(genericType);
+                        fieldDescriptor = helper.getClassCode(genericType);
                     } else if (Collection.class.isAssignableFrom(clz)) {
-                        fieldDescriptor = getClassCode(genericType);
+                        fieldDescriptor = helper.getClassCode(genericType);
                     } else if (types[0] instanceof ParameterizedType) {
-                        classCode = getClassCode(((ParameterizedType)types[0]).getRawType());
-                        fieldDescriptor = getClassCode(genericType);
+                        classCode = helper.getClassCode(((ParameterizedType)types[0]).getRawType());
+                        fieldDescriptor = helper.getClassCode(genericType);
                     }
                 }
             } else {
-                classCode = getClassCode(((ParameterizedType)genericType).getRawType());
-                fieldDescriptor = getClassCode(genericType);
+                classCode = helper.getClassCode(((ParameterizedType)genericType).getRawType());
+                fieldDescriptor = helper.getClassCode(genericType);
             }
         }
         String fieldName = JavaUtils.isJavaKeyword(name) ? JavaUtils.makeNonJavaKeyword(name) : name;
 
-        FieldVisitor fv = cw.visitField(Opcodes.ACC_PRIVATE,
+        ASMHelper.FieldVisitor fv = cw.visitField(opCodes.ACC_PRIVATE,
                                         fieldName,
                                         classCode,
                                         fieldDescriptor,
@@ -344,7 +360,7 @@ public final class WrapperClassGenerator extends ASMHelper {
 
         List<Annotation> jaxbAnnos = getJaxbAnnos(mpi);
         if (!addJAXBAnnotations(fv, jaxbAnnos, name)) {
-            AnnotationVisitor av0 = fv.visitAnnotation("Ljavax/xml/bind/annotation/XmlElement;", true);
+            ASMHelper.AnnotationVisitor av0 = fv.visitAnnotation("Ljavax/xml/bind/annotation/XmlElement;", true);
             av0.visit("name", name);
             if (Boolean.TRUE.equals(factory.isWrapperPartQualified(mpi))) {
                 av0.visit("namespace", mpi.getConcreteName().getNamespaceURI());
@@ -360,35 +376,35 @@ public final class WrapperClassGenerator extends ASMHelper {
         fv.visitEnd();
 
         String methodName = JAXBUtils.nameToIdentifier(name, JAXBUtils.IdentifierType.GETTER);
-        MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, methodName, "()" + classCode,
+        ASMHelper.MethodVisitor mv = cw.visitMethod(opCodes.ACC_PUBLIC, methodName, "()" + classCode,
                                           fieldDescriptor == null ? null : "()" + fieldDescriptor,
                                           null);
         mv.visitCode();
 
-        mv.visitVarInsn(Opcodes.ALOAD, 0);
-        mv.visitFieldInsn(Opcodes.GETFIELD, classFileName, fieldName, classCode);
-        mv.visitInsn(getType(classCode).getOpcode(Opcodes.IRETURN));
+        mv.visitVarInsn(opCodes.ALOAD, 0);
+        mv.visitFieldInsn(opCodes.GETFIELD, classFileName, fieldName, classCode);
+        mv.visitInsn(helper.getType(classCode).getOpcode(opCodes.IRETURN));
         mv.visitMaxs(0, 0);
         mv.visitEnd();
 
         methodName = JAXBUtils.nameToIdentifier(name, JAXBUtils.IdentifierType.SETTER);
-        mv = cw.visitMethod(Opcodes.ACC_PUBLIC, methodName, "(" + classCode + ")V",
+        mv = cw.visitMethod(opCodes.ACC_PUBLIC, methodName, "(" + classCode + ")V",
                             fieldDescriptor == null ? null : "(" + fieldDescriptor + ")V", null);
         mv.visitCode();
-        mv.visitVarInsn(Opcodes.ALOAD, 0);
-        ASMType setType = getType(classCode);
-        mv.visitVarInsn(setType.getOpcode(Opcodes.ILOAD), 1);
-        mv.visitFieldInsn(Opcodes.PUTFIELD, className, fieldName, classCode);
-        mv.visitInsn(Opcodes.RETURN);
+        mv.visitVarInsn(opCodes.ALOAD, 0);
+        ASMHelper.ASMType setType = helper.getType(classCode);
+        mv.visitVarInsn(setType.getOpcode(opCodes.ILOAD), 1);
+        mv.visitFieldInsn(opCodes.PUTFIELD, className, fieldName, classCode);
+        mv.visitInsn(opCodes.RETURN);
         mv.visitMaxs(0, 0);
         mv.visitEnd();
 
     }
 
-    private boolean addJAXBAnnotations(FieldVisitor fv,
+    private boolean addJAXBAnnotations(ASMHelper.FieldVisitor fv,
                                        List<Annotation> jaxbAnnos,
                                        String name) {
-        AnnotationVisitor av0;
+        ASMHelper.AnnotationVisitor av0;
         boolean addedEl = false;
         for (Annotation ann : jaxbAnnos) {
             if (ann instanceof XmlMimeType) {
diff --git a/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/spi/WrapperClassCreator.java b/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/spi/WrapperClassCreator.java
new file mode 100644
index 0000000..4d3992d
--- /dev/null
+++ b/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/spi/WrapperClassCreator.java
@@ -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.cxf.jaxws.spi;
+
+import java.util.Set;
+
+import org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean;
+import org.apache.cxf.service.model.InterfaceInfo;
+
+public interface WrapperClassCreator {
+    Set<Class<?>> generate(JaxWsServiceFactoryBean fact, InterfaceInfo inf, boolean q);
+}
diff --git a/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/spi/WrapperClassCreatorProxyService.java b/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/spi/WrapperClassCreatorProxyService.java
new file mode 100644
index 0000000..75ea8db
--- /dev/null
+++ b/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/spi/WrapperClassCreatorProxyService.java
@@ -0,0 +1,53 @@
+/**
+ * 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.cxf.jaxws.spi;
+
+import java.util.Set;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.jaxws.WrapperClassGenerator;
+import org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean;
+import org.apache.cxf.service.model.InterfaceInfo;
+
+public class WrapperClassCreatorProxyService implements WrapperClassCreator {
+    private final WrapperClassCreator srv;
+    public WrapperClassCreatorProxyService(final Bus bus) {
+        this(new WrapperClassGenerator(bus));
+    }
+    public WrapperClassCreatorProxyService(WrapperClassCreator srv) {
+        super();
+        this.srv = srv;
+    }
+
+    @Override
+    public Set<Class<?>> generate(JaxWsServiceFactoryBean fact, InterfaceInfo inf, boolean q) {
+        return srv.generate(fact, inf, q);
+    }
+
+    public class LoadFirst extends WrapperClassCreatorProxyService {
+        public LoadFirst(Bus bus) {
+            super(new WrapperClassLoader(bus));
+        }
+    }
+    public class GenerateJustInTime extends WrapperClassCreatorProxyService {
+        public GenerateJustInTime(final Bus bus) {
+            super(new WrapperClassGenerator(bus));
+        }
+    }
+}
diff --git a/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/spi/WrapperClassLoader.java b/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/spi/WrapperClassLoader.java
new file mode 100644
index 0000000..dfaf195
--- /dev/null
+++ b/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/spi/WrapperClassLoader.java
@@ -0,0 +1,119 @@
+/**
+ * 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.cxf.jaxws.spi;
+
+import java.lang.reflect.Method;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.common.spi.GeneratedClassClassLoader;
+import org.apache.cxf.common.util.PackageUtils;
+import org.apache.cxf.common.util.StringUtils;
+import org.apache.cxf.jaxws.WrapperClassGenerator;
+import org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean;
+import org.apache.cxf.service.model.InterfaceInfo;
+import org.apache.cxf.service.model.MessageInfo;
+import org.apache.cxf.service.model.MessagePartInfo;
+import org.apache.cxf.service.model.OperationInfo;
+import org.apache.cxf.wsdl.service.factory.ReflectionServiceFactoryBean;
+
+/** If class has been generated during build time
+ *  (use @see org.apache.cxf.common.spi.GeneratedClassClassLoaderCapture capture to save bytes)
+ *  you can set class loader to avoid class generation during runtime:
+ *  bus.setExtension(new GeneratedWrapperClassLoader(bus), WrapperClassCreator.class);
+ * @author olivier dufour
+ */
+public class WrapperClassLoader extends GeneratedClassClassLoader implements WrapperClassCreator {
+    public WrapperClassLoader(Bus bus) {
+        super(bus);
+    }
+
+    @Override
+    public Set<Class<?>> generate(JaxWsServiceFactoryBean factory, InterfaceInfo interfaceInfo, boolean q) {
+        Set<Class<?>> wrapperBeans = new LinkedHashSet<>();
+        for (OperationInfo opInfo : interfaceInfo.getOperations()) {
+            if (opInfo.isUnwrappedCapable()) {
+                Method method = (Method)opInfo.getProperty(ReflectionServiceFactoryBean.METHOD);
+                if (method == null) {
+                    continue;
+                }
+                MessagePartInfo inf = opInfo.getInput().getFirstMessagePart();
+                if (inf.getTypeClass() == null) {
+                    MessageInfo messageInfo = opInfo.getUnwrappedOperation().getInput();
+                    wrapperBeans.add(createWrapperClass(inf,
+                            messageInfo,
+                            opInfo,
+                            method,
+                            true,
+                            factory));
+                }
+                MessageInfo messageInfo = opInfo.getUnwrappedOperation().getOutput();
+                if (messageInfo != null) {
+                    inf = opInfo.getOutput().getFirstMessagePart();
+                    if (inf.getTypeClass() == null) {
+                        wrapperBeans.add(createWrapperClass(inf,
+                                messageInfo,
+                                opInfo,
+                                method,
+                                false,
+                                factory));
+                    }
+                }
+            }
+        }
+        return wrapperBeans;
+    }
+
+    private Class<?> createWrapperClass(MessagePartInfo wrapperPart,
+                                    MessageInfo messageInfo,
+                                    OperationInfo op,
+                                    Method method,
+                                    boolean isRequest,
+                                    JaxWsServiceFactoryBean factory) {
+        boolean anonymous = factory.getAnonymousWrapperTypes();
+
+        String pkg = getPackageName(method) + ".jaxws_asm" + (anonymous ? "_an" : "");
+        String className = pkg + "."
+                + StringUtils.capitalize(op.getName().getLocalPart());
+        if (!isRequest) {
+            className = className + "Response";
+        }
+
+        Class<?> def = findClass(className, method.getDeclaringClass());
+        String origClassName = className;
+        int count = 0;
+        while (def != null) {
+            Boolean b = messageInfo.getProperty("parameterized", Boolean.class);
+            if (b != null && b) {
+                className = origClassName + (++count);
+                def = findClass(className, method.getDeclaringClass());
+            } else {
+                wrapperPart.setTypeClass(def);
+                return def;
+            }
+        }
+        //throw new ClassNotFoundException(origClassName);
+        return null;
+    }
+    private String getPackageName(Method method) {
+        String pkg = PackageUtils.getPackageName(method.getDeclaringClass());
+        return pkg.length() == 0 ? WrapperClassGenerator.DEFAULT_PACKAGE_NAME : pkg;
+    }
+}
diff --git a/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/support/JaxWsServiceFactoryBean.java b/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/support/JaxWsServiceFactoryBean.java
index 4e98839..2153c64 100644
--- a/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/support/JaxWsServiceFactoryBean.java
+++ b/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/support/JaxWsServiceFactoryBean.java
@@ -68,8 +68,8 @@ import org.apache.cxf.helpers.CastUtils;
 import org.apache.cxf.jaxws.JAXWSMethodDispatcher;
 import org.apache.cxf.jaxws.JAXWSMethodInvoker;
 import org.apache.cxf.jaxws.JAXWSProviderMethodDispatcher;
-import org.apache.cxf.jaxws.WrapperClassGenerator;
 import org.apache.cxf.jaxws.interceptors.WebFaultOutInterceptor;
+import org.apache.cxf.jaxws.spi.WrapperClassCreator;
 import org.apache.cxf.service.factory.FactoryBeanListener;
 import org.apache.cxf.service.factory.FactoryBeanListener.Event;
 import org.apache.cxf.service.factory.ServiceConstructionException;
@@ -666,10 +666,10 @@ public class JaxWsServiceFactoryBean extends ReflectionServiceFactoryBean {
         if (b.getClass().getName().endsWith("JAXBDataBinding")
             && schemaLocations == null) {
             ServiceInfo serviceInfo = getService().getServiceInfos().get(0);
-            WrapperClassGenerator wrapperGen = new WrapperClassGenerator(this,
-                                                                         serviceInfo.getInterface(),
-                                                                         getQualifyWrapperSchema());
-            return wrapperGen.generate();
+            WrapperClassCreator wrapperGen = getBus().getExtension(WrapperClassCreator.class);
+            return wrapperGen.generate(this,
+                    serviceInfo.getInterface(),
+                    getQualifyWrapperSchema());
         }
         return Collections.emptySet();
     }
diff --git a/rt/frontend/jaxws/src/main/resources/META-INF/cxf/bus-extensions.txt b/rt/frontend/jaxws/src/main/resources/META-INF/cxf/bus-extensions.txt
index 5bec1e5..ea4dc9d 100644
--- a/rt/frontend/jaxws/src/main/resources/META-INF/cxf/bus-extensions.txt
+++ b/rt/frontend/jaxws/src/main/resources/META-INF/cxf/bus-extensions.txt
@@ -1 +1,2 @@
 org.apache.cxf.jaxws.context.WebServiceContextResourceResolver::true
+org.apache.cxf.jaxws.spi.WrapperClassCreatorProxyService:org.apache.cxf.jaxws.spi.WrapperClassCreator:true
\ No newline at end of file
diff --git a/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/WrapperClassGeneratorTest.java b/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/WrapperNamespaceClassGeneratorTest.java
similarity index 62%
rename from rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/WrapperClassGeneratorTest.java
rename to rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/WrapperNamespaceClassGeneratorTest.java
index fe788c7..1d98893 100644
--- a/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/WrapperClassGeneratorTest.java
+++ b/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/WrapperNamespaceClassGeneratorTest.java
@@ -21,14 +21,23 @@ package org.apache.cxf.jaxws;
 
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 import javax.xml.bind.JAXBContext;
 import javax.xml.bind.Marshaller;
 
+import org.apache.cxf.Bus;
 import org.apache.cxf.BusFactory;
+import org.apache.cxf.common.spi.GeneratedClassClassLoader;
+import org.apache.cxf.common.spi.GeneratedClassClassLoaderCapture;
 import org.apache.cxf.databinding.WrapperHelper;
 import org.apache.cxf.jaxb.JAXBDataBinding;
+import org.apache.cxf.jaxb.JAXBWrapperHelper;
+import org.apache.cxf.jaxb.WrapperHelperClassLoader;
+import org.apache.cxf.jaxb.WrapperHelperCreator;
+import org.apache.cxf.jaxws.service.AddNumbers2Impl;
 import org.apache.cxf.jaxws.service.AddNumbersImpl;
 import org.apache.cxf.jaxws.support.JaxWsImplementorInfo;
 import org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean;
@@ -39,9 +48,10 @@ import org.apache.cxf.service.model.ServiceInfo;
 
 import org.junit.After;
 
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
-public class WrapperClassGeneratorTest {
+public class WrapperNamespaceClassGeneratorTest {
 
     @After
     public void tearDown() {
@@ -119,5 +129,60 @@ public class WrapperClassGeneratorTest {
         assertTrue("The generated response wrapper class is not correct", bout.toString().contains(expected));
 
     }
+    public static class Capture implements GeneratedClassClassLoaderCapture {
+        private final Map<String, byte[]> sources;
+        public Capture() {
+            sources = new HashMap<>();
+        }
+        public void capture(String className, byte[] bytes) {
+            sources.put(className, bytes);
+        }
+
+        public void restore(GeneratedClassClassLoader.TypeHelperClassLoader cl) {
+            for  (Map.Entry<String, byte[]> cls : sources.entrySet()) {
+                cl.defineClass(cls.getKey(), cls.getValue());
+            }
+        }
+    }
+
+    @org.junit.Test
+    public void testGeneratedFirst() throws Exception {
+        JaxWsImplementorInfo implInfo =
+                new JaxWsImplementorInfo(AddNumbers2Impl.class);
+        JaxWsServiceFactoryBean jaxwsFac = new JaxWsServiceFactoryBean(implInfo);
+        Bus bus = BusFactory.getDefaultBus();
+        jaxwsFac.setBus(bus);
+        Capture c = new Capture();
+        bus.setExtension(c, GeneratedClassClassLoaderCapture.class);
+        Service service = jaxwsFac.create();
+
+
+        ServiceInfo serviceInfo = service.getServiceInfos().get(0);
+
+        InterfaceInfo interfaceInfo = serviceInfo.getInterface();
+        OperationInfo inf = interfaceInfo.getOperations().iterator().next();
+        Class<?> requestClass = inf.getInput().getMessagePart(0).getTypeClass();
 
+        // Create request wrapper Object
+        List<String> partNames = Arrays.asList(new String[] {"arg0"});
+        List<String> elTypeNames = Arrays.asList(new String[] {"list"});
+        List<Class<?>> partClasses = Arrays.asList(new Class<?>[] {List.class});
+
+        // generate class and store it to class loader
+        WrapperHelper wh = new JAXBDataBinding().createWrapperHelper(requestClass, null,
+                partNames, elTypeNames, partClasses);
+
+        // now no more generation is allowed
+        WrapperHelperClassLoader wrapperHelperClassLoader = new WrapperHelperClassLoader(bus);
+
+        GeneratedClassClassLoader.TypeHelperClassLoader cl = wrapperHelperClassLoader.getClassLoader();
+        c.restore(cl);
+
+        bus.setExtension(wrapperHelperClassLoader, WrapperHelperCreator.class);
+
+        wh = new JAXBDataBinding().createWrapperHelper(requestClass, null,
+                partNames, elTypeNames, partClasses);
+
+        assertFalse("Precompiled class not loaded", wh instanceof JAXBWrapperHelper);
+    }
 }
\ No newline at end of file
diff --git a/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/service/AddNumbers2.java b/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/service/AddNumbers2.java
new file mode 100644
index 0000000..236cd56
--- /dev/null
+++ b/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/service/AddNumbers2.java
@@ -0,0 +1,35 @@
+/**
+ * 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.cxf.jaxws.service;
+import java.util.List;
+
+import javax.jws.WebMethod;
+import javax.jws.WebParam;
+import javax.jws.WebService;
+import javax.xml.bind.annotation.XmlList;
+
+@WebService
+public interface AddNumbers2 {
+    @WebMethod
+    List<Integer> addListNumbers(
+                             @WebParam
+                             @XmlList
+                             List<String> arg);
+}
diff --git a/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/service/AddNumbers2Impl.java b/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/service/AddNumbers2Impl.java
new file mode 100644
index 0000000..6804f7a
--- /dev/null
+++ b/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/service/AddNumbers2Impl.java
@@ -0,0 +1,36 @@
+/**
+ * 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.cxf.jaxws.service;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@javax.jws.WebService(endpointInterface = "org.apache.cxf.jaxws.service.AddNumbers2")
+public class AddNumbers2Impl implements AddNumbers2 {
+
+    public List<Integer> addListNumbers(List<String> arg) {
+        List<Integer> res = new ArrayList<>();
+        res.add(100);
+        res.add(200);
+        return res;
+
+    }
+
+}
diff --git a/rt/frontend/simple/src/main/java/org/apache/cxf/endpoint/dynamic/DynamicClientFactory.java b/rt/frontend/simple/src/main/java/org/apache/cxf/endpoint/dynamic/DynamicClientFactory.java
index e8e8d41..514b2f7 100644
--- a/rt/frontend/simple/src/main/java/org/apache/cxf/endpoint/dynamic/DynamicClientFactory.java
+++ b/rt/frontend/simple/src/main/java/org/apache/cxf/endpoint/dynamic/DynamicClientFactory.java
@@ -431,7 +431,7 @@ public class DynamicClientFactory {
         // Setup the new classloader!
         ClassLoaderUtils.setThreadContextClassloader(cl);
 
-        TypeClassInitializer visitor = new TypeClassInitializer(svcfo,
+        TypeClassInitializer visitor = new TypeClassInitializer(bus, svcfo,
                                                                 intermediateModel,
                                                                 allowWrapperOps());
         visitor.walk();
diff --git a/rt/frontend/simple/src/main/java/org/apache/cxf/endpoint/dynamic/ExceptionClassCreator.java b/rt/frontend/simple/src/main/java/org/apache/cxf/endpoint/dynamic/ExceptionClassCreator.java
new file mode 100644
index 0000000..4fd60e5
--- /dev/null
+++ b/rt/frontend/simple/src/main/java/org/apache/cxf/endpoint/dynamic/ExceptionClassCreator.java
@@ -0,0 +1,23 @@
+/**
+ * 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.cxf.endpoint.dynamic;
+
+public interface ExceptionClassCreator {
+    Class<?> createExceptionClass(Class<?> bean);
+}
diff --git a/rt/frontend/simple/src/main/java/org/apache/cxf/endpoint/dynamic/ExceptionClassCreatorProxyService.java b/rt/frontend/simple/src/main/java/org/apache/cxf/endpoint/dynamic/ExceptionClassCreatorProxyService.java
new file mode 100644
index 0000000..0fb73d8
--- /dev/null
+++ b/rt/frontend/simple/src/main/java/org/apache/cxf/endpoint/dynamic/ExceptionClassCreatorProxyService.java
@@ -0,0 +1,48 @@
+/**
+ * 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.cxf.endpoint.dynamic;
+
+import org.apache.cxf.Bus;
+
+public class ExceptionClassCreatorProxyService implements ExceptionClassCreator {
+    private final ExceptionClassCreator srv;
+    public ExceptionClassCreatorProxyService(Bus bus) {
+        this(new ExceptionClassGenerator(bus));
+    }
+    public ExceptionClassCreatorProxyService(ExceptionClassCreator srv) {
+        super();
+        this.srv = srv;
+    }
+
+    @Override
+    public Class<?> createExceptionClass(Class<?> bean) {
+        return srv.createExceptionClass(bean);
+    }
+
+    public class LoadFirst extends ExceptionClassCreatorProxyService {
+        public LoadFirst(Bus bus) {
+            super(new ExceptionClassLoader(bus));
+        }
+    }
+    public class GenerateJustInTime extends ExceptionClassCreatorProxyService {
+        public GenerateJustInTime(Bus bus) {
+            super(new ExceptionClassGenerator(bus));
+        }
+    }
+}
\ No newline at end of file
diff --git a/rt/frontend/simple/src/main/java/org/apache/cxf/endpoint/dynamic/ExceptionClassGenerator.java b/rt/frontend/simple/src/main/java/org/apache/cxf/endpoint/dynamic/ExceptionClassGenerator.java
new file mode 100644
index 0000000..0621e68
--- /dev/null
+++ b/rt/frontend/simple/src/main/java/org/apache/cxf/endpoint/dynamic/ExceptionClassGenerator.java
@@ -0,0 +1,95 @@
+/**
+ * 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.cxf.endpoint.dynamic;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.common.spi.ClassGeneratorClassLoader;
+import org.apache.cxf.common.util.ASMHelper;
+import org.apache.cxf.common.util.OpcodesProxy;
+import org.apache.cxf.common.util.StringUtils;
+
+public class ExceptionClassGenerator extends ClassGeneratorClassLoader implements ExceptionClassCreator {
+    private final ASMHelper helper;
+
+    public ExceptionClassGenerator(Bus bus) {
+        super(bus);
+        this.helper = bus.getExtension(ASMHelper.class);
+    }
+    @Override
+    public Class<?> createExceptionClass(Class<?> bean) {
+        String newClassName = bean.getName() + "_Exception";
+        newClassName = newClassName.replaceAll("\\$", ".");
+        newClassName = StringUtils.periodToSlashes(newClassName);
+
+        Class<?> cls = findClass(StringUtils.slashesToPeriod(newClassName), bean);
+        if (cls == null) {
+            ASMHelper.ClassWriter cw = helper.createClassWriter();
+            OpcodesProxy opCodes = helper.getOpCodes();
+
+            cw.visit(opCodes.V1_5,
+                    opCodes.ACC_PUBLIC | opCodes.ACC_SUPER,
+                    newClassName,
+                    null,
+                    "java/lang/Exception",
+                    null);
+
+            ASMHelper.FieldVisitor fv;
+            ASMHelper.MethodVisitor mv;
+
+            String beanClassCode = helper.getClassCode(bean);
+            fv = cw.visitField(0, "faultInfo", beanClassCode, null, null);
+            fv.visitEnd();
+
+
+            mv = cw.visitMethod(opCodes.ACC_PUBLIC, "<init>",
+                    "(Ljava/lang/String;" + beanClassCode + ")V", null, null);
+            mv.visitCode();
+            mv.visitLabel(helper.createLabel());
+            mv.visitVarInsn(opCodes.ALOAD, 0);
+            mv.visitVarInsn(opCodes.ALOAD, 1);
+            mv.visitMethodInsn(opCodes.INVOKESPECIAL, "java/lang/Exception",
+                    "<init>", "(Ljava/lang/String;)V", false);
+            mv.visitLabel(helper.createLabel());
+            mv.visitVarInsn(opCodes.ALOAD, 0);
+            mv.visitVarInsn(opCodes.ALOAD, 2);
+            mv.visitFieldInsn(opCodes.PUTFIELD, newClassName, "faultInfo", beanClassCode);
+            mv.visitLabel(helper.createLabel());
+            mv.visitInsn(opCodes.RETURN);
+            mv.visitLabel(helper.createLabel());
+            mv.visitMaxs(0, 0);
+            mv.visitEnd();
+
+            mv = cw.visitMethod(opCodes.ACC_PUBLIC, "getFaultInfo",
+                    "()" + beanClassCode, null, null);
+            mv.visitCode();
+            mv.visitLabel(helper.createLabel());
+            mv.visitVarInsn(opCodes.ALOAD, 0);
+            mv.visitFieldInsn(opCodes.GETFIELD, newClassName, "faultInfo", beanClassCode);
+            mv.visitInsn(opCodes.ARETURN);
+            mv.visitLabel(helper.createLabel());
+            mv.visitMaxs(0, 0);
+            mv.visitEnd();
+
+            cw.visitEnd();
+
+            return loadClass(bean.getName() + "_Exception", bean, cw.toByteArray());
+        }
+        return cls;
+    }
+}
diff --git a/rt/frontend/simple/src/main/java/org/apache/cxf/endpoint/dynamic/ExceptionClassLoader.java b/rt/frontend/simple/src/main/java/org/apache/cxf/endpoint/dynamic/ExceptionClassLoader.java
new file mode 100644
index 0000000..de05276
--- /dev/null
+++ b/rt/frontend/simple/src/main/java/org/apache/cxf/endpoint/dynamic/ExceptionClassLoader.java
@@ -0,0 +1,42 @@
+/**
+ * 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.cxf.endpoint.dynamic;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.common.spi.GeneratedClassClassLoader;
+
+/** If class has been generated during build time
+ *  (use @see org.apache.cxf.common.spi.GeneratedClassClassLoaderCapture capture to save bytes)
+ *  you can set class loader to avoid class generation during runtime:
+ *  bus.setExtension(new ExceptionClassLoader(bus), ExceptionClassCreator.class);
+ * @author olivier dufour
+ */
+public class ExceptionClassLoader extends GeneratedClassClassLoader implements ExceptionClassCreator {
+
+    public ExceptionClassLoader(Bus bus) {
+        super(bus);
+    }
+
+    @Override
+    public Class<?> createExceptionClass(Class<?> bean) {
+        String newClassName = bean.getName() + "_Exception";
+        return findClass(newClassName, bean);
+
+    }
+}
diff --git a/rt/frontend/simple/src/main/java/org/apache/cxf/endpoint/dynamic/TypeClassInitializer.java b/rt/frontend/simple/src/main/java/org/apache/cxf/endpoint/dynamic/TypeClassInitializer.java
index 67a5d9a..3ba3cf7 100644
--- a/rt/frontend/simple/src/main/java/org/apache/cxf/endpoint/dynamic/TypeClassInitializer.java
+++ b/rt/frontend/simple/src/main/java/org/apache/cxf/endpoint/dynamic/TypeClassInitializer.java
@@ -24,6 +24,7 @@ import java.util.logging.Logger;
 
 import javax.xml.namespace.QName;
 
+import org.apache.cxf.Bus;
 import org.apache.cxf.common.classloader.ClassLoaderUtils;
 import org.apache.cxf.common.i18n.Message;
 import org.apache.cxf.common.jaxb.JAXBUtils.JType;
@@ -31,7 +32,6 @@ import org.apache.cxf.common.jaxb.JAXBUtils.Mapping;
 import org.apache.cxf.common.jaxb.JAXBUtils.S2JJAXBModel;
 import org.apache.cxf.common.jaxb.JAXBUtils.TypeAndAnnotation;
 import org.apache.cxf.common.logging.LogUtils;
-import org.apache.cxf.common.util.ASMHelper;
 import org.apache.cxf.common.util.PrimitiveUtils;
 import org.apache.cxf.service.ServiceModelVisitor;
 import org.apache.cxf.service.factory.ServiceConstructionException;
@@ -48,13 +48,15 @@ public class TypeClassInitializer extends ServiceModelVisitor {
     S2JJAXBModel model;
     boolean allowWrapperOperations;
     boolean isFault;
+    Bus bus;
 
-    public TypeClassInitializer(ServiceInfo serviceInfo,
+    public TypeClassInitializer(Bus bus, ServiceInfo serviceInfo,
                                 S2JJAXBModel model,
                                 boolean allowWr) {
         super(serviceInfo);
         this.model = model;
         this.allowWrapperOperations = allowWr;
+        this.bus = bus;
     }
 
     @Override
@@ -162,7 +164,8 @@ public class TypeClassInitializer extends ServiceModelVisitor {
     }
 
     private Class<?> createFaultClass(Class<?> cls) {
-        return new ExceptionCreator().createExceptionClass(cls);
+        ExceptionClassCreator exceptionClassCreator = bus.getExtension(ExceptionClassCreator.class);
+        return exceptionClassCreator.createExceptionClass(cls);
     }
 
     private Class<?> getClassByName(JType jType) throws ClassNotFoundException {
@@ -182,65 +185,4 @@ public class TypeClassInitializer extends ServiceModelVisitor {
         isFault = false;
     }
 
-
-    private static class ExceptionCreator extends ASMHelper {
-        public Class<?> createExceptionClass(Class<?> bean) {
-            String newClassName = bean.getName() + "_Exception";
-            newClassName = newClassName.replaceAll("\\$", ".");
-            newClassName = periodToSlashes(newClassName);
-
-            Class<?> cls = super.findClass(newClassName.replace('/', '.'), bean);
-            if (cls == null) {
-                ClassWriter cw = createClassWriter();
-                cw.visit(Opcodes.V1_5,
-                         Opcodes.ACC_PUBLIC | Opcodes.ACC_SUPER,
-                         newClassName,
-                         null,
-                         "java/lang/Exception",
-                         null);
-
-                FieldVisitor fv;
-                MethodVisitor mv;
-
-                String beanClassCode = getClassCode(bean);
-                fv = cw.visitField(0, "faultInfo", beanClassCode, null, null);
-                fv.visitEnd();
-
-
-                mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>",
-                                    "(Ljava/lang/String;" + beanClassCode + ")V", null, null);
-                mv.visitCode();
-                mv.visitLabel(createLabel());
-                mv.visitVarInsn(Opcodes.ALOAD, 0);
-                mv.visitVarInsn(Opcodes.ALOAD, 1);
-                mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Exception",
-                                   "<init>", "(Ljava/lang/String;)V", false);
-                mv.visitLabel(createLabel());
-                mv.visitVarInsn(Opcodes.ALOAD, 0);
-                mv.visitVarInsn(Opcodes.ALOAD, 2);
-                mv.visitFieldInsn(Opcodes.PUTFIELD, newClassName, "faultInfo", beanClassCode);
-                mv.visitLabel(createLabel());
-                mv.visitInsn(Opcodes.RETURN);
-                mv.visitLabel(createLabel());
-                mv.visitMaxs(2, 3);
-                mv.visitEnd();
-
-                mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "getFaultInfo",
-                                    "()" + beanClassCode, null, null);
-                mv.visitCode();
-                mv.visitLabel(createLabel());
-                mv.visitVarInsn(Opcodes.ALOAD, 0);
-                mv.visitFieldInsn(Opcodes.GETFIELD, newClassName, "faultInfo", beanClassCode);
-                mv.visitInsn(Opcodes.ARETURN);
-                mv.visitLabel(createLabel());
-                mv.visitMaxs(1, 1);
-                mv.visitEnd();
-
-                cw.visitEnd();
-
-                return super.loadClass(bean.getName() + "_Exception", bean, cw.toByteArray());
-            }
-            return cls;
-        }
-    }
 }
diff --git a/rt/frontend/simple/src/main/resources/META-INF/cxf/bus-extensions.txt b/rt/frontend/simple/src/main/resources/META-INF/cxf/bus-extensions.txt
new file mode 100644
index 0000000..746ec08
--- /dev/null
+++ b/rt/frontend/simple/src/main/resources/META-INF/cxf/bus-extensions.txt
@@ -0,0 +1 @@
+org.apache.cxf.endpoint.dynamic.ExceptionClassCreatorProxyService:org.apache.cxf.endpoint.dynamic.ExceptionClassCreator:true
\ No newline at end of file
diff --git a/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HTTPWSDLExtensionLoader.java b/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HTTPWSDLExtensionLoader.java
index b2078b5..73dcfea 100644
--- a/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HTTPWSDLExtensionLoader.java
+++ b/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HTTPWSDLExtensionLoader.java
@@ -37,18 +37,18 @@ public final class HTTPWSDLExtensionLoader implements WSDLExtensionLoader {
     public HTTPWSDLExtensionLoader(Bus b) {
         WSDLManager manager = b.getExtension(WSDLManager.class);
 
-        createExtensor(manager, javax.wsdl.Port.class,
+        createExtensor(b, manager, javax.wsdl.Port.class,
                        org.apache.cxf.transports.http.configuration.HTTPClientPolicy.class);
-        createExtensor(manager, javax.wsdl.Port.class,
+        createExtensor(b, manager, javax.wsdl.Port.class,
                        org.apache.cxf.transports.http.configuration.HTTPServerPolicy.class);
-        createExtensor(manager, javax.wsdl.Port.class,
+        createExtensor(b, manager, javax.wsdl.Port.class,
                        AddressType.class);
     }
-    public void createExtensor(WSDLManager manager,
+    public void createExtensor(Bus b, WSDLManager manager,
                                 Class<?> parentType,
                                 Class<?> elementType) {
         try {
-            JAXBExtensionHelper.addExtensions(manager.getExtensionRegistry(),
+            JAXBExtensionHelper.addExtensions(b, manager.getExtensionRegistry(),
                                               parentType,
                                               elementType, null,
                                               this.getClass().getClassLoader());
diff --git a/rt/transports/jms/src/main/java/org/apache/cxf/transport/jms/wsdl11/JMSWSDLExtensionLoader.java b/rt/transports/jms/src/main/java/org/apache/cxf/transport/jms/wsdl11/JMSWSDLExtensionLoader.java
index 2b1c7a7..13dfa3c 100644
--- a/rt/transports/jms/src/main/java/org/apache/cxf/transport/jms/wsdl11/JMSWSDLExtensionLoader.java
+++ b/rt/transports/jms/src/main/java/org/apache/cxf/transport/jms/wsdl11/JMSWSDLExtensionLoader.java
@@ -52,8 +52,10 @@ public final class JMSWSDLExtensionLoader implements WSDLExtensionLoader {
         TimeToLiveType.class,
         TopicReplyToNameType.class
     };
+    private final Bus bus;
 
     public JMSWSDLExtensionLoader(Bus b) {
+        this.bus = b;
         WSDLManager manager = b.getExtension(WSDLManager.class);
         for (Class<?> extensor : EXTENSORS) {
             addExtensions(manager, javax.wsdl.Binding.class, extensor);
@@ -64,7 +66,7 @@ public final class JMSWSDLExtensionLoader implements WSDLExtensionLoader {
 
     public void addExtensions(WSDLManager manager, Class<?> parentType, Class<?> elementType) {
         try {
-            JAXBExtensionHelper.addExtensions(manager.getExtensionRegistry(), parentType, elementType, null,
+            JAXBExtensionHelper.addExtensions(bus, manager.getExtensionRegistry(), parentType, elementType, null,
                                               this.getClass().getClassLoader());
         } catch (JAXBException e) {
             // ignore, won't support XML
diff --git a/rt/ws/addr/src/main/java/org/apache/cxf/ws/addressing/impl/AddressingWSDLExtensionLoader.java b/rt/ws/addr/src/main/java/org/apache/cxf/ws/addressing/impl/AddressingWSDLExtensionLoader.java
index 100abf8..037b0a1 100644
--- a/rt/ws/addr/src/main/java/org/apache/cxf/ws/addressing/impl/AddressingWSDLExtensionLoader.java
+++ b/rt/ws/addr/src/main/java/org/apache/cxf/ws/addressing/impl/AddressingWSDLExtensionLoader.java
@@ -33,7 +33,10 @@ import org.apache.cxf.wsdl.WSDLManager;
 @NoJSR250Annotations
 public final class AddressingWSDLExtensionLoader implements WSDLExtensionLoader {
 
+    private final Bus bus;
+
     public AddressingWSDLExtensionLoader(Bus b) {
+        this.bus = b;
         WSDLManager manager = b.getExtension(WSDLManager.class);
 
         createExtensor(manager, javax.wsdl.Binding.class,
@@ -43,7 +46,7 @@ public final class AddressingWSDLExtensionLoader implements WSDLExtensionLoader
                                 Class<?> parentType,
                                 Class<?> elementType) {
         try {
-            JAXBExtensionHelper.addExtensions(manager.getExtensionRegistry(),
+            JAXBExtensionHelper.addExtensions(bus, manager.getExtensionRegistry(),
                                               parentType,
                                               elementType, null,
                                               this.getClass().getClassLoader());
diff --git a/rt/wsdl/src/main/java/org/apache/cxf/wsdl/ExtensionClassCreator.java b/rt/wsdl/src/main/java/org/apache/cxf/wsdl/ExtensionClassCreator.java
new file mode 100644
index 0000000..b58474a
--- /dev/null
+++ b/rt/wsdl/src/main/java/org/apache/cxf/wsdl/ExtensionClassCreator.java
@@ -0,0 +1,25 @@
+/**
+ * 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.cxf.wsdl;
+
+import javax.xml.namespace.QName;
+
+public interface ExtensionClassCreator {
+    Class<?> createExtensionClass(Class<?> cls, QName qname, ClassLoader loader);
+}
diff --git a/rt/wsdl/src/main/java/org/apache/cxf/wsdl/ExtensionClassCreatorProxyService.java b/rt/wsdl/src/main/java/org/apache/cxf/wsdl/ExtensionClassCreatorProxyService.java
new file mode 100644
index 0000000..03cf42d
--- /dev/null
+++ b/rt/wsdl/src/main/java/org/apache/cxf/wsdl/ExtensionClassCreatorProxyService.java
@@ -0,0 +1,50 @@
+/**
+ * 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.cxf.wsdl;
+
+import javax.xml.namespace.QName;
+
+import org.apache.cxf.Bus;
+
+public class ExtensionClassCreatorProxyService implements ExtensionClassCreator {
+    private final ExtensionClassCreator srv;
+    public ExtensionClassCreatorProxyService(Bus bus) {
+        this(new ExtensionClassGenerator(bus));
+    }
+    public ExtensionClassCreatorProxyService(ExtensionClassCreator srv) {
+        super();
+        this.srv = srv;
+    }
+
+    @Override
+    public Class<?> createExtensionClass(Class<?> cls, QName qname, ClassLoader loader) {
+        return srv.createExtensionClass(cls, qname, loader);
+    }
+
+    public class LoadFirst extends ExtensionClassCreatorProxyService {
+        public LoadFirst(Bus bus) {
+            super(new ExtensionClassLoader(bus));
+        }
+    }
+    public class GenerateJustInTime extends ExtensionClassCreatorProxyService {
+        public GenerateJustInTime(Bus bus) {
+            super(new ExtensionClassGenerator(bus));
+        }
+    }
+}
diff --git a/rt/wsdl/src/main/java/org/apache/cxf/wsdl/ExtensionClassGenerator.java b/rt/wsdl/src/main/java/org/apache/cxf/wsdl/ExtensionClassGenerator.java
new file mode 100644
index 0000000..5596762
--- /dev/null
+++ b/rt/wsdl/src/main/java/org/apache/cxf/wsdl/ExtensionClassGenerator.java
@@ -0,0 +1,294 @@
+/**
+ * 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.cxf.wsdl;
+
+import java.lang.reflect.Method;
+import java.util.Map;
+
+import javax.xml.namespace.QName;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.common.spi.ClassGeneratorClassLoader;
+import org.apache.cxf.common.util.ASMHelper;
+import org.apache.cxf.common.util.OpcodesProxy;
+import org.apache.cxf.common.util.StringUtils;
+
+public class ExtensionClassGenerator extends ClassGeneratorClassLoader implements ExtensionClassCreator {
+
+    public ExtensionClassGenerator(Bus bus) {
+        super(bus);
+    }
+    //CHECKSTYLE:OFF - very complicated ASM code
+    public Class<?> createExtensionClass(Class<?> cls, QName qname, ClassLoader loader) {
+
+        String className = StringUtils.periodToSlashes(cls.getName());
+        ASMHelper helper = bus.getExtension(ASMHelper.class);
+        OpcodesProxy Opcodes = helper.getOpCodes();
+
+        Class<?> extClass = findClass(className + "Extensibility", loader);
+        if (extClass != null) {
+            return extClass;
+        }
+
+        ASMHelper.ClassWriter cw = helper.createClassWriter();
+        ASMHelper.FieldVisitor fv;
+        ASMHelper.MethodVisitor mv;
+        ASMHelper.AnnotationVisitor av0;
+
+        cw.visit(Opcodes.V1_6, Opcodes.ACC_PUBLIC + Opcodes.ACC_SUPER + Opcodes.ACC_SYNTHETIC,
+                className + "Extensibility", null,
+                className,
+                new String[] {"javax/wsdl/extensions/ExtensibilityElement"});
+
+        cw.visitSource(cls.getSimpleName() + "Extensibility.java", null);
+
+        fv = cw.visitField(Opcodes.ACC_PRIVATE + Opcodes.ACC_FINAL + Opcodes.ACC_STATIC,
+                "WSDL_REQUIRED", "Ljavax/xml/namespace/QName;", null, null);
+        fv.visitEnd();
+        fv = cw.visitField(0, "qn", "Ljavax/xml/namespace/QName;", null, null);
+        fv.visitEnd();
+
+
+        boolean hasAttributes = false;
+        try {
+            Method m = cls.getDeclaredMethod("getOtherAttributes");
+            if (m != null && m.getReturnType() == Map.class){
+                hasAttributes = true;
+            }
+        } catch (Throwable t) {
+            //ignore
+        }
+        if (hasAttributes) {
+            mv = cw.visitMethod(Opcodes.ACC_STATIC, "<clinit>", "()V", null, null);
+            mv.visitCode();
+            ASMHelper.Label l0 = helper.createLabel();
+            mv.visitLabel(l0);
+            mv.visitLineNumber(64, l0);
+            mv.visitTypeInsn(Opcodes.NEW, "javax/xml/namespace/QName");
+            mv.visitInsn(Opcodes.DUP);
+            mv.visitLdcInsn("http://schemas.xmlsoap.org/wsdl/");
+            mv.visitLdcInsn("required");
+            mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "javax/xml/namespace/QName", "<init>",
+                    "(Ljava/lang/String;Ljava/lang/String;)V", false);
+            mv.visitFieldInsn(Opcodes.PUTSTATIC, className + "Extensibility", "WSDL_REQUIRED",
+                    "Ljavax/xml/namespace/QName;");
+            mv.visitInsn(Opcodes.RETURN);
+            mv.visitMaxs(0, 0);
+            mv.visitEnd();
+        } else {
+            fv = cw.visitField(Opcodes.ACC_PRIVATE, "required", "Ljava/lang/Boolean;", null, null);
+            fv.visitEnd();
+        }
+
+        mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
+        mv.visitCode();
+        ASMHelper.Label l0 = helper.createLabel();
+        mv.visitLabel(l0);
+        mv.visitLineNumber(33, l0);
+        mv.visitVarInsn(Opcodes.ALOAD, 0);
+        mv.visitMethodInsn(Opcodes.INVOKESPECIAL, className, "<init>", "()V", false);
+        ASMHelper.Label l1 = helper.createLabel();
+        mv.visitLabel(l1);
+        mv.visitLineNumber(31, l1);
+        mv.visitVarInsn(Opcodes.ALOAD, 0);
+        mv.visitTypeInsn(Opcodes.NEW, "javax/xml/namespace/QName");
+        mv.visitInsn(Opcodes.DUP);
+
+        mv.visitLdcInsn(qname.getNamespaceURI());
+        mv.visitLdcInsn(qname.getLocalPart());
+
+        mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "javax/xml/namespace/QName",
+                "<init>", "(Ljava/lang/String;Ljava/lang/String;)V", false);
+        mv.visitFieldInsn(Opcodes.PUTFIELD, className + "Extensibility",
+                "qn", "Ljavax/xml/namespace/QName;");
+        ASMHelper.Label l2 = helper.createLabel();
+        mv.visitLabel(l2);
+        mv.visitLineNumber(34, l2);
+        mv.visitInsn(Opcodes.RETURN);
+        ASMHelper.Label l3 = helper.createLabel();
+        mv.visitLabel(l3);
+
+        mv.visitLocalVariable("this", "L" + className + "Extensibility;", null, l0, l3, 0);
+        mv.visitMaxs(0, 0);
+        mv.visitEnd();
+
+        mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "setElementType", "(Ljavax/xml/namespace/QName;)V", null, null);
+        mv.visitCode();
+        l0 = helper.createLabel();
+        mv.visitLabel(l0);
+        mv.visitLineNumber(37, l0);
+        mv.visitVarInsn(Opcodes.ALOAD, 0);
+        mv.visitVarInsn(Opcodes.ALOAD, 1);
+        mv.visitFieldInsn(Opcodes.PUTFIELD, className + "Extensibility", "qn", "Ljavax/xml/namespace/QName;");
+        l1 = helper.createLabel();
+        mv.visitLabel(l1);
+        mv.visitLineNumber(38, l1);
+        mv.visitInsn(Opcodes.RETURN);
+        l2 = helper.createLabel();
+        mv.visitLabel(l2);
+        mv.visitLocalVariable("this", "L" + className + "Extensibility;", null, l0, l2, 0);
+        mv.visitLocalVariable("elementType", "Ljavax/xml/namespace/QName;", null, l0, l2, 1);
+        mv.visitMaxs(0, 0);
+        mv.visitEnd();
+
+        mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "getElementType", "()Ljavax/xml/namespace/QName;", null, null);
+        av0 = mv.visitAnnotation("Ljavax/xml/bind/annotation/XmlTransient;", true);
+        av0.visitEnd();
+        mv.visitCode();
+        l0 = helper.createLabel();
+        mv.visitLabel(l0);
+        mv.visitLineNumber(40, l0);
+        mv.visitVarInsn(Opcodes.ALOAD, 0);
+        mv.visitFieldInsn(Opcodes.GETFIELD, className + "Extensibility", "qn", "Ljavax/xml/namespace/QName;");
+        mv.visitInsn(Opcodes.ARETURN);
+        l1 = helper.createLabel();
+        mv.visitLabel(l1);
+        mv.visitLocalVariable("this", "L" + className + "Extensibility;", null, l0, l1, 0);
+        mv.visitMaxs(0, 0);
+        mv.visitEnd();
+
+        if (hasAttributes) {
+            mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "getRequired", "()Ljava/lang/Boolean;", null, null);
+            mv.visitCode();
+            l0 = helper.createLabel();
+            mv.visitLabel(l0);
+            mv.visitLineNumber(66, l0);
+            mv.visitVarInsn(Opcodes.ALOAD, 0);
+            mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, className + "Extensibility", "getOtherAttributes",
+                    "()Ljava/util/Map;", false);
+            mv.visitFieldInsn(Opcodes.GETSTATIC, className + "Extensibility", "WSDL_REQUIRED",
+                    "Ljavax/xml/namespace/QName;");
+            mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/Map", "get",
+                    "(Ljava/lang/Object;)Ljava/lang/Object;", true);
+            mv.visitTypeInsn(Opcodes.CHECKCAST, "java/lang/String");
+            mv.visitVarInsn(Opcodes.ASTORE, 1);
+            l1 = helper.createLabel();
+            mv.visitLabel(l1);
+            mv.visitLineNumber(67, l1);
+            mv.visitVarInsn(Opcodes.ALOAD, 1);
+            l2 = helper.createLabel();
+            mv.visitJumpInsn(Opcodes.IFNONNULL, l2);
+            mv.visitInsn(Opcodes.ACONST_NULL);
+            l3 = helper.createLabel();
+            mv.visitJumpInsn(Opcodes.GOTO, l3);
+            mv.visitLabel(l2);
+            mv.visitFrame(Opcodes.F_APPEND, 1, new Object[] {"java/lang/String"}, 0, null);
+            mv.visitVarInsn(Opcodes.ALOAD, 1);
+            mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Boolean", "valueOf",
+                    "(Ljava/lang/String;)Ljava/lang/Boolean;", false);
+            mv.visitLabel(l3);
+            mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {"java/lang/Boolean"});
+            mv.visitInsn(Opcodes.ARETURN);
+            ASMHelper.Label l4 = helper.createLabel();
+            mv.visitLabel(l4);
+            mv.visitLocalVariable("this", "L" + className + "Extensibility;", null, l0, l4, 0);
+            mv.visitLocalVariable("s", "Ljava/lang/String;", null, l1, l4, 1);
+            mv.visitMaxs(0, 0);
+            mv.visitEnd();
+
+
+
+            mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "setRequired", "(Ljava/lang/Boolean;)V", null, null);
+            mv.visitCode();
+            l0 = helper.createLabel();
+            mv.visitLabel(l0);
+            mv.visitLineNumber(76, l0);
+            mv.visitVarInsn(Opcodes.ALOAD, 1);
+            l1 = helper.createLabel();
+            mv.visitJumpInsn(Opcodes.IFNONNULL, l1);
+            l2 = helper.createLabel();
+            mv.visitLabel(l2);
+            mv.visitLineNumber(77, l2);
+            mv.visitVarInsn(Opcodes.ALOAD, 0);
+            mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, className + "Extensibility", "getOtherAttributes",
+                    "()Ljava/util/Map;", false);
+            mv.visitFieldInsn(Opcodes.GETSTATIC, className + "Extensibility", "WSDL_REQUIRED",
+                    "Ljavax/xml/namespace/QName;");
+            mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/Map", "remove",
+                    "(Ljava/lang/Object;)Ljava/lang/Object;", true);
+            mv.visitInsn(Opcodes.POP);
+            l3 = helper.createLabel();
+            mv.visitLabel(l3);
+            mv.visitLineNumber(78, l3);
+            l4 = helper.createLabel();
+            mv.visitJumpInsn(Opcodes.GOTO, l4);
+            mv.visitLabel(l1);
+            mv.visitLineNumber(79, l1);
+            mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
+            mv.visitVarInsn(Opcodes.ALOAD, 0);
+            mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, className + "Extensibility", "getOtherAttributes",
+                    "()Ljava/util/Map;", false);
+            mv.visitFieldInsn(Opcodes.GETSTATIC, className + "Extensibility", "WSDL_REQUIRED",
+                    "Ljavax/xml/namespace/QName;");
+            mv.visitVarInsn(Opcodes.ALOAD, 1);
+            mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Boolean", "toString", "()Ljava/lang/String;", false);
+            mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/Map", "put",
+                    "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", true);
+            mv.visitInsn(Opcodes.POP);
+            mv.visitLabel(l4);
+            mv.visitLineNumber(81, l4);
+            mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
+            mv.visitInsn(Opcodes.RETURN);
+            ASMHelper.Label l5 = helper.createLabel();
+            mv.visitLabel(l5);
+            mv.visitLocalVariable("this", "L" + className + "Extensibility;", null, l0, l5, 0);
+            mv.visitLocalVariable("b", "Ljava/lang/Boolean;", null, l0, l5, 1);
+            mv.visitMaxs(0, 0);
+            mv.visitEnd();
+        } else {
+            mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "getRequired", "()Ljava/lang/Boolean;", null, null);
+            mv.visitCode();
+            l0 = helper.createLabel();
+            mv.visitLabel(l0);
+            mv.visitLineNumber(68, l0);
+            mv.visitVarInsn(Opcodes.ALOAD, 0);
+            mv.visitFieldInsn(Opcodes.GETFIELD, className + "Extensibility", "required", "Ljava/lang/Boolean;");
+            mv.visitInsn(Opcodes.ARETURN);
+            l1 = helper.createLabel();
+            mv.visitLabel(l1);
+            mv.visitLocalVariable("this", "L" + className + "Extensibility;", null, l0, l1, 0);
+            mv.visitMaxs(0, 0);
+            mv.visitEnd();
+
+            mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "setRequired", "(Ljava/lang/Boolean;)V", null, null);
+            mv.visitCode();
+            l0 = helper.createLabel();
+            mv.visitLabel(l0);
+            mv.visitLineNumber(71, l0);
+            mv.visitVarInsn(Opcodes.ALOAD, 0);
+            mv.visitVarInsn(Opcodes.ALOAD, 1);
+            mv.visitFieldInsn(Opcodes.PUTFIELD, className + "Extensibility", "required", "Ljava/lang/Boolean;");
+            l1 = helper.createLabel();
+            mv.visitLabel(l1);
+            mv.visitLineNumber(72, l1);
+            mv.visitInsn(Opcodes.RETURN);
+            l2 = helper.createLabel();
+            mv.visitLabel(l2);
+            mv.visitLocalVariable("this", "L" + className + "Extensibility;", null, l0, l2, 0);
+            mv.visitLocalVariable("b", "Ljava/lang/Boolean;", null, l0, l2, 1);
+            mv.visitMaxs(0, 0);
+            mv.visitEnd();
+        }
+
+        cw.visitEnd();
+
+        byte[] bytes = cw.toByteArray();
+        return loadClass(className + "Extensibility", loader, bytes);
+    }
+}
diff --git a/rt/wsdl/src/main/java/org/apache/cxf/wsdl/ExtensionClassLoader.java b/rt/wsdl/src/main/java/org/apache/cxf/wsdl/ExtensionClassLoader.java
new file mode 100644
index 0000000..5d16380
--- /dev/null
+++ b/rt/wsdl/src/main/java/org/apache/cxf/wsdl/ExtensionClassLoader.java
@@ -0,0 +1,43 @@
+/**
+ * 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.cxf.wsdl;
+
+import javax.xml.namespace.QName;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.common.spi.GeneratedClassClassLoader;
+
+/** If class has been generated during build time
+ *  (use @see org.apache.cxf.common.spi.GeneratedClassClassLoaderCapture capture to save bytes)
+ *  you can set class loader to avoid class generation during runtime:
+ *  bus.setExtension(new ExtensionClassLoader(bus), ExtensionClassCreator.class);
+ * @author olivier dufour
+ */
+public class ExtensionClassLoader extends GeneratedClassClassLoader implements ExtensionClassCreator {
+
+    public ExtensionClassLoader(Bus bus) {
+        super(bus);
+    }
+
+    @Override
+    public Class<?> createExtensionClass(Class<?> cls, QName qname, ClassLoader loader) {
+        return findClass(cls.getName() + "Extensibility", ExtensionClassLoader.class);
+    }
+}
diff --git a/rt/wsdl/src/main/java/org/apache/cxf/wsdl/JAXBExtensionHelper.java b/rt/wsdl/src/main/java/org/apache/cxf/wsdl/JAXBExtensionHelper.java
index c31d336..c8b6478 100644
--- a/rt/wsdl/src/main/java/org/apache/cxf/wsdl/JAXBExtensionHelper.java
+++ b/rt/wsdl/src/main/java/org/apache/cxf/wsdl/JAXBExtensionHelper.java
@@ -63,18 +63,12 @@ import javax.xml.stream.util.StreamReaderDelegate;
 
 import org.w3c.dom.Element;
 
+import org.apache.cxf.Bus;
 import org.apache.cxf.common.classloader.ClassLoaderUtils;
 import org.apache.cxf.common.jaxb.JAXBContextCache;
 import org.apache.cxf.common.jaxb.JAXBContextCache.CachedContextAndSchemas;
 import org.apache.cxf.common.jaxb.JAXBUtils;
 import org.apache.cxf.common.logging.LogUtils;
-import org.apache.cxf.common.util.ASMHelper;
-import org.apache.cxf.common.util.ASMHelper.AnnotationVisitor;
-import org.apache.cxf.common.util.ASMHelper.ClassWriter;
-import org.apache.cxf.common.util.ASMHelper.FieldVisitor;
-import org.apache.cxf.common.util.ASMHelper.Label;
-import org.apache.cxf.common.util.ASMHelper.MethodVisitor;
-import org.apache.cxf.common.util.ASMHelper.Opcodes;
 import org.apache.cxf.common.util.PackageUtils;
 import org.apache.cxf.common.util.ReflectionUtil;
 import org.apache.cxf.common.util.StringUtils;
@@ -82,7 +76,6 @@ import org.apache.cxf.staxutils.PrettyPrintXMLStreamWriter;
 import org.apache.cxf.staxutils.StaxUtils;
 import org.apache.cxf.staxutils.transform.OutTransformWriter;
 
-
 /**
  * JAXBExtensionHelper
  */
@@ -99,13 +92,15 @@ public class JAXBExtensionHelper implements ExtensionSerializer, ExtensionDeseri
     private JAXBContext marshalContext;
     private JAXBContext unmarshalContext;
     private Set<Class<?>> classes;
+    private Bus bus;
 
 
-    public JAXBExtensionHelper(Class<?> cls,
+    public JAXBExtensionHelper(Bus bus, Class<?> cls,
                                String ns) {
         typeClass = cls;
         namespace = ns;
         extensionClass = cls;
+        this.bus = bus;
     }
 
     void setJaxbNamespace(String ns) {
@@ -138,16 +133,16 @@ public class JAXBExtensionHelper implements ExtensionSerializer, ExtensionDeseri
     }
 
 
-    public static void addExtensions(ExtensionRegistry registry, String parentType, String elementType)
+    public static void addExtensions(Bus b, ExtensionRegistry registry, String parentType, String elementType)
         throws JAXBException, ClassNotFoundException {
         Class<?> parentTypeClass = ClassLoaderUtils.loadClass(parentType, JAXBExtensionHelper.class);
 
         Class<? extends ExtensibilityElement> elementTypeClass =
             ClassLoaderUtils.loadClass(elementType, JAXBExtensionHelper.class)
                 .asSubclass(ExtensibilityElement.class);
-        addExtensions(registry, parentTypeClass, elementTypeClass, null);
+        addExtensions(b, registry, parentTypeClass, elementTypeClass, null);
     }
-    public static void addExtensions(ExtensionRegistry registry,
+    public static void addExtensions(Bus b, ExtensionRegistry registry,
                                      String parentType,
                                      String elementType,
                                      String namespace)
@@ -157,27 +152,28 @@ public class JAXBExtensionHelper implements ExtensionSerializer, ExtensionDeseri
         Class<? extends ExtensibilityElement> elementTypeClass =
             ClassLoaderUtils.loadClass(elementType, JAXBExtensionHelper.class)
                 .asSubclass(ExtensibilityElement.class);
-        addExtensions(registry, parentTypeClass, elementTypeClass, namespace);
+        addExtensions(b, registry, parentTypeClass, elementTypeClass, namespace);
     }
-    public static void addExtensions(ExtensionRegistry registry,
+    public static void addExtensions(Bus b, ExtensionRegistry registry,
                                      Class<?> parentType,
                                      Class<?> cls)
         throws JAXBException {
-        addExtensions(registry, parentType, cls, null);
+        addExtensions(b, registry, parentType, cls, null);
     }
-    public static void addExtensions(ExtensionRegistry registry,
+    public static void addExtensions(Bus b, ExtensionRegistry registry,
                                      Class<?> parentType,
                                      Class<?> cls,
                                      String namespace) throws JAXBException {
-        addExtensions(registry, parentType, cls, namespace, cls.getClassLoader());
+        addExtensions(b, registry, parentType, cls, namespace, cls.getClassLoader());
     }
-    public static void addExtensions(ExtensionRegistry registry,
+    public static void addExtensions(Bus b, ExtensionRegistry registry,
                                      Class<?> parentType,
                                      Class<?> cls,
                                      String namespace,
                                      ClassLoader loader) throws JAXBException {
 
-        JAXBExtensionHelper helper = new JAXBExtensionHelper(cls, namespace);
+        JAXBExtensionHelper helper = new JAXBExtensionHelper(b, cls, namespace);
+        ExtensionClassCreator extensionClassCreator = b.getExtension(ExtensionClassCreator.class);
         boolean found = false;
         Class<?> extCls = cls;
         try {
@@ -197,7 +193,7 @@ public class JAXBExtensionHelper implements ExtensionSerializer, ExtensionDeseri
                         }
                         QName elementType = new QName(ns, name);
                         if (!ExtensibilityElement.class.isAssignableFrom(extCls)) {
-                            extCls = createExtensionClass(cls, elementType, loader);
+                            extCls = extensionClassCreator.createExtensionClass(cls, elementType, loader);
                             helper.setExtensionClass(extCls);
                         }
                         registry.registerDeserializer(parentType, elementType, helper);
@@ -234,7 +230,7 @@ public class JAXBExtensionHelper implements ExtensionSerializer, ExtensionDeseri
                     }
                     QName elementType = new QName(ns, name);
                     if (!ExtensibilityElement.class.isAssignableFrom(extCls)) {
-                        extCls = createExtensionClass(cls, elementType, loader);
+                        extCls = extensionClassCreator.createExtensionClass(cls, elementType, loader);
                         helper.setExtensionClass(extCls);
                     }
                     registry.registerDeserializer(parentType, elementType, helper);
@@ -326,7 +322,7 @@ public class JAXBExtensionHelper implements ExtensionSerializer, ExtensionDeseri
                 Map.Entry<?, ?> entry = (Map.Entry<?, ?>)ent;
                 nspref.put((String)entry.getValue(), (String)entry.getKey());
             }
-            JAXBUtils.setNamespaceMapper(nspref, u);
+            JAXBUtils.setNamespaceMapper(bus, nspref, u);
             u.marshal(mObj, writer);
             writer.flush();
         } catch (Exception ex) {
@@ -453,260 +449,5 @@ public class JAXBExtensionHelper implements ExtensionSerializer, ExtensionDeseri
 
     };
 
-    //CHECKSTYLE:OFF - very complicated ASM code
-    private static Class<?> createExtensionClass(Class<?> cls, QName qname, ClassLoader loader) {
-
-        String className = ASMHelper.periodToSlashes(cls.getName());
-        ASMHelper helper = new ASMHelper();
-        Class<?> extClass = helper.findClass(className + "Extensibility", loader);
-        if (extClass != null) {
-            return extClass;
-        }
-
-        ClassWriter cw = helper.createClassWriter();
-        FieldVisitor fv;
-        MethodVisitor mv;
-        AnnotationVisitor av0;
-
-        cw.visit(Opcodes.V1_6, Opcodes.ACC_PUBLIC + Opcodes.ACC_SUPER + Opcodes.ACC_SYNTHETIC,
-                 className + "Extensibility", null,
-                 className,
-                 new String[] {"javax/wsdl/extensions/ExtensibilityElement"});
-
-        cw.visitSource(cls.getSimpleName() + "Extensibility.java", null);
-
-        fv = cw.visitField(Opcodes.ACC_PRIVATE + Opcodes.ACC_FINAL + Opcodes.ACC_STATIC,
-                           "WSDL_REQUIRED", "Ljavax/xml/namespace/QName;", null, null);
-        fv.visitEnd();
-        fv = cw.visitField(0, "qn", "Ljavax/xml/namespace/QName;", null, null);
-        fv.visitEnd();
-
-
-        boolean hasAttributes = false;
-        try {
-            Method m = cls.getDeclaredMethod("getOtherAttributes");
-            if (m != null && m.getReturnType() == Map.class){
-                hasAttributes = true;
-            }
-        } catch (Throwable t) {
-            //ignore
-        }
-        if (hasAttributes) {
-            mv = cw.visitMethod(Opcodes.ACC_STATIC, "<clinit>", "()V", null, null);
-            mv.visitCode();
-            Label l0 = helper.createLabel();
-            mv.visitLabel(l0);
-            mv.visitLineNumber(64, l0);
-            mv.visitTypeInsn(Opcodes.NEW, "javax/xml/namespace/QName");
-            mv.visitInsn(Opcodes.DUP);
-            mv.visitLdcInsn("http://schemas.xmlsoap.org/wsdl/");
-            mv.visitLdcInsn("required");
-            mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "javax/xml/namespace/QName", "<init>",
-                  "(Ljava/lang/String;Ljava/lang/String;)V", false);
-            mv.visitFieldInsn(Opcodes.PUTSTATIC, className + "Extensibility", "WSDL_REQUIRED",
-                  "Ljavax/xml/namespace/QName;");
-            mv.visitInsn(Opcodes.RETURN);
-            mv.visitMaxs(4, 0);
-            mv.visitEnd();
-        } else {
-            fv = cw.visitField(Opcodes.ACC_PRIVATE, "required", "Ljava/lang/Boolean;", null, null);
-            fv.visitEnd();
-        }
-
-        mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
-        mv.visitCode();
-        Label l0 = helper.createLabel();
-        mv.visitLabel(l0);
-        mv.visitLineNumber(33, l0);
-        mv.visitVarInsn(Opcodes.ALOAD, 0);
-        mv.visitMethodInsn(Opcodes.INVOKESPECIAL, className, "<init>", "()V", false);
-        Label l1 = helper.createLabel();
-        mv.visitLabel(l1);
-        mv.visitLineNumber(31, l1);
-        mv.visitVarInsn(Opcodes.ALOAD, 0);
-        mv.visitTypeInsn(Opcodes.NEW, "javax/xml/namespace/QName");
-        mv.visitInsn(Opcodes.DUP);
-
-        mv.visitLdcInsn(qname.getNamespaceURI());
-        mv.visitLdcInsn(qname.getLocalPart());
-
-        mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "javax/xml/namespace/QName",
-                           "<init>", "(Ljava/lang/String;Ljava/lang/String;)V", false);
-        mv.visitFieldInsn(Opcodes.PUTFIELD, className + "Extensibility",
-                          "qn", "Ljavax/xml/namespace/QName;");
-        Label l2 = helper.createLabel();
-        mv.visitLabel(l2);
-        mv.visitLineNumber(34, l2);
-        mv.visitInsn(Opcodes.RETURN);
-        Label l3 = helper.createLabel();
-        mv.visitLabel(l3);
-
-        mv.visitLocalVariable("this", "L" + className + "Extensibility;", null, l0, l3, 0);
-        mv.visitMaxs(5, 1);
-        mv.visitEnd();
-
-        mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "setElementType", "(Ljavax/xml/namespace/QName;)V", null, null);
-        mv.visitCode();
-        l0 = helper.createLabel();
-        mv.visitLabel(l0);
-        mv.visitLineNumber(37, l0);
-        mv.visitVarInsn(Opcodes.ALOAD, 0);
-        mv.visitVarInsn(Opcodes.ALOAD, 1);
-        mv.visitFieldInsn(Opcodes.PUTFIELD, className + "Extensibility", "qn", "Ljavax/xml/namespace/QName;");
-        l1 = helper.createLabel();
-        mv.visitLabel(l1);
-        mv.visitLineNumber(38, l1);
-        mv.visitInsn(Opcodes.RETURN);
-        l2 = helper.createLabel();
-        mv.visitLabel(l2);
-        mv.visitLocalVariable("this", "L" + className + "Extensibility;", null, l0, l2, 0);
-        mv.visitLocalVariable("elementType", "Ljavax/xml/namespace/QName;", null, l0, l2, 1);
-        mv.visitMaxs(2, 2);
-        mv.visitEnd();
-
-        mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "getElementType", "()Ljavax/xml/namespace/QName;", null, null);
-        av0 = mv.visitAnnotation("Ljavax/xml/bind/annotation/XmlTransient;", true);
-        av0.visitEnd();
-        mv.visitCode();
-        l0 = helper.createLabel();
-        mv.visitLabel(l0);
-        mv.visitLineNumber(40, l0);
-        mv.visitVarInsn(Opcodes.ALOAD, 0);
-        mv.visitFieldInsn(Opcodes.GETFIELD, className + "Extensibility", "qn", "Ljavax/xml/namespace/QName;");
-        mv.visitInsn(Opcodes.ARETURN);
-        l1 = helper.createLabel();
-        mv.visitLabel(l1);
-        mv.visitLocalVariable("this", "L" + className + "Extensibility;", null, l0, l1, 0);
-        mv.visitMaxs(1, 1);
-        mv.visitEnd();
-
-        if (hasAttributes) {
-            mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "getRequired", "()Ljava/lang/Boolean;", null, null);
-            mv.visitCode();
-            l0 = helper.createLabel();
-            mv.visitLabel(l0);
-            mv.visitLineNumber(66, l0);
-            mv.visitVarInsn(Opcodes.ALOAD, 0);
-            mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, className + "Extensibility", "getOtherAttributes",
-                 "()Ljava/util/Map;", false);
-            mv.visitFieldInsn(Opcodes.GETSTATIC, className + "Extensibility", "WSDL_REQUIRED",
-                 "Ljavax/xml/namespace/QName;");
-            mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/Map", "get",
-                 "(Ljava/lang/Object;)Ljava/lang/Object;", true);
-            mv.visitTypeInsn(Opcodes.CHECKCAST, "java/lang/String");
-            mv.visitVarInsn(Opcodes.ASTORE, 1);
-            l1 = helper.createLabel();
-            mv.visitLabel(l1);
-            mv.visitLineNumber(67, l1);
-            mv.visitVarInsn(Opcodes.ALOAD, 1);
-            l2 = helper.createLabel();
-            mv.visitJumpInsn(Opcodes.IFNONNULL, l2);
-            mv.visitInsn(Opcodes.ACONST_NULL);
-            l3 = helper.createLabel();
-            mv.visitJumpInsn(Opcodes.GOTO, l3);
-            mv.visitLabel(l2);
-            mv.visitFrame(Opcodes.F_APPEND, 1, new Object[] {"java/lang/String"}, 0, null);
-            mv.visitVarInsn(Opcodes.ALOAD, 1);
-            mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Boolean", "valueOf",
-                 "(Ljava/lang/String;)Ljava/lang/Boolean;", false);
-            mv.visitLabel(l3);
-            mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {"java/lang/Boolean"});
-            mv.visitInsn(Opcodes.ARETURN);
-            Label l4 = helper.createLabel();
-            mv.visitLabel(l4);
-            mv.visitLocalVariable("this", "L" + className + "Extensibility;", null, l0, l4, 0);
-            mv.visitLocalVariable("s", "Ljava/lang/String;", null, l1, l4, 1);
-            mv.visitMaxs(2, 2);
-            mv.visitEnd();
-
-
-
-            mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "setRequired", "(Ljava/lang/Boolean;)V", null, null);
-            mv.visitCode();
-            l0 = helper.createLabel();
-            mv.visitLabel(l0);
-            mv.visitLineNumber(76, l0);
-            mv.visitVarInsn(Opcodes.ALOAD, 1);
-            l1 = helper.createLabel();
-            mv.visitJumpInsn(Opcodes.IFNONNULL, l1);
-            l2 = helper.createLabel();
-            mv.visitLabel(l2);
-            mv.visitLineNumber(77, l2);
-            mv.visitVarInsn(Opcodes.ALOAD, 0);
-            mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, className + "Extensibility", "getOtherAttributes",
-                 "()Ljava/util/Map;", false);
-            mv.visitFieldInsn(Opcodes.GETSTATIC, className + "Extensibility", "WSDL_REQUIRED",
-                 "Ljavax/xml/namespace/QName;");
-            mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/Map", "remove",
-                 "(Ljava/lang/Object;)Ljava/lang/Object;", true);
-            mv.visitInsn(Opcodes.POP);
-            l3 = helper.createLabel();
-            mv.visitLabel(l3);
-            mv.visitLineNumber(78, l3);
-            l4 = helper.createLabel();
-            mv.visitJumpInsn(Opcodes.GOTO, l4);
-            mv.visitLabel(l1);
-            mv.visitLineNumber(79, l1);
-            mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
-            mv.visitVarInsn(Opcodes.ALOAD, 0);
-            mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, className + "Extensibility", "getOtherAttributes", 
-                "()Ljava/util/Map;", false);
-            mv.visitFieldInsn(Opcodes.GETSTATIC, className + "Extensibility", "WSDL_REQUIRED",
-                 "Ljavax/xml/namespace/QName;");
-            mv.visitVarInsn(Opcodes.ALOAD, 1);
-            mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Boolean", "toString", "()Ljava/lang/String;", false);
-            mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/Map", "put",
-                 "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", true);
-            mv.visitInsn(Opcodes.POP);
-            mv.visitLabel(l4);
-            mv.visitLineNumber(81, l4);
-            mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
-            mv.visitInsn(Opcodes.RETURN);
-            Label l5 = helper.createLabel();
-            mv.visitLabel(l5);
-            mv.visitLocalVariable("this", "L" + className + "Extensibility;", null, l0, l5, 0);
-            mv.visitLocalVariable("b", "Ljava/lang/Boolean;", null, l0, l5, 1);
-            mv.visitMaxs(3, 2);
-            mv.visitEnd();
-        } else {
-            mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "getRequired", "()Ljava/lang/Boolean;", null, null);
-            mv.visitCode();
-            l0 = helper.createLabel();
-            mv.visitLabel(l0);
-            mv.visitLineNumber(68, l0);
-            mv.visitVarInsn(Opcodes.ALOAD, 0);
-            mv.visitFieldInsn(Opcodes.GETFIELD, className + "Extensibility", "required", "Ljava/lang/Boolean;");
-            mv.visitInsn(Opcodes.ARETURN);
-            l1 = helper.createLabel();
-            mv.visitLabel(l1);
-            mv.visitLocalVariable("this", "L" + className + "Extensibility;", null, l0, l1, 0);
-            mv.visitMaxs(1, 1);
-            mv.visitEnd();
-
-            mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "setRequired", "(Ljava/lang/Boolean;)V", null, null);
-            mv.visitCode();
-            l0 = helper.createLabel();
-            mv.visitLabel(l0);
-            mv.visitLineNumber(71, l0);
-            mv.visitVarInsn(Opcodes.ALOAD, 0);
-            mv.visitVarInsn(Opcodes.ALOAD, 1);
-            mv.visitFieldInsn(Opcodes.PUTFIELD, className + "Extensibility", "required", "Ljava/lang/Boolean;");
-            l1 = helper.createLabel();
-            mv.visitLabel(l1);
-            mv.visitLineNumber(72, l1);
-            mv.visitInsn(Opcodes.RETURN);
-            l2 = helper.createLabel();
-            mv.visitLabel(l2);
-            mv.visitLocalVariable("this", "L" + className + "Extensibility;", null, l0, l2, 0);
-            mv.visitLocalVariable("b", "Ljava/lang/Boolean;", null, l0, l2, 1);
-            mv.visitMaxs(2, 2);
-            mv.visitEnd();
-        }
-
-        cw.visitEnd();
-
-        byte[] bytes = cw.toByteArray();
-        return helper.loadClass(className + "Extensibility", loader, bytes);
-    }
 
 }
diff --git a/rt/wsdl/src/main/resources/META-INF/cxf/bus-extensions.txt b/rt/wsdl/src/main/resources/META-INF/cxf/bus-extensions.txt
index c69b655..3ce9b5b 100644
--- a/rt/wsdl/src/main/resources/META-INF/cxf/bus-extensions.txt
+++ b/rt/wsdl/src/main/resources/META-INF/cxf/bus-extensions.txt
@@ -1,2 +1,2 @@
 org.apache.cxf.wsdl11.WSDLManagerImpl:org.apache.cxf.wsdl.WSDLManager:true
-
+org.apache.cxf.wsdl.ExtensionClassCreatorProxyService:org.apache.cxf.wsdl.ExtensionClassCreator:true
diff --git a/rt/wsdl/src/test/java/org/apache/cxf/wsdl/JAXBExtensionHelperTest.java b/rt/wsdl/src/test/java/org/apache/cxf/wsdl/JAXBExtensionHelperTest.java
index fd569d0..f07d88a 100644
--- a/rt/wsdl/src/test/java/org/apache/cxf/wsdl/JAXBExtensionHelperTest.java
+++ b/rt/wsdl/src/test/java/org/apache/cxf/wsdl/JAXBExtensionHelperTest.java
@@ -37,9 +37,13 @@ import javax.xml.namespace.QName;
 
 import org.xml.sax.InputSource;
 
+import org.apache.cxf.Bus;
 import org.apache.cxf.abc.test.AnotherPolicyType;
 import org.apache.cxf.abc.test.NewServiceType;
 import org.apache.cxf.abc.test.TestPolicyType;
+import org.apache.cxf.bus.extension.ExtensionManagerBus;
+import org.apache.cxf.common.util.ASMHelper;
+import org.apache.cxf.common.util.ASMHelperImpl;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -58,6 +62,8 @@ public class JAXBExtensionHelperTest {
 
     private ExtensionRegistry registry;
 
+    private Bus bus;
+
     @Before
     public void setUp() throws Exception {
 
@@ -68,19 +74,24 @@ public class JAXBExtensionHelperTest {
         if (registry == null) {
             registry = wsdlFactory.newPopulatedExtensionRegistry();
         }
+        bus = new ExtensionManagerBus();
+        bus.setExtension(new ASMHelperImpl(), ASMHelper.class);
+        ExtensionClassCreator extr = new ExtensionClassGenerator(bus);
+        bus.setExtension(extr, ExtensionClassCreator.class);
     }
 
     @Test
     public void testAddTestExtension() throws Exception {
 
-        JAXBExtensionHelper.addExtensions(registry, "javax.wsdl.Port",
-                        "org.apache.cxf.abc.test.TestPolicyType");
 
-        JAXBExtensionHelper.addExtensions(registry, "javax.wsdl.Port",
-                        "org.apache.cxf.abc.test.AnotherPolicyType");
+        JAXBExtensionHelper.addExtensions(bus, registry, "javax.wsdl.Port",
+                "org.apache.cxf.abc.test.TestPolicyType");
+
+        JAXBExtensionHelper.addExtensions(bus, registry, "javax.wsdl.Port",
+                "org.apache.cxf.abc.test.AnotherPolicyType");
 
-        JAXBExtensionHelper.addExtensions(registry, "javax.wsdl.Definition",
-                        "org.apache.cxf.abc.test.NewServiceType");
+        JAXBExtensionHelper.addExtensions(bus, registry, "javax.wsdl.Definition",
+                "org.apache.cxf.abc.test.NewServiceType");
 
         String file = this.getClass().getResource("/wsdl/test_ext.wsdl").toURI().toString();
 
@@ -92,8 +103,8 @@ public class JAXBExtensionHelperTest {
 
     @Test
     public void testPrettyPrintXMLStreamWriter() throws Exception {
-        JAXBExtensionHelper.addExtensions(registry, "javax.wsdl.Definition",
-                        "org.apache.cxf.abc.test.NewServiceType");
+        JAXBExtensionHelper.addExtensions(bus, registry, "javax.wsdl.Definition",
+                "org.apache.cxf.abc.test.NewServiceType");
 
         String file = this.getClass().getResource("/wsdl/test_ext.wsdl").toURI().toString();
 
@@ -114,13 +125,13 @@ public class JAXBExtensionHelperTest {
 
         ByteArrayOutputStream stream = new ByteArrayOutputStream();
 
-        JAXBExtensionHelper helper = new JAXBExtensionHelper(NewServiceType.class, null);
+        JAXBExtensionHelper helper = new JAXBExtensionHelper(bus, NewServiceType.class, null);
         helper.marshall(javax.wsdl.Definition.class,
-                        new QName("http://cxf.apache.org/test/hello_world", "newService"),
-                        newService,
-                        new PrintWriter(stream),
-                        wsdlDefinition,
-                        registry);
+                new QName("http://cxf.apache.org/test/hello_world", "newService"),
+                newService,
+                new PrintWriter(stream),
+                wsdlDefinition,
+                registry);
         BufferedReader reader = new BufferedReader(new StringReader(new String(stream.toByteArray())));
         String actual = reader.readLine();
         int spaces = 0;
@@ -139,17 +150,17 @@ public class JAXBExtensionHelperTest {
 
     @Test
     public void testMappedNamespace() throws Exception {
-        JAXBExtensionHelper.addExtensions(registry, javax.wsdl.Port.class,
-            org.apache.cxf.abc.test.TestPolicyType.class,
-            "http://cxf.apache.org/abc/test/remapped");
+        JAXBExtensionHelper.addExtensions(bus, registry, javax.wsdl.Port.class,
+                org.apache.cxf.abc.test.TestPolicyType.class,
+                "http://cxf.apache.org/abc/test/remapped");
 
-        JAXBExtensionHelper.addExtensions(registry, javax.wsdl.Port.class,
-            org.apache.cxf.abc.test.AnotherPolicyType.class,
-            "http://cxf.apache.org/abc/test/remapped");
+        JAXBExtensionHelper.addExtensions(bus, registry, javax.wsdl.Port.class,
+                org.apache.cxf.abc.test.AnotherPolicyType.class,
+                "http://cxf.apache.org/abc/test/remapped");
 
-        JAXBExtensionHelper.addExtensions(registry, javax.wsdl.Definition.class,
-            org.apache.cxf.abc.test.NewServiceType.class,
-            "http://cxf.apache.org/abc/test/remapped");
+        JAXBExtensionHelper.addExtensions(bus, registry, javax.wsdl.Definition.class,
+                org.apache.cxf.abc.test.NewServiceType.class,
+                "http://cxf.apache.org/abc/test/remapped");
 
         String file = this.getClass().getResource("/wsdl/test_ext_remapped.wsdl").toURI().toString();
         wsdlReader.setExtensionRegistry(registry);
@@ -159,13 +170,13 @@ public class JAXBExtensionHelperTest {
         StringWriter out = new StringWriter();
         wsdlFactory.newWSDLWriter().writeWSDL(wsdlDefinition, out);
         wsdlDefinition = wsdlReader.readWSDL(null,
-                                             new InputSource(new StringReader(out.toString())));
+                new InputSource(new StringReader(out.toString())));
         checkTestExt();
     }
 
     private void checkTestExt() throws Exception {
         Service s = wsdlDefinition.getService(new QName("http://cxf.apache.org/test/hello_world",
-            "HelloWorldService"));
+                "HelloWorldService"));
         Port p = s.getPort("HelloWorldPort");
         List<?> extPortList = p.getExtensibilityElements();
 
@@ -177,7 +188,7 @@ public class JAXBExtensionHelperTest {
             } else if (ext instanceof AnotherPolicyType) {
                 ap = (AnotherPolicyType) ext;
             } else if (ext instanceof UnknownExtensibilityElement) {
-                UnknownExtensibilityElement e = (UnknownExtensibilityElement)ext;
+                UnknownExtensibilityElement e = (UnknownExtensibilityElement) ext;
                 System.out.println(e.getElementType());
             }
         }
@@ -187,7 +198,7 @@ public class JAXBExtensionHelperTest {
         assertEquals("Unexpected value for TestPolicyType intAttr", 30, tp.getIntAttr());
         assertEquals("Unexpected value for TestPolicyType stringAttr", "hello", tp.getStringAttr());
         assertTrue("Unexpected value for AnotherPolicyType floatAttr",
-                   Math.abs(0.1F - ap.getFloatAttr()) < 0.5E-5);
+                Math.abs(0.1F - ap.getFloatAttr()) < 0.5E-5);
     }
 
     private void checkSpaces(String actual, int spaces) {
@@ -196,7 +207,7 @@ public class JAXBExtensionHelperTest {
             space += " ";
         }
         assertTrue("Indentation level not proper when marshalling a extension element;" + actual,
-                   actual.startsWith(space));
+                actual.startsWith(space));
     }
 
 }
\ No newline at end of file
diff --git a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/ClientServerMiscTest.java b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/ClientServerMiscTest.java
index 78807ea..c75e6e0 100644
--- a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/ClientServerMiscTest.java
+++ b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/ClientServerMiscTest.java
@@ -22,7 +22,7 @@ package org.apache.cxf.systest.jaxws;
 import java.io.BufferedReader;
 import java.io.InputStream;
 import java.io.StringReader;
-import java.lang.reflect.Field;
+import java.lang.reflect.Method;
 import java.lang.reflect.UndeclaredThrowableException;
 import java.math.BigInteger;
 import java.net.HttpURLConnection;
@@ -99,6 +99,7 @@ public class ClientServerMiscTest extends AbstractBusClientServerTestBase {
 
     @BeforeClass
     public static void startServers() throws Exception {
+        createStaticBus();
         assertTrue("server did not launch correctly", launchServer(ServerMisc.class, true));
     }
 
@@ -419,9 +420,11 @@ public class ClientServerMiscTest extends AbstractBusClientServerTestBase {
     }
 
     private void setASM(boolean b) throws Exception {
-        Field f = ASMHelper.class.getDeclaredField("badASM");
-        ReflectionUtil.setAccessible(f);
-        f.set(null, !b);
+
+        ASMHelper helper = getBus().getExtension(ASMHelper.class);
+        Method m = helper.getClass().getMethod("setBadASM", Boolean.TYPE);
+        ReflectionUtil.setAccessible(m);
+        m.invoke(helper, !b);
     }
 
     @Test
@@ -608,7 +611,7 @@ public class ClientServerMiscTest extends AbstractBusClientServerTestBase {
         assertEquals(3, ints.length);
         assertEquals(1, ints[0]);
 
-        if (new ASMHelper().createClassWriter() != null) {
+        if (getBus().getExtension(ASMHelper.class).createClassWriter() != null) {
             //doing the type adapter things and such really
             //requires the ASM generated helper classes
             assertEquals("Val", port.createBar("Val").getName());