[ 
https://issues.apache.org/jira/browse/CXF-8836?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]
Andreas Rusjaev updated CXF-8836:
---------------------------------
    Description: 
Dear CXF developers,
I am using version 4.0.0 of CXF cxf-spring-boot-starter-jaxws.
My CXF jaxws services are wrapped in Spring Boot 3.0. I also use 
akarta.xml.bind-api 4.0.0 and org.eclipse.persistence.moxy 4.0.1.
I generate Java models with cxf-codegen-plugin with the following configuration:

 
{code:java}
<plugin>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-codegen-plugin</artifactId>
    <version>${cxf.version}</version>
    <dependencies>
        <dependency>
            <groupId>org.jvnet.jaxb2_commons</groupId>
            <artifactId>jaxb2-basics-annotate</artifactId>
            <version>1.1.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf.xjc-utils</groupId>
            <artifactId>cxf-xjc-runtime</artifactId>
            <version>${cxf.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf.xjcplugins</groupId>
            <artifactId>cxf-xjc-ts</artifactId>
            <version>${cxf.version}</version>
        </dependency>
        <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
            <version>2.4.0-b180830.0359</version>
        </dependency>
    </dependencies>
    <executions>
        <execution>
            <id>generate-sources</id>
            <phase>generate-sources</phase>
            <configuration>
                
<sourceRoot>${project.build.directory}/generated-sources/cxf</sourceRoot>
                <defaultOptions>
                    <noAddressBinding>true</noAddressBinding>
                    
<faultSerialVersionUID>3105839350746982386</faultSerialVersionUID>
                    <extraargs>
                        <extraarg>-xjc-Xannotate</extraarg>
                    </extraargs>
                </defaultOptions>
                <wsdlOptions>
                    <wsdlOption>
                        
<wsdl>${basedir}/src/main/resources/wsdl/myservice.wsdl</wsdl>
                        
<wsdlLocation>classpath:wsdl/myservice.wsdl</wsdlLocation>
                        <serviceName>myservice</serviceName>
                        <bindingFiles>
                            
<bindingFile>${basedir}/src/main/resources/wsdl/bindings.xjb</bindingFile>
                        </bindingFiles>
                    </wsdlOption>
                </wsdlOptions>
            </configuration>
            <goals>
                <goal>wsdl2java</goal>
            </goals>
        </execution>
    </executions>
</plugin>{code}
 

Binding file has the following configuration:
{code:java}
<?xml version="1.0"?>
<jaxb:bindings version="3.0"
               xmlns:jaxb="https://jakarta.ee/xml/ns/jaxb";
               jaxb:extensionBindingPrefixes="annox xjc"
               xmlns:xs="http://www.w3.org/2001/XMLSchema";
               xmlns:annox="http://annox.dev.java.net";
               xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc";>
    <jaxb:bindings>
        <jaxb:bindings>
            <jaxb:globalBindings typesafeEnumMaxMembers="3000"
                                 generateElementProperty="false"
                                 mapSimpleTypeDef="false"
                                 fixedAttributeAsConstantProperty="true"
                                 choiceContentProperty="true"
                                 typesafeEnumBase="xs:boolean">
            </jaxb:globalBindings>
        </jaxb:bindings>
    </jaxb:bindings>
    <jaxb:bindings schemaLocation="*">
        <jaxb:bindings node="//xs:complexType" multiple="true" required="false">
            
<annox:annotateClass>@lombok.experimental.SuperBuilder</annox:annotateClass>
            
<annox:annotateClass>@jakarta.xml.bind.annotation.XmlRootElement</annox:annotateClass>
            <annox:annotateClass>@lombok.NoArgsConstructor</annox:annotateClass>
        </jaxb:bindings>
        <jaxb:bindings node="//xs:element" multiple="true" required="false">
            <annox:annotate target="field">
                
@org.eclipse.persistence.oxm.annotations.XmlNullPolicy(nullRepresentationForXml=
                XmlMarshalNullRepresentation.ABSENT_NODE, 
xsiNilRepresentsNull=false)
            </annox:annotate>
        </jaxb:bindings>
    </jaxb:bindings>
</jaxb:bindings>
{code}
 

Model class generation works fine, nullable properties are marked with 
annotation:
{code:java}
@XmlNullPolicy(nullRepresentationForXml = 
XmlMarshalNullRepresentation.ABSENT_NODE, xsiNilRepresentsNull = false){code}
To start Moxy Runtime use the following settings in main method of Application:
{code:java}
 System.setProperty("jakarta.xml.bind.JAXBContextFactory", 
"org.eclipse.persistence.jaxb.JAXBContextFactory");{code}
 
I use this initialisation because I still need to use Spring Web Service Client 
from Spring WS in parallel.
 
But on application startup I get errors:

Caused by: java.lang.reflect.InvocationTargetException: null
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native 
Method) ~[na:na]
    at 
java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
 ~[na:na]
    at 
java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
 ~[na:na]
    at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
    at org.apache.cxf.common.jaxb.JAXBUtils$3.run(JAXBUtils.java:1189) 
~[cxf-core-4.0.0.jar:4.0.0]
    at org.apache.cxf.common.jaxb.JAXBUtils$3.run(JAXBUtils.java:1183) 
~[cxf-core-4.0.0.jar:4.0.0]
    at 
java.base/java.security.AccessController.doPrivileged(AccessController.java:569)
 ~[na:na]
    at org.apache.cxf.common.jaxb.JAXBUtils.createContext(JAXBUtils.java:1183) 
~[cxf-core-4.0.0.jar:4.0.0]
    ... 64 common frames omitted
Caused by: jakarta.xml.bind.JAXBException: Property 
"eclipselink.default-target-namespace" is not supported.
    at 
org.glassfish.jaxb.runtime.v2.ContextFactory.createContext(ContextFactory.java:126)
 ~[jaxb-runtime-4.0.1.jar:4.0.1 - a95cb76]
    
I have examined your code and found that you are using hard coded call to 
"Class<?> factoryClass = 
ClassLoaderUtils.loadClass("org.glassfish.jaxb.runtime.v2.ContextFactory" in 
cxf-core org.apache.cxf.common.jaxb.JAXBUtils

I have experimented a bit and if you can make a few changes in two classes 
everything will work. The classes need to be changed:

1. org.apache.cxf.common.jaxb.JAXBContextCache Method 
getCachedContextAndSchemas in lines 197 to 194 

    old code

 
{code:java}
if (defaultNs != null) {
    if (HAS_MOXY){                 
      map.put("eclipselink.default-target-namespace", defaultNs);               
  
    }
    map.put("org.glassfish.jaxb.defaultNamespaceRemap", defaultNs);
}
{code}
    new code
{code:java}
if (defaultNs != null){             
   if (HAS_MOXY){                 
      map.put("eclipselink.default-target-namespace", defaultNs);             
   }
   else{                 
      map.put("org.glassfish.jaxb.defaultNamespaceRemap", defaultNs);           
  
   }
}
{code}
        
2. org.apache.cxf.common.jaxb.JAXBUtils
    
    2.1 Method getPostfix in lines 1105 to 1117
        old code:
{code:java}
private static String getPostfix(Class<?> cls) {
   String className = cls.getName();
   //TODO: review and remove "com.sun" package name check
   if (className.contains("org.glassfish.jaxb") || 
className.contains("com.sun.xml.bind")
                        || className.startsWith("com.ibm.xml")){                
     
     return "";                 
   }
   else if (className.contains("com.sun.xml.internal")
                        || className.contains("eclipse")){                     
     //eclipse moxy accepts sun package CharacterEscapeHandler                  
   
      return ".internal";                 
    }
    return null;
 }
{code}
        new code:    
{code:java}
private static String getPostfix(Class<?> cls) {
    String className = cls.getName();
    //TODO: review and remove "com.sun" package name check
    if (className.contains("org.glassfish.jaxb") || 
className.contains("com.sun.xml.bind")
            || className.startsWith("com.ibm.xml") || 
className.contains("eclipse")) {
        //eclipse moxy 4.0 accepts glassfish package CharacterEscapeHandler see 
const SUN_CHARACTER_ESCAPE_HANDLER
        // Const in MOXY 4.0.1
        // SUN_CHARACTER_ESCAPE_HANDLER= 
"org.glassfish.jaxb.characterEscapeHandler";
        // SUN_JSE_CHARACTER_ESCAPE_HANDLER = 
"com.sun.xml.internal.bind.characterEscapeHandler";
        // SUN_CHARACTER_ESCAPE_HANDLER_MARSHALLER = 
"org.glassfish.jaxb.marshaller.CharacterEscapeHandler";
        // SUN_JSE_CHARACTER_ESCAPE_HANDLER_MARSHALLER = 
"com.sun.xml.internal.bind.marshaller.CharacterEscapeHandler"
                    
        // part of setProperty(String key, Object value) from Class 
org.eclipse.persistence.jaxb. JAXBMarshaller
                    
        //        else if (SUN_CHARACTER_ESCAPE_HANDLER.equals(key) || 
SUN_JSE_CHARACTER_ESCAPE_HANDLER.equals(key) || 
        //                SUN_CHARACTER_ESCAPE_HANDLER_MARSHALLER.equals(key) 
|| 
        //                
SUN_JSE_CHARACTER_ESCAPE_HANDLER_MARSHALLER.equals(key)) {
        //        if (value == null) {
        //            xmlMarshaller.setCharacterEscapeHandler(null);
        //        } else {
        //            xmlMarshaller.setCharacterEscapeHandler(new 
CharacterEscapeHandlerWrapper(value));
        //        }
                    
        return "";
    } else if (className.contains("com.sun.xml.internal")) {
        return ".internal";
    }
    return null;
}{code}
            
    2.2 Method createContext in lines 1179 to 1202
        old code:    
{code:java}
public static JAXBContext createContext(final Set<Class<?>> classes,
                                                final Map<String, Object> map) 
throws JAXBException {
  JAXBContext ctx = null;
  try {
      ctx = AccessController.doPrivileged(new 
PrivilegedExceptionAction<JAXBContext>() {
          public JAXBContext run() throws Exception {    
              //This is a workaround for CXF-8675                            

              Class<?> factoryClass = 
ClassLoaderUtils.loadClass("org.glassfish.jaxb.runtime.v2.ContextFactory",     
                        JAXBContextCache.class);                             
              Method m = factoryClass.getMethod("createContext", Class[].class, 
Map.class);               
              Object context = m.invoke(null, classes.toArray(new Class<?>[0]), 
map);                             
              return (JAXBContext) context;                         
          }
      });
  } catch (PrivilegedActionException e2) {
      if (e2.getException() instanceof JAXBException){                         
          JAXBException ex = (JAXBException) e2.getException();                 
        
          throw ex;                     
      } else {                         
          throw new RuntimeException(e2.getException());                     
      }
  }
  return ctx;
}
        
{code}
        new code:
{code:java}
public static JAXBContext createContext(final Set<Class<?>> classes,
                                            final Map<String, Object> map) 
throws JAXBException {
    JAXBContext ctx = null;
    try {
        ctx = AccessController.doPrivileged(new 
PrivilegedExceptionAction<JAXBContext>() {
           public JAXBContext run() throws Exception {                          
   
              String factoryClassName = 
classNameFromSystemProperties("org.glassfish.jaxb.runtime.v2.ContextFactory");  
                           
              //This is a workaround for CXF-8675                             
              Class<?> factoryClass = 
ClassLoaderUtils.loadClass(factoryClassName, JAXBContextCache.class);           
                  
              Method m = factoryClass.getMethod("createContext", Class[].class, 
Map.class);                             
              Object context = m.invoke(null, classes.toArray(new Class<?>[0]), 
map);                             
              return (JAXBContext) context;                         
           }
        });
    } catch (PrivilegedActionException e2) {
        if (e2.getException() instanceof JAXBException) {                       
  
            JAXBException ex = (JAXBException) e2.getException();               
          
            throw ex;                     
        }
        else{                         
            throw new RuntimeException(e2.getException());                     
        }
    }
    return ctx;
}
private static String classNameFromSystemProperties(String defaultValue) throws 
JAXBException {
    String factoryClassName = 
getSystemProperty(JAXBContext.JAXB_CONTEXT_FACTORY, defaultValue);
    if (factoryClassName != null){                     
        return factoryClassName;                 
    }
    return null;
}
private static String getSystemProperty(String property, String defaultValue) {
    String value = System.getProperty(property);
    if (value != null){                     
        return value;                 
    }
    else{                     
        return defaultValue;                 
    }
}
{code}
With this Changes work for me fine, without Errors. Can you please check if you 
can incorporate these changes into CXF-CORE.             

If you have other possibilities to configure org.eclipse.persistence.moxy. Can 
you please describe. 
Thanks in advance
Anderas Rusjaev

 

  was:
Dear CXF developers,
I am using version 4.0.0 of CXF cxf-spring-boot-starter-jaxws.
My CXF jaxws services are wrapped in Spring Boot 3.0. I also use 
akarta.xml.bind-api 4.0.0 and org.eclipse.persistence.moxy 4.0.1.
I generate Java models with cxf-codegen-plugin with the following configuration:

 
{code:java}
<plugin>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-codegen-plugin</artifactId>
    <version>${cxf.version}</version>
    <dependencies>
        <dependency>
            <groupId>org.jvnet.jaxb2_commons</groupId>
            <artifactId>jaxb2-basics-annotate</artifactId>
            <version>1.1.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf.xjc-utils</groupId>
            <artifactId>cxf-xjc-runtime</artifactId>
            <version>${cxf.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf.xjcplugins</groupId>
            <artifactId>cxf-xjc-ts</artifactId>
            <version>${cxf.version}</version>
        </dependency>
        <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
            <version>2.4.0-b180830.0359</version>
        </dependency>
    </dependencies>
    <executions>
        <execution>
            <id>generate-sources</id>
            <phase>generate-sources</phase>
            <configuration>
                
<sourceRoot>${project.build.directory}/generated-sources/cxf</sourceRoot>
                <defaultOptions>
                    <noAddressBinding>true</noAddressBinding>
                    
<faultSerialVersionUID>3105839350746982386</faultSerialVersionUID>
                    <extraargs>
                        <extraarg>-xjc-Xannotate</extraarg>
                    </extraargs>
                </defaultOptions>
                <wsdlOptions>
                    <wsdlOption>
                        
<wsdl>${basedir}/src/main/resources/wsdl/myservice.wsdl</wsdl>
                        
<wsdlLocation>classpath:wsdl/myservice.wsdl</wsdlLocation>
                        <serviceName>myservice</serviceName>
                        <bindingFiles>
                            
<bindingFile>${basedir}/src/main/resources/wsdl/bindings.xjb</bindingFile>
                        </bindingFiles>
                    </wsdlOption>
                </wsdlOptions>
            </configuration>
            <goals>
                <goal>wsdl2java</goal>
            </goals>
        </execution>
    </executions>
</plugin>{code}
 

Binding file has the following configuration:
{code:java}
<?xml version="1.0"?>
<jaxb:bindings version="3.0"
               xmlns:jaxb="https://jakarta.ee/xml/ns/jaxb";
               jaxb:extensionBindingPrefixes="annox xjc"
               xmlns:xs="http://www.w3.org/2001/XMLSchema";
               xmlns:annox="http://annox.dev.java.net";
               xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc";>
    <jaxb:bindings>
        <jaxb:bindings>
            <jaxb:globalBindings typesafeEnumMaxMembers="3000"
                                 generateElementProperty="false"
                                 mapSimpleTypeDef="false"
                                 fixedAttributeAsConstantProperty="true"
                                 choiceContentProperty="true"
                                 typesafeEnumBase="xs:boolean">
            </jaxb:globalBindings>
        </jaxb:bindings>
    </jaxb:bindings>
    <jaxb:bindings schemaLocation="*">
        <jaxb:bindings node="//xs:complexType" multiple="true" required="false">
            
<annox:annotateClass>@lombok.experimental.SuperBuilder</annox:annotateClass>
            
<annox:annotateClass>@jakarta.xml.bind.annotation.XmlRootElement</annox:annotateClass>
            <annox:annotateClass>@lombok.NoArgsConstructor</annox:annotateClass>
        </jaxb:bindings>
        <jaxb:bindings node="//xs:element" multiple="true" required="false">
            <annox:annotate target="field">
                
@org.eclipse.persistence.oxm.annotations.XmlNullPolicy(nullRepresentationForXml=
                XmlMarshalNullRepresentation.ABSENT_NODE, 
xsiNilRepresentsNull=false)
            </annox:annotate>
        </jaxb:bindings>
    </jaxb:bindings>
</jaxb:bindings>
{code}
 

Model class generation works fine, nullable properties are marked with 
annotation:
{code:java}
@XmlNullPolicy(nullRepresentationForXml = 
XmlMarshalNullRepresentation.ABSENT_NODE, xsiNilRepresentsNull = false){code}
To start Moxy Runtime use the following settings in main method of Application:
{code:java}
 System.setProperty("jakarta.xml.bind.JAXBContextFactory", 
"org.eclipse.persistence.jaxb.JAXBContextFactory");{code}
 
I use this initialisation because I still need to use Spring Web Service Client 
from Spring WS in parallel.
 
But on application startup I get errors:

Caused by: java.lang.reflect.InvocationTargetException: null
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native 
Method) ~[na:na]
    at 
java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
 ~[na:na]
    at 
java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
 ~[na:na]
    at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
    at org.apache.cxf.common.jaxb.JAXBUtils$3.run(JAXBUtils.java:1189) 
~[cxf-core-4.0.0.jar:4.0.0]
    at org.apache.cxf.common.jaxb.JAXBUtils$3.run(JAXBUtils.java:1183) 
~[cxf-core-4.0.0.jar:4.0.0]
    at 
java.base/java.security.AccessController.doPrivileged(AccessController.java:569)
 ~[na:na]
    at org.apache.cxf.common.jaxb.JAXBUtils.createContext(JAXBUtils.java:1183) 
~[cxf-core-4.0.0.jar:4.0.0]
    ... 64 common frames omitted
Caused by: jakarta.xml.bind.JAXBException: Property 
"eclipselink.default-target-namespace" is not supported.
    at 
org.glassfish.jaxb.runtime.v2.ContextFactory.createContext(ContextFactory.java:126)
 ~[jaxb-runtime-4.0.1.jar:4.0.1 - a95cb76]
    
I have examined your code and found that you are using hard coded call to 
"Class<?> factoryClass = 
ClassLoaderUtils.loadClass("org.glassfish.jaxb.runtime.v2.ContextFactory" in 
cxf-core org.apache.cxf.common.jaxb.JAXBUtils

I have experimented a bit and if you can make a few changes in two classes 
everything will work. The classes need to be changed:

1. org.apache.cxf.common.jaxb.JAXBContextCache Method 
getCachedContextAndSchemas in lines 197 to 194 

    old code

 
{code:java}
if (defaultNs != null) {
    if (HAS_MOXY){                 
      map.put("eclipselink.default-target-namespace", defaultNs);               
  
    }
    map.put("org.glassfish.jaxb.defaultNamespaceRemap", defaultNs);
}
{code}
    new code
       
{code:java}
if (defaultNs != null){             
   if (HAS_MOXY){                 
      map.put("eclipselink.default-target-namespace", defaultNs);             
   }
   else{                 
      map.put("org.glassfish.jaxb.defaultNamespaceRemap", defaultNs);           
  
   }
}
{code}
        
2. org.apache.cxf.common.jaxb.JAXBUtils
    
    2.1 Method getPostfix in lines 1105 to 1117
        old code:
{code:java}
private static String getPostfix(Class<?> cls) {
   String className = cls.getName();
   //TODO: review and remove "com.sun" package name check
   if (className.contains("org.glassfish.jaxb") || 
className.contains("com.sun.xml.bind")
                        || className.startsWith("com.ibm.xml")){                
     
     return "";                 
   }
   else if (className.contains("com.sun.xml.internal")
                        || className.contains("eclipse")){                     
     //eclipse moxy accepts sun package CharacterEscapeHandler                  
   
      return ".internal";                 
    }
    return null;
 }
{code}
        new code:    
           
{code:java}
private static String getPostfix(Class<?> cls) {
    String className = cls.getName();
    //TODO: review and remove "com.sun" package name check
    if (className.contains("org.glassfish.jaxb") || 
className.contains("com.sun.xml.bind")
            || className.startsWith("com.ibm.xml") || 
className.contains("eclipse")) {
        //eclipse moxy 4.0 accepts glassfish package CharacterEscapeHandler see 
const SUN_CHARACTER_ESCAPE_HANDLER
        // Const in MOXY 4.0.1
        // SUN_CHARACTER_ESCAPE_HANDLER= 
"org.glassfish.jaxb.characterEscapeHandler";
        // SUN_JSE_CHARACTER_ESCAPE_HANDLER = 
"com.sun.xml.internal.bind.characterEscapeHandler";
        // SUN_CHARACTER_ESCAPE_HANDLER_MARSHALLER = 
"org.glassfish.jaxb.marshaller.CharacterEscapeHandler";
        // SUN_JSE_CHARACTER_ESCAPE_HANDLER_MARSHALLER = 
"com.sun.xml.internal.bind.marshaller.CharacterEscapeHandler"
                    
        // part of setProperty(String key, Object value) from Class 
org.eclipse.persistence.jaxb. JAXBMarshaller
                    
        //        else if (SUN_CHARACTER_ESCAPE_HANDLER.equals(key) || 
SUN_JSE_CHARACTER_ESCAPE_HANDLER.equals(key) || 
        //                SUN_CHARACTER_ESCAPE_HANDLER_MARSHALLER.equals(key) 
|| 
        //                
SUN_JSE_CHARACTER_ESCAPE_HANDLER_MARSHALLER.equals(key)) {
        //        if (value == null) {
        //            xmlMarshaller.setCharacterEscapeHandler(null);
        //        } else {
        //            xmlMarshaller.setCharacterEscapeHandler(new 
CharacterEscapeHandlerWrapper(value));
        //        }
                    
        return "";
    } else if (className.contains("com.sun.xml.internal")) {
        return ".internal";
    }
    return null;
}{code}
            
    2.2 Method createContext in lines 1179 to 1202
        old code:
           
{code:java}
public static JAXBContext createContext(final Set<Class<?>> classes,
                                                final Map<String, Object> map) 
throws JAXBException {
  JAXBContext ctx = null;
  try {
   ctx = AccessController.doPrivileged(new 
PrivilegedExceptionAction<JAXBContext>() {
     public JAXBContext run() throws Exception {    
      //This is a workaround for CXF-8675                            

Class<?> factoryClass = 
ClassLoaderUtils.loadClass("org.glassfish.jaxb.runtime.v2.ContextFactory",      
                               JAXBContextCache.class);                         
    
Method m = factoryClass.getMethod("createContext", Class[].class, Map.class);   
            Object context = m.invoke(null, classes.toArray(new Class<?>[0]), 
map);                             return (JAXBContext) context;                 
        }
                    });
                } catch (PrivilegedActionException e2) {
                    if (e2.getException() instanceof JAXBException)
{                         JAXBException ex = (JAXBException) e2.getException(); 
                        throw ex;                     } else {                  
       throw new RuntimeException(e2.getException());                     }
                }
                return ctx;
            }
        
{code}
 

        new code:

           
{code:java}
public static JAXBContext createContext(final Set<Class<?>> classes,
                                            final Map<String, Object> map) 
throws JAXBException {
                JAXBContext ctx = null;
                try {
                    ctx = AccessController.doPrivileged(new 
PrivilegedExceptionAction<JAXBContext>() {
                        public JAXBContext run() throws Exception {             
                String factoryClassName = 
classNameFromSystemProperties("org.glassfish.jaxb.runtime.v2.ContextFactory");  
                           //This is a workaround for CXF-8675                  
           
Class<?> factoryClass = ClassLoaderUtils.loadClass(factoryClassName,            
                         JAXBContextCache.class);                             
Method m = factoryClass.getMethod("createContext", Class[].class, Map.class);   
                          Object context = m.invoke(null, classes.toArray(new 
Class<?>[0]), map);                             return (JAXBContext) context;   
                      }
                    });
                } catch (PrivilegedActionException e2) {
                    if (e2.getException() instanceof JAXBException) {           
              JAXBException ex = (JAXBException) e2.getException();             
            throw ex;                     }
else
{                         throw new RuntimeException(e2.getException());        
             }
                }
                return ctx;
            }
            private static String classNameFromSystemProperties(String 
defaultValue) throws JAXBException {
                String factoryClassName = 
getSystemProperty(JAXBContext.JAXB_CONTEXT_FACTORY, defaultValue);
                if (factoryClassName != null)
{                     return factoryClassName;                 }
                return null;
            }
            private static String getSystemProperty(String property, String 
defaultValue) {
                String value = System.getProperty(property);
                if (value != null)
{                     return value;                 }
else
{                     return defaultValue;                 }
            }
{code}
With this Changes work for me fine, without Errors. Can you please check if you 
can incorporate these changes into CXF-CORE.             

If you have other possibilities to configure org.eclipse.persistence.moxy. Can 
you please describe. 
Thanks in advance
Anderas Rusjaev

 


> Jaxb Integration with EclipseLink has Error
> -------------------------------------------
>
>                 Key: CXF-8836
>                 URL: https://issues.apache.org/jira/browse/CXF-8836
>             Project: CXF
>          Issue Type: Bug
>          Components: Core
>    Affects Versions: 4.0.0
>            Reporter: Andreas Rusjaev
>            Priority: Major
>
> Dear CXF developers,
> I am using version 4.0.0 of CXF cxf-spring-boot-starter-jaxws.
> My CXF jaxws services are wrapped in Spring Boot 3.0. I also use 
> akarta.xml.bind-api 4.0.0 and org.eclipse.persistence.moxy 4.0.1.
> I generate Java models with cxf-codegen-plugin with the following 
> configuration:
>  
> {code:java}
> <plugin>
>     <groupId>org.apache.cxf</groupId>
>     <artifactId>cxf-codegen-plugin</artifactId>
>     <version>${cxf.version}</version>
>     <dependencies>
>         <dependency>
>             <groupId>org.jvnet.jaxb2_commons</groupId>
>             <artifactId>jaxb2-basics-annotate</artifactId>
>             <version>1.1.0</version>
>         </dependency>
>         <dependency>
>             <groupId>org.apache.cxf.xjc-utils</groupId>
>             <artifactId>cxf-xjc-runtime</artifactId>
>             <version>${cxf.version}</version>
>         </dependency>
>         <dependency>
>             <groupId>org.apache.cxf.xjcplugins</groupId>
>             <artifactId>cxf-xjc-ts</artifactId>
>             <version>${cxf.version}</version>
>         </dependency>
>         <dependency>
>             <groupId>javax.xml.bind</groupId>
>             <artifactId>jaxb-api</artifactId>
>             <version>2.4.0-b180830.0359</version>
>         </dependency>
>     </dependencies>
>     <executions>
>         <execution>
>             <id>generate-sources</id>
>             <phase>generate-sources</phase>
>             <configuration>
>                 
> <sourceRoot>${project.build.directory}/generated-sources/cxf</sourceRoot>
>                 <defaultOptions>
>                     <noAddressBinding>true</noAddressBinding>
>                     
> <faultSerialVersionUID>3105839350746982386</faultSerialVersionUID>
>                     <extraargs>
>                         <extraarg>-xjc-Xannotate</extraarg>
>                     </extraargs>
>                 </defaultOptions>
>                 <wsdlOptions>
>                     <wsdlOption>
>                         
> <wsdl>${basedir}/src/main/resources/wsdl/myservice.wsdl</wsdl>
>                         
> <wsdlLocation>classpath:wsdl/myservice.wsdl</wsdlLocation>
>                         <serviceName>myservice</serviceName>
>                         <bindingFiles>
>                             
> <bindingFile>${basedir}/src/main/resources/wsdl/bindings.xjb</bindingFile>
>                         </bindingFiles>
>                     </wsdlOption>
>                 </wsdlOptions>
>             </configuration>
>             <goals>
>                 <goal>wsdl2java</goal>
>             </goals>
>         </execution>
>     </executions>
> </plugin>{code}
>  
> Binding file has the following configuration:
> {code:java}
> <?xml version="1.0"?>
> <jaxb:bindings version="3.0"
>                xmlns:jaxb="https://jakarta.ee/xml/ns/jaxb";
>                jaxb:extensionBindingPrefixes="annox xjc"
>                xmlns:xs="http://www.w3.org/2001/XMLSchema";
>                xmlns:annox="http://annox.dev.java.net";
>                xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc";>
>     <jaxb:bindings>
>         <jaxb:bindings>
>             <jaxb:globalBindings typesafeEnumMaxMembers="3000"
>                                  generateElementProperty="false"
>                                  mapSimpleTypeDef="false"
>                                  fixedAttributeAsConstantProperty="true"
>                                  choiceContentProperty="true"
>                                  typesafeEnumBase="xs:boolean">
>             </jaxb:globalBindings>
>         </jaxb:bindings>
>     </jaxb:bindings>
>     <jaxb:bindings schemaLocation="*">
>         <jaxb:bindings node="//xs:complexType" multiple="true" 
> required="false">
>             
> <annox:annotateClass>@lombok.experimental.SuperBuilder</annox:annotateClass>
>             
> <annox:annotateClass>@jakarta.xml.bind.annotation.XmlRootElement</annox:annotateClass>
>             
> <annox:annotateClass>@lombok.NoArgsConstructor</annox:annotateClass>
>         </jaxb:bindings>
>         <jaxb:bindings node="//xs:element" multiple="true" required="false">
>             <annox:annotate target="field">
>                 
> @org.eclipse.persistence.oxm.annotations.XmlNullPolicy(nullRepresentationForXml=
>                 XmlMarshalNullRepresentation.ABSENT_NODE, 
> xsiNilRepresentsNull=false)
>             </annox:annotate>
>         </jaxb:bindings>
>     </jaxb:bindings>
> </jaxb:bindings>
> {code}
>  
> Model class generation works fine, nullable properties are marked with 
> annotation:
> {code:java}
> @XmlNullPolicy(nullRepresentationForXml = 
> XmlMarshalNullRepresentation.ABSENT_NODE, xsiNilRepresentsNull = false){code}
> To start Moxy Runtime use the following settings in main method of 
> Application:
> {code:java}
>  System.setProperty("jakarta.xml.bind.JAXBContextFactory", 
> "org.eclipse.persistence.jaxb.JAXBContextFactory");{code}
>  
> I use this initialisation because I still need to use Spring Web Service 
> Client from Spring WS in parallel.
>  
> But on application startup I get errors:
> Caused by: java.lang.reflect.InvocationTargetException: null
>     at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native 
> Method) ~[na:na]
>     at 
> java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
>  ~[na:na]
>     at 
> java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
>  ~[na:na]
>     at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
>     at org.apache.cxf.common.jaxb.JAXBUtils$3.run(JAXBUtils.java:1189) 
> ~[cxf-core-4.0.0.jar:4.0.0]
>     at org.apache.cxf.common.jaxb.JAXBUtils$3.run(JAXBUtils.java:1183) 
> ~[cxf-core-4.0.0.jar:4.0.0]
>     at 
> java.base/java.security.AccessController.doPrivileged(AccessController.java:569)
>  ~[na:na]
>     at 
> org.apache.cxf.common.jaxb.JAXBUtils.createContext(JAXBUtils.java:1183) 
> ~[cxf-core-4.0.0.jar:4.0.0]
>     ... 64 common frames omitted
> Caused by: jakarta.xml.bind.JAXBException: Property 
> "eclipselink.default-target-namespace" is not supported.
>     at 
> org.glassfish.jaxb.runtime.v2.ContextFactory.createContext(ContextFactory.java:126)
>  ~[jaxb-runtime-4.0.1.jar:4.0.1 - a95cb76]
>     
> I have examined your code and found that you are using hard coded call to 
> "Class<?> factoryClass = 
> ClassLoaderUtils.loadClass("org.glassfish.jaxb.runtime.v2.ContextFactory" in 
> cxf-core org.apache.cxf.common.jaxb.JAXBUtils
> I have experimented a bit and if you can make a few changes in two classes 
> everything will work. The classes need to be changed:
> 1. org.apache.cxf.common.jaxb.JAXBContextCache Method 
> getCachedContextAndSchemas in lines 197 to 194 
>     old code
>  
> {code:java}
> if (defaultNs != null) {
>     if (HAS_MOXY){                 
>       map.put("eclipselink.default-target-namespace", defaultNs);             
>     
>     }
>     map.put("org.glassfish.jaxb.defaultNamespaceRemap", defaultNs);
> }
> {code}
>     new code
> {code:java}
> if (defaultNs != null){             
>    if (HAS_MOXY){                 
>       map.put("eclipselink.default-target-namespace", defaultNs);             
>    }
>    else{                 
>       map.put("org.glassfish.jaxb.defaultNamespaceRemap", defaultNs);         
>     
>    }
> }
> {code}
>         
> 2. org.apache.cxf.common.jaxb.JAXBUtils
>     
>     2.1 Method getPostfix in lines 1105 to 1117
>         old code:
> {code:java}
> private static String getPostfix(Class<?> cls) {
>    String className = cls.getName();
>    //TODO: review and remove "com.sun" package name check
>    if (className.contains("org.glassfish.jaxb") || 
> className.contains("com.sun.xml.bind")
>                         || className.startsWith("com.ibm.xml")){              
>        
>      return "";                 
>    }
>    else if (className.contains("com.sun.xml.internal")
>                         || className.contains("eclipse")){                    
>  
>      //eclipse moxy accepts sun package CharacterEscapeHandler                
>      
>       return ".internal";                 
>     }
>     return null;
>  }
> {code}
>         new code:    
> {code:java}
> private static String getPostfix(Class<?> cls) {
>     String className = cls.getName();
>     //TODO: review and remove "com.sun" package name check
>     if (className.contains("org.glassfish.jaxb") || 
> className.contains("com.sun.xml.bind")
>             || className.startsWith("com.ibm.xml") || 
> className.contains("eclipse")) {
>         //eclipse moxy 4.0 accepts glassfish package CharacterEscapeHandler 
> see const SUN_CHARACTER_ESCAPE_HANDLER
>         // Const in MOXY 4.0.1
>         // SUN_CHARACTER_ESCAPE_HANDLER= 
> "org.glassfish.jaxb.characterEscapeHandler";
>         // SUN_JSE_CHARACTER_ESCAPE_HANDLER = 
> "com.sun.xml.internal.bind.characterEscapeHandler";
>         // SUN_CHARACTER_ESCAPE_HANDLER_MARSHALLER = 
> "org.glassfish.jaxb.marshaller.CharacterEscapeHandler";
>         // SUN_JSE_CHARACTER_ESCAPE_HANDLER_MARSHALLER = 
> "com.sun.xml.internal.bind.marshaller.CharacterEscapeHandler"
>                     
>         // part of setProperty(String key, Object value) from Class 
> org.eclipse.persistence.jaxb. JAXBMarshaller
>                     
>         //        else if (SUN_CHARACTER_ESCAPE_HANDLER.equals(key) || 
> SUN_JSE_CHARACTER_ESCAPE_HANDLER.equals(key) || 
>         //                SUN_CHARACTER_ESCAPE_HANDLER_MARSHALLER.equals(key) 
> || 
>         //                
> SUN_JSE_CHARACTER_ESCAPE_HANDLER_MARSHALLER.equals(key)) {
>         //        if (value == null) {
>         //            xmlMarshaller.setCharacterEscapeHandler(null);
>         //        } else {
>         //            xmlMarshaller.setCharacterEscapeHandler(new 
> CharacterEscapeHandlerWrapper(value));
>         //        }
>                     
>         return "";
>     } else if (className.contains("com.sun.xml.internal")) {
>         return ".internal";
>     }
>     return null;
> }{code}
>             
>     2.2 Method createContext in lines 1179 to 1202
>         old code:    
> {code:java}
> public static JAXBContext createContext(final Set<Class<?>> classes,
>                                                 final Map<String, Object> 
> map) throws JAXBException {
>   JAXBContext ctx = null;
>   try {
>       ctx = AccessController.doPrivileged(new 
> PrivilegedExceptionAction<JAXBContext>() {
>           public JAXBContext run() throws Exception {    
>               //This is a workaround for CXF-8675                            
>               Class<?> factoryClass = 
> ClassLoaderUtils.loadClass("org.glassfish.jaxb.runtime.v2.ContextFactory",    
>  
>                         JAXBContextCache.class);                             
>               Method m = factoryClass.getMethod("createContext", 
> Class[].class, Map.class);               
>               Object context = m.invoke(null, classes.toArray(new 
> Class<?>[0]), map);                             
>               return (JAXBContext) context;                         
>           }
>       });
>   } catch (PrivilegedActionException e2) {
>       if (e2.getException() instanceof JAXBException){                        
>  
>           JAXBException ex = (JAXBException) e2.getException();               
>           
>           throw ex;                     
>       } else {                         
>           throw new RuntimeException(e2.getException());                     
>       }
>   }
>   return ctx;
> }
>         
> {code}
>         new code:
> {code:java}
> public static JAXBContext createContext(final Set<Class<?>> classes,
>                                             final Map<String, Object> map) 
> throws JAXBException {
>     JAXBContext ctx = null;
>     try {
>         ctx = AccessController.doPrivileged(new 
> PrivilegedExceptionAction<JAXBContext>() {
>            public JAXBContext run() throws Exception {                        
>      
>               String factoryClassName = 
> classNameFromSystemProperties("org.glassfish.jaxb.runtime.v2.ContextFactory");
>                              
>               //This is a workaround for CXF-8675                             
>               Class<?> factoryClass = 
> ClassLoaderUtils.loadClass(factoryClassName, JAXBContextCache.class);         
>                     
>               Method m = factoryClass.getMethod("createContext", 
> Class[].class, Map.class);                             
>               Object context = m.invoke(null, classes.toArray(new 
> Class<?>[0]), map);                             
>               return (JAXBContext) context;                         
>            }
>         });
>     } catch (PrivilegedActionException e2) {
>         if (e2.getException() instanceof JAXBException) {                     
>     
>             JAXBException ex = (JAXBException) e2.getException();             
>             
>             throw ex;                     
>         }
>         else{                         
>             throw new RuntimeException(e2.getException());                    
>  
>         }
>     }
>     return ctx;
> }
> private static String classNameFromSystemProperties(String defaultValue) 
> throws JAXBException {
>     String factoryClassName = 
> getSystemProperty(JAXBContext.JAXB_CONTEXT_FACTORY, defaultValue);
>     if (factoryClassName != null){                     
>         return factoryClassName;                 
>     }
>     return null;
> }
> private static String getSystemProperty(String property, String defaultValue) 
> {
>     String value = System.getProperty(property);
>     if (value != null){                     
>         return value;                 
>     }
>     else{                     
>         return defaultValue;                 
>     }
> }
> {code}
> With this Changes work for me fine, without Errors. Can you please check if 
> you can incorporate these changes into CXF-CORE.             
> If you have other possibilities to configure org.eclipse.persistence.moxy. 
> Can you please describe. 
> Thanks in advance
> Anderas Rusjaev
>  



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to