Question

I have web service:

@SchemaValidation
@WebService(endpointInterface = "myEndpoint",
            portName = "myPort", serviceName = "myService")
public class MyEndpointImpl implements MyEndpoint {

injected by spring to jetty with CXF:

<jaxws:endpoint
        id="myEndpoint"
        implementor="MyEndpointImpl"
        address="/myEndpoint"
        publishedEndpointUrl="http://000.000.00.215/endpoint">
    <jaxws:schemaLocations>
        <jaxws:schemaLocation>classpath:MyRequests.xsd</jaxws:schemaLocation>
    </jaxws:schemaLocations>
    <jaxws:properties>
        <entry key="schema-validation-enabled" value="true"/>
        <entry key="ws-security.bst.validator" value="org.apache.ws.security.validate.NoOpValidator"/>
    </jaxws:properties>
    <jaxws:inInterceptors>
        <ref bean="inbound-security"/>
        <ref bean="cryptoCoverageChecker"/>
    </jaxws:inInterceptors>
</jaxws:endpoint>

The xsd contains decimal type, java classes were generated with current xjc:

<xsd:element name="limitMin" type="xsd:decimal"/>
<xsd:element name="limitMax" type="xsd:decimal"/>

The service works, but I can see such log statements, which makes me nervous:

java.lang.InstantiationException: java.math.BigDecimal
Continuing ...
java.lang.RuntimeException: failed to evaluate: <unbound>=Class.new();

I googled some 10 years old Sun explanation and some workaround for JAXB:

PersistenceDelegate pd=encoder.getPersistenceDelegate(Integer.class);
encoder.setPersistenceDelegate(BigDecimal.class,pd );

But I cannot access it directly. What to do? Can I fix it somehow?

Was it helpful?

Solution

What looks like it's happening is that the marshaller tries to serialize BigDecimal by trying to call it's empty constructor.

But BigDecimal has no empty constructor, so the serialization mechanism catches the exception and goes on trying to serialize the BigDecimal in another way. According to the Oracle JAX-WS documentation:

A class must have either a public zero-argument constructor or a static zero-argument factory method in order to be mapped by this annotation. One of these methods is used during unmarshalling to create an instance of the class.

So the serialization process uses another way to convert the BigDecimal, such as calling a static factory method that it knows about, because we know the serialization eventually succeeds.

It is also possible to provide to JAXB our own static factory method, that does a custom conversion. That would prevent the attempt to call the empty constructor in the first place, have a look at this answer for an example.

But the message is a debugging message, so as the marshalling works fine it can then be safely ignored, by reducing the logging level of the marshaller.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top