Configure CXF JAX-WS service to work with MOXY - jaxb

Although I've added a jaxb.properties with MOXY factory and I see that the JAXB was switched to moxy, CXF has a method named createRIContext in the JAXBUtils class which loads hard coded the sun JAXB implementation.
Is there a way to override it and use moxy instead?
The problematic code is the following:
// fall back if we're using another jaxb implementation
try {
riContext = JAXBUtils.createRIContext(contextClasses
.toArray(new Class[contextClasses.size()]), tns);
}
It loads hard coded the "com.sun.xml.bind.v2.ContextFactory" class and use it to create a JAXB context.

The 3.0.0-milestone2 version of CXF should handle Moxy quite a bit better. That said, there are still bugs in Moxy that have prevented all of the CXF unit and system tests to pass with it so we don't have the same level of confidence with Moxy as we do with the JAXB RI.
(any help with testing 3.0.0 would be greatly appreciated)

Related

The method getRootLogger() is undefined for the type Logger migration from Log4j 1.x to 2.x

I’m remediating from log4j1.x to Log4j2.x and trying to convert below to Lg4j2.x compatible.
Actually below code is used in Test cases
#Mock
private AppenderSkeleton appender;
Logger.getRootLogger().addAppender(appender);
I went through suggestions like
Dynamically add appender with slf4j and log4j2
How to add Log4J2 appenders at runtime programmatically?
I change like below
LogManager.getRootLogger().addAppender(appender);
But I am not able to find the replacement of addAppender(appender);
But its actually should be working, that's why issue.

How can I disable Grails createLink codec (encoding)?

Updated Grails from 2.2.0 to 2.2.4.
Before: http://localhost:8180/sub:favorites
After: http://localhost:8180/sub%3Afavorites
As you can see Grails encodes URL's params by default. How can I disable it and encode it manually?
Chances are high that there is an easier way. But if there isn't you can do the following:
Grails registeres a bean named grailsLinkGenerator. This bean is used for creating links (createLink(..) or <g:createLink />) within the the application. I think the default implementation is a CachingLinkGenerator which is a subclass of DefaultLinkGenerator which again implements the interface LinkGenerator.
You could extend one of these classes and override the bean in resources.groovy:
grailsLinkGenerator(YourLinkGenerator) {
..
}

Jersey 2 - JAXB

Using Jersey 2 m13-3 in Tomcat 7, I'm trying to post XML and have JAXB automatically unmarshal it.
My method signature is something like:
#POST
#Consumes(MediaType.APPLICATION_XML)
#Produces( {"text/xml"})
public Response setFoo(
myXJC.generatedclass.Foo foo
)
I get a 400 bad request, but no exception (that I can find).
Testing with:
#POST
#Consumes(MediaType.APPLICATION_XML)
#Produces( {"text/xml"})
public Response setFoo() { ... }
I'm confident this method is being invoked in response to a request.
But as soon as I add arg myXJC.generatedclass.Foo, it isn't.
Do I need something special in my class which extends javax.ws.rs.core.Application to use JAXB? Something ResourceConfig related perhaps? Any extra jersey specific jars?
I see there is a jersey-media-moxy. I'd be happy to get it working with MOXy, but ideally it would also work with Sun/Oracle JAXB.
I've had a look at the source code of:
<dependency>
<groupId>org.glassfish.jersey.examples</groupId>
<artifactId>jaxb</artifactId>
<version>2.0-m13-3</version>
</dependency>
but I'm still having trouble.
Turns out that when I generated the classes from my XSD using XJC, I'd left an incorrect target namespace in there.
The XML I was posting was not namespace qualified, but the generated classes were expecting a namespace.
Once I fixed this, things worked fine.

Jaxb Xjc: make generated classes subtype of Exception?

How is it possible to make some xjc generated classes subclasses of a custom Exception, such that you can actually throw them, and processable by the JAXBContext? Often webservices return various faults defined that really should be an exception, but since they aren't you need to wrap them unneccesarily.
Even if you could create a JAXB (JSR-222) model that extended from Exception you wouldn't be able to create a JAXBContext from it. I would recommend wrapping the Exception in a domain model that is compatible with JAXB.
Java Model (Foo)
Below is a simple Java class that extends Exception.
package forum12840627;
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement
public class Foo extends Exception {
}
Demo
The demo code below attempts to creates a JAXBContext on the Java model.
package forum12840627;
import javax.xml.bind.JAXBContext;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Foo.class);
}
}
Output
Below is the exception returned from running the demo code. The problem is that Exception is not a valid JAXB class and JAXB implementations pull in the super classes as it processes the Java model. (Note: In your own domain model you can annotate super classes with #XmlTransient to prevent them from being processed: http://blog.bdoughan.com/2011/06/ignoring-inheritance-with-xmltransient.html)
Exception in thread "main" com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions
java.lang.StackTraceElement does not have a no-arg default constructor.
this problem is related to the following location:
at java.lang.StackTraceElement
at public java.lang.StackTraceElement[] java.lang.Throwable.getStackTrace()
at java.lang.Throwable
at java.lang.Exception
at forum12840627.Foo
at com.sun.xml.bind.v2.runtime.IllegalAnnotationsException$Builder.check(IllegalAnnotationsException.java:102)
at com.sun.xml.bind.v2.runtime.JAXBContextImpl.getTypeInfoSet(JAXBContextImpl.java:472)
at com.sun.xml.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:302)
at com.sun.xml.bind.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(JAXBContextImpl.java:1140)
at com.sun.xml.bind.v2.ContextFactory.createContext(ContextFactory.java:154)
at com.sun.xml.bind.v2.ContextFactory.createContext(ContextFactory.java:121)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:202)
at javax.xml.bind.ContextFinder.find(ContextFinder.java:363)
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:574)
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:522)
at forum12840627.Demo.main(Demo.java:8)
UPDATE #1
If you are using EclipseLink JAXB (MOXy) as your JAXB provider then you will not see this exception as classes in the javax.* and java.* packages are not treated as domain classes. MOXy is the default JAXB provider in the WebLogic 12c environment or can be configured using a jaxb.properties file.
For More Information
http://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-as-your.html
http://blog.bdoughan.com/2011/12/eclipselink-moxy-is-jaxb-provider-in.html
UPDATE #2
The latest versions of the JAXB reference implementation appear to handle this use case now as well as MOXy. My original portability concerns may not be so much of an issue.
Yeah, I finally found something! The Inheritance plugin is able to make the generated classes inherit from classes or implement additional interfaces.
You need to include something like
<bindings node="//xsd:complexType[#name='WhateverException']">
<inheritance:extends>foo.bar.WhateverException</inheritance:extends>
</bindings>
into the binding file and override getStackTrace() to return null such that it doesn't get marshalled.
Unfortunately you might run into trouble with some JAXB implementations (see Blaise Doughan's answer) - I haven't found a workaround for that yet. So you can either use a not quite nonportable solution, or wrap the JAXB objects into Exceptions.

JSF 2 checkboxes and boolean getters

I'm generating a jaxws client based on webservice. Jaxb will generate booleans using the java.lang.Boolean instead of the primitive type. In addition to this, it will generate the is() naming convention for beans.
However if I try to link the boolean (e.g. isOptional()) to a checkbox, it will throw the following exception:
value="#{property.optional}": Property 'optional' not readable on type java.lang.Boolean
My google skills have informed me that jsf works fine with:
boolean isOptional()
boolean getOptional()
Boolean getOptional()
But not with
Boolean isOptional()
However it is not feasible to update the beans manually due to the size and amount of the webservices, so is there any way to make jsf use the java.lang.Boolean isOptional() properly? Or can I somehow define a property in the jaxb bindings file at generation time which magically generates "getOptional()"?
On a sidenote, the following does work:
<h:selectBooleanCheckbox value="#{property.isOptional()}"/>
However I can't actually update the value presumably because it can't find the setter.
EDIT: I'm running the latest jdk 7, the output of "java -version":
java version "1.7.0_05"
Java(TM) SE Runtime Environment (build 1.7.0_05-b05)
Java HotSpot(TM) Client VM (build 23.1-b03, mixed mode, sharing)
The output of "wsimport -version":
JAX-WS RI 2.2.4-b01
Generated code:
public Boolean isOptional() {
return optional;
}
Jaxb will generate booleans using the java.lang.Boolean instead of the primitive type. In addition to this, it will generate the is() naming convention for beans.
Using the is getter prefix for java.lang.Boolean was a known major mistake of JAXB. It has been fixed in version 2.1.13 which was released April 2010 already. Keep your libraries up to date.
See also this blog article for some background.
The Great JAXB API Blunder
September 15, 2006
You've got to hand it to Sun for screwing this one up. It's one thing to write software that doesn't adhere to a specification when the documentation is as thick as a textbook. Take, for example, just about anything created by the W3C. However, it's really bad when it is your own spec that you can't follow, especially when it is the most well known part of it. That's right, Sun missed by a mile on their own spec when they created the JAXB 2.0 API. The JAXB 2.0 compiler (XJC) incorrectly uses the prefix "is" rather than "get" when generating the getter method for a java.lang.Boolean property. While the JavaBean spec states that read methods for primitive booleans can use the alternate "is" prefix, this flexibility does not extend to its boolean wrapper counterpart.
8.3.2 Boolean Properties
In addition, for boolean properties, we allow a getter method to match the pattern:
public boolean is();
This "is" method may be provided instead of a "get" method, or it may be provided in addition to a "get" method. In either case, if the "is" method is present for a boolean property then we will use the "is" method to read the property value.
An example boolean property might be:
public boolean isMarsupial();
public void setMarsupial(boolean m);
Given that JAXB is a code generation framework, and the idea behind code generation frameworks is that the code is to be used "as is" and not modified thereafter, this is a pretty big "oops". While this issue has been reported, the response from Sun is "sorry, its too late".
This behavior is governed by the spec, and unfortunately it's just too late for the spec to change now.
In terms of the user experience, thanks to auto-boxing, I don't think this will be a real issue for people. Is the problem that you are using Introspector and it's missing the property?
Too late? Not a real issue? It's BROKEN. FIX IT! I also don't like the naive statement that it probably won't affect frameworks. Um, yes it will, considering other projects did happen to adhere to the spec (hibernate, spring, myfaces, etc.)
UPDATE: Stevo Slavic informed me that this has been fixed in JAXB 2.1.13. See JAXB-131 for details. Yeah!
JSF/EL is not at fault here. It's doing its job properly conform the JavaBeans spec.
I'm not sure why the latest and greatest JAXB version still generates the wrong method but I finally fixed it by adding "-B-enableIntrospection" (as per http://jaxb.java.net/2.2.4/docs/xjc.html) to the wsimport call. This results in:
public Boolean getOptional() {
return optional;
}

Resources