[
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:
"@XmlNullPolicy(nullRepresentationForXml =
XmlMarshalNullRepresentation.ABSENT_NODE, xsiNilRepresentsNull = false)".
To start Moxy Runtime use the following settings in main method of Application:
System.setProperty("jakarta.xml.bind.JAXBContextFactory",
"org.eclipse.persistence.jaxb.JAXBContextFactory");
I use this initialisation because I still need to use Spring Web Service Client
from Spring WS in parallel.
But on 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
if (defaultNs != null) {
if (HAS_MOXY) \{
map.put("eclipselink.default-target-namespace", defaultNs); }
else
{ map.put("org.glassfish.jaxb.defaultNamespaceRemap",
defaultNs); }
}
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}
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:
<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>
Binding file has the following configuration:
<?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>
Model class generation works fine, nullable properties are marked with
annotation:
"@XmlNullPolicy(nullRepresentationForXml =
XmlMarshalNullRepresentation.ABSENT_NODE, xsiNilRepresentsNull = false)".
To start Moxy Runtime use the following settings in main method of Application:
System.setProperty("jakarta.xml.bind.JAXBContextFactory",
"org.eclipse.persistence.jaxb.JAXBContextFactory");
I use this initialisation because I still need to use Spring Web Service Client
from Spring WS in parallel.
But on 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
if (defaultNs != null) {
if (HAS_MOXY) {
map.put("eclipselink.default-target-namespace", defaultNs);
}
map.put("org.glassfish.jaxb.defaultNamespaceRemap", defaultNs);
}
new code
if (defaultNs != null) {
if (HAS_MOXY) {
map.put("eclipselink.default-target-namespace", defaultNs);
} else {
map.put("org.glassfish.jaxb.defaultNamespaceRemap", defaultNs);
}
}
2. org.apache.cxf.common.jaxb.JAXBUtils
2.1 Method getPostfix in lines 1105 to 1117
old code:
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;
}
new code:
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;
}
2.2 Method createContext in lines 1179 to 1202
old code:
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;
}
new code:
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;
}
}
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:
> "@XmlNullPolicy(nullRepresentationForXml =
> XmlMarshalNullRepresentation.ABSENT_NODE, xsiNilRepresentsNull = false)".
> To start Moxy Runtime use the following settings in main method of
> Application:
> System.setProperty("jakarta.xml.bind.JAXBContextFactory",
> "org.eclipse.persistence.jaxb.JAXBContextFactory");
>
> I use this initialisation because I still need to use Spring Web Service
> Client from Spring WS in parallel.
>
> But on 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
> if (defaultNs != null) {
> if (HAS_MOXY) \{
> map.put("eclipselink.default-target-namespace", defaultNs); }
> else
> { map.put("org.glassfish.jaxb.defaultNamespaceRemap",
> defaultNs); }
> }
>
> 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}
>
> 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)