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:43 UTC

[cxf] branch 3.4.x-fixes updated (510933e -> 3df663a)

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

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


    from 510933e  Updating Jackson to 2.11.4
     new 5ec867c  [cxf-8340] add precompiled class for Graalvm native support (#721)
     new 5a2b431  Fixing some outdated comments
     new 3df663a  Recording .gitmergeinfo Changes

The 3 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .gitmergeinfo                                      |   3 +
 .../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 +-
 75 files changed, 3785 insertions(+), 2135 deletions(-)
 create mode 100644 core/src/main/java/org/apache/cxf/common/spi/ClassGeneratorClassLoader.java
 create mode 100644 core/src/main/java/org/apache/cxf/common/spi/ClassLoaderProxyService.java
 create mode 100644 core/src/main/java/org/apache/cxf/common/spi/ClassLoaderService.java
 create mode 100644 core/src/main/java/org/apache/cxf/common/spi/GeneratedClassClassLoader.java
 create mode 100644 core/src/main/java/org/apache/cxf/common/spi/GeneratedClassClassLoaderCapture.java
 create mode 100644 core/src/main/java/org/apache/cxf/common/spi/GeneratedNamespaceClassLoader.java
 create mode 100644 core/src/main/java/org/apache/cxf/common/spi/NamespaceClassCreator.java
 create mode 100644 core/src/main/java/org/apache/cxf/common/spi/NamespaceClassGenerator.java
 create mode 100644 core/src/main/java/org/apache/cxf/common/util/ASMHelperImpl.java
 create mode 100644 core/src/main/java/org/apache/cxf/common/util/OpcodesProxy.java
 create mode 100644 rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/utils/CorbaFixedAnyImplClassCreator.java
 create mode 100644 rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/utils/CorbaFixedAnyImplClassCreatorProxyService.java
 create mode 100644 rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/utils/CorbaFixedAnyImplClassLoader.java
 create mode 100644 rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/utils/CorbaFixedAnyImplGenerator.java
 create mode 100644 rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/FactoryClassCreator.java
 create mode 100644 rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/FactoryClassGenerator.java
 create mode 100644 rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/FactoryClassLoader.java
 create mode 100644 rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/FactoryClassProxyService.java
 create mode 100644 rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/WrapperHelperClassGenerator.java
 create mode 100644 rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/WrapperHelperClassLoader.java
 delete mode 100644 rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/WrapperHelperCompiler.java
 create mode 100644 rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/WrapperHelperCreator.java
 create mode 100644 rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/WrapperHelperProxyService.java
 create mode 100644 rt/databinding/jaxb/src/main/resources/META-INF/cxf/bus-extensions.txt
 create mode 100644 rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/spi/WrapperClassCreator.java
 create mode 100644 rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/spi/WrapperClassCreatorProxyService.java
 create mode 100644 rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/spi/WrapperClassLoader.java
 rename rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/{WrapperClassGeneratorTest.java => WrapperNamespaceClassGeneratorTest.java} (62%)
 create mode 100644 rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/service/AddNumbers2.java
 create mode 100644 rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/service/AddNumbers2Impl.java
 create mode 100644 rt/frontend/simple/src/main/java/org/apache/cxf/endpoint/dynamic/ExceptionClassCreator.java
 create mode 100644 rt/frontend/simple/src/main/java/org/apache/cxf/endpoint/dynamic/ExceptionClassCreatorProxyService.java
 create mode 100644 rt/frontend/simple/src/main/java/org/apache/cxf/endpoint/dynamic/ExceptionClassGenerator.java
 create mode 100644 rt/frontend/simple/src/main/java/org/apache/cxf/endpoint/dynamic/ExceptionClassLoader.java
 create mode 100644 rt/frontend/simple/src/main/resources/META-INF/cxf/bus-extensions.txt
 create mode 100644 rt/wsdl/src/main/java/org/apache/cxf/wsdl/ExtensionClassCreator.java
 create mode 100644 rt/wsdl/src/main/java/org/apache/cxf/wsdl/ExtensionClassCreatorProxyService.java
 create mode 100644 rt/wsdl/src/main/java/org/apache/cxf/wsdl/ExtensionClassGenerator.java
 create mode 100644 rt/wsdl/src/main/java/org/apache/cxf/wsdl/ExtensionClassLoader.java


[cxf] 03/03: Recording .gitmergeinfo Changes

Posted by re...@apache.org.
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 3df663a11ad3492cce42aec501755f3e425202cb
Author: reta <dr...@gmail.com>
AuthorDate: Wed Dec 16 20:23:23 2020 -0500

    Recording .gitmergeinfo Changes
---
 .gitmergeinfo | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/.gitmergeinfo b/.gitmergeinfo
index b1e2334..de513a4 100644
--- a/.gitmergeinfo
+++ b/.gitmergeinfo
@@ -8,7 +8,10 @@ B 9485e3b46125c9102610aa6dcab6e330952b2fb0
 B c58d2cd38003a90608aa04e40756c042cbaf7e03
 B f5f08c838e1d52f17bcc8422fac38831a63e6e30
 M 1820f1a94b08ba840c3868ac3e1f3b7751540a08
+M 2f844e251362ab62923cfc6b7061591375a1cb44
 M 4162189dabdb22aec54dc3c5ae93cf42b0575d3d
+M 420f6f35915cbd50cc175a6a10359125516b0213
+M 4c3c5196be3e9295c31b5bc592ebc8f911c93c6d
 M 6a77819f4bc141fcddd53a36b178972f1f68fe97
 M 70c7d6a1e3f23522609d58b72b61c52e3cbc919a
 M 8c4f04855a5d8623daff2aa8a8856367879c624b


[cxf] 02/03: Fixing some outdated comments

Posted by re...@apache.org.
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 5a2b431a5b672138231c488cb72dd29c77077ff0
Author: reta <dr...@gmail.com>
AuthorDate: Wed Dec 16 20:21:33 2020 -0500

    Fixing some outdated comments
    
    (cherry picked from commit 8100e4d9512b2fd9ce2fe30a4b7feeaab1d691a5)
---
 .../org/apache/cxf/common/spi/GeneratedClassClassLoaderCapture.java     | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

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
index b71d582..06f7044 100644
--- a/core/src/main/java/org/apache/cxf/common/spi/GeneratedClassClassLoaderCapture.java
+++ b/core/src/main/java/org/apache/cxf/common/spi/GeneratedClassClassLoaderCapture.java
@@ -26,7 +26,7 @@ package org.apache.cxf.common.spi;
  *  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 WrapperHelperClassLoader(bus), WrapperClassCreator.class);
  *  bus.setExtension(new FactoryClassLoader(bus), FactoryClassCreator.class);
  *  bus.setExtension(new GeneratedNamespaceClassLoader(bus), NamespaceClassCreator.class);
  * @author olivier dufour


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

Posted by re...@apache.org.
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());