Scorpio
Scorpio

Reputation: 2327

Error when starting up cxf client for xsd containing xmldsig

We're currently developing a webservive containing a 3rd party XSD. This 3rd party XSD contains a digital signature (importing the http://www.w3.org/2000/09/xmldsig# XSD).

The architecture has 2 major functionalities:

  1. our Webservice accepts messages as per the 3rd party XSD contract
  2. we forward some of these messages to another (also 3rd party) webservice via a small client

1) works perfectly, there are no issues involving the signature here.

2) is the odd one. As long as the signature-element

<xs:element ref="sig:Signature" minOccurs="0" maxOccurs="1"/>

is present, the software will not startup, and instead crash with this errormessage:

Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [net.eucaris.services.GenericServiceSoap]: Factory method 'genericServiceSoap' threw exception; nested exception is java.lang.IllegalArgumentException: can't parse argument number: ''{0}'' at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:189) [spring-beans-4.3.8.RELEASE.jar:4.3.8.RELEASE] at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:588) [spring-beans-4.3.8.RELEASE.jar:4.3.8.RELEASE] ... 38 more Caused by: java.lang.IllegalArgumentException: can't parse argument number: ''{0}'' at java.text.MessageFormat.makeFormat(MessageFormat.java:1429) [rt.jar:1.8.0_131] at java.text.MessageFormat.applyPattern(MessageFormat.java:479) [rt.jar:1.8.0_131] at java.text.MessageFormat.(MessageFormat.java:362) [rt.jar:1.8.0_131] at java.text.MessageFormat.format(MessageFormat.java:840) [rt.jar:1.8.0_131] at com.sun.xml.bind.v2.model.impl.Messages.format(Messages.java:132) [jaxb-impl-2.2.11.jar:2.2.11]

I traced it down to the generated files, to be precise the porttype-interface:

@WebService(targetNamespace = "http://services.eucaris.net/", name = "GenericServiceSoap")
@XmlSeeAlso({org.w3._2000._09.xmldsig_.ObjectFactory.class, ObjectFactory.class})
public interface GenericServiceSoap {
...

As long as the xmldsig-ObjectFactory is referenced here, the system crashes. Once its out, everything works fine (well, until someone sends a signature, which then cannot be recognized).

Digging deeper (ie, debugging) leads me to this information:

The exception is thrown in this piece of code (java.text.MessageFormat, from line 1415, jdk 1.8.131)

 private void makeFormat(int position, int offsetNumber,
                            StringBuilder[] textSegments)
    {
        String[] segments = new String[textSegments.length];
        for (int i = 0; i < textSegments.length; i++) {
            StringBuilder oneseg = textSegments[i];
            segments[i] = (oneseg != null) ? oneseg.toString() : "";
        }

        // get the argument number
        int argumentNumber;
        try {
            argumentNumber = Integer.parseInt(segments[SEG_INDEX]); // always unlocalized!
        } catch (NumberFormatException e) {
            throw new IllegalArgumentException("can't parse argument number: "
                                               + segments[SEG_INDEX], e);
        }

The method parameters are 73, 0, and a StringBuilder containing this data:

[Es ist keine ObjectFactory mit @XmlElementDecl für das Element ', ''{0}'', null, null]

This indicates, that somehow, somewhere, this StringBuffer is filled wrong, as the method clearly expects a number. ''{0}'' kinda looks like a placeholder. In itself, the application tries to raise an error or at least a warning, considering the content of the message.

More info:

We're using CXF 3.1.11 with Spring 4.3.8. We're generating code from the wsdl and xsd files. The client is created via

@Bean
public GenericServiceSoap genericServiceSoap() {
    final JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
    factory.setAddress(http://example.com);
    factory.setServiceClass(GenericServiceSoap.class);
    factory.setInInterceptors(createInInterceptors());
    factory.setOutInterceptors(createOutInterceptors());
    return (GenericServiceSoap) factory.create();
}

The signature generates this piece of code, which looks fine to me:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "SignatureType", propOrder = {
    "signedInfo",
    "signatureValue",
    "keyInfo",
    "objects"
})
@XmlRootElement(name = "Signature")
public class Signature implements Serializable
{

    private final static Long serialVersionUID = 5363422069410258353L;
    @XmlElement(name = "SignedInfo", required = true)
    @NotNull
    protected SignedInfo signedInfo;
    @XmlElement(name = "SignatureValue", required = true)
    @NotNull
    protected SignatureValue signatureValue;
    @XmlElement(name = "KeyInfo")
    protected KeyInfo keyInfo;
    @XmlElement(name = "Object")
    protected List<org.w3._2000._09.xmldsig_.Object> objects;
    @XmlAttribute(name = "Id")
    @XmlJavaTypeAdapter(CollapsedStringAdapter.class)
    @XmlID
    @XmlSchemaType(name = "ID")
    @Pattern(regexp = "[\\i-[:]][\\c-[:]]*")
    protected String id;
    // getters/setters omitted

I just don't get how or why this happens. Or am I running into a bug here?

Upvotes: 0

Views: 894

Answers (1)

Scorpio
Scorpio

Reputation: 2327

The main problem was an instance of

com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions Two classes have the same XML type name "xxx". Use @XmlType.name and @XmlType.namespace

That problem was solved.

As to why this error was mangled deep inside of the framework instead of clearly given out, I have no clue. I've seen the error before, once it was known it was clear what to do. Maybe there is a bug somewhere in there, who knows.

Upvotes: 0

Related Questions