# [Tomcat 5.5 / Axis] WebServiceClient - NumberFormatException



## Krabat (2. Nov 2005)

Mittlerweile habe ich einen WebService zum laufen bekommen, die Daten / Rückgabewerte stimmen auch, leider nur im browser. Wenn ich einen WebService Client testweise schreibe, bekomme ich beim Ausführen eine NumberFormatException. Was mache ich noch falsch?

Was an Information noch ganz interessant sein könnte: der WebService läuft zwar unter Tomcat v5.5 / Axis, aber den Client generiere ich mittels suns wscompile, was bisher stets funktionierte und auch funktionieren sollte, da der client doch unabhängig von der verwendeten Service Technik sein sollte.


Folgendes Interface:

```
package de.qsgrimm.webservice.test;

import java.rmi.Remote;
import java.rmi.RemoteException;
//import java.util.Calendar;
//import java.util.GregorianCalendar;


public interface HelloIF extends Remote {

    public String sayHello(String s) throws RemoteException;
    
    public int getDate() throws RemoteException;
    
    public int getDbResult() throws RemoteException;
}
```


Mein Client Programm:

```
package staticstub;

import javax.xml.rpc.Stub; 
import de.qsgrimm.webservice.test.*;
 

public class HelloClient {
    private final static String ENDPOINT = 
    	"http://localhost:8080/axis/services/pminfo";
//    	"http://localhost:8080/webservice/pminfo";
//    	"http://localhost:8080/qsg_pkg/pminfo";

    public static void main(String[] args) {
    	System.out.println("Endpoint address = " + ENDPOINT);

        try {
            Stub stub = createProxy();

            stub._setProperty(javax.xml.rpc.Stub.ENDPOINT_ADDRESS_PROPERTY,
                ENDPOINT);

            HelloImpl hello = (HelloImpl) stub;

            System.out.println(hello.sayHello("Duke!"));
            System.out.println("--------------------");
            Integer it = new Integer((int)hello.getDbResult());
            System.out.println("getDbResult= "+it.toString());
        } catch (Exception ex) {
        	System.err.println("*ERROR* caught!");
            ex.printStackTrace(); 
        }
    }

    private static Stub createProxy() {
        // Note: MyHelloService_Impl is implementation-specific. 
        return (Stub) (new HelloImplService_Impl().getPminfo()); 
    }
}
```


Exception:

```
Endpoint address = [url]http://localhost:8080/axis/services/pminfo[/url]
Hello Duke!
--------------------
*ERROR* caught!
java.rmi.RemoteException: Runtime exception; nested exception is: 
	Fehler beim Aufheben der Serialisierung: java.lang.NumberFormatException: For input string: ""
	at com.sun.xml.rpc.client.StreamingSender._handleRuntimeExceptionInSend(StreamingSender.java:318)
	at com.sun.xml.rpc.client.StreamingSender._send(StreamingSender.java:300)
	at de.qsgrimm.webservice.test.HelloImpl_Stub.getDbResult(HelloImpl_Stub.java:69)
	at staticstub.HelloClient.main(HelloClient.java:61)
Caused by: Fehler beim Aufheben der Serialisierung: java.lang.NumberFormatException: For input string: ""
	at com.sun.xml.rpc.encoding.SimpleTypeSerializer.deserialize(SimpleTypeSerializer.java:154)
	at de.qsgrimm.webservice.test.HelloImpl_getDbResult_ResponseStruct_SOAPSerializer.doDeserialize(HelloImpl_getDbResult_ResponseStruct_SOAPSerializer.java:42)
	at com.sun.xml.rpc.encoding.ObjectSerializerBase.deserialize(ObjectSerializerBase.java:192)
	at com.sun.xml.rpc.encoding.ReferenceableSerializerImpl.deserialize(ReferenceableSerializerImpl.java:155)
	at de.qsgrimm.webservice.test.HelloImpl_Stub._deserialize_getDbResult(HelloImpl_Stub.java:224)
	at de.qsgrimm.webservice.test.HelloImpl_Stub._readFirstBodyElement(HelloImpl_Stub.java:205)
	at com.sun.xml.rpc.client.StreamingSender._send(StreamingSender.java:215)
	... 2 more
```


----------



## Bleiglanz (2. Nov 2005)

```
Integer it = new Integer((int)hello.getDbResult());
```
seltsamer Code 

btw scheint der server gar kein int zu senden, sondern "", was der erzeugte stub natürlich nicht int ein int deserialisieren kann?

also liegt der Fehler eher beim Endpoint...


----------



## Krabat (2. Nov 2005)

Bleiglanz hat gesagt.:
			
		

> ```
> Integer it = new Integer((int)hello.getDbResult());
> ```
> seltsamer Code



Stimmt, das _int_ muss natürlich weg, hatte den Aufruf erst direkt in der _System.out._ Anweisung drin, wollte dann nochmal sichergehen, daß die richtigen Typen genommen werden.



			
				Bleiglanz hat gesagt.:
			
		

> btw scheint der server gar kein int zu senden, sondern "", was der erzeugte stub natürlich nicht int ein int deserialisieren kann? also liegt der Fehler eher beim Endpoint...



hmm... das ist allerdings eigenartig, da beim Aufruf im Browser von...

```
http://localhost:8080/axis/services/pminfo?method=getDbResult
```

...eine xml Ausgabe geliefert wird, die ein int Ergebnis besitzt:

```
<soapenv:Envelope>
	<soapenv:Body>

	<getDbResultResponse soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<getDbResultReturn href="#id0"/>
</getDbResultResponse>
<multiRef id="id0" soapenc:root="0" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="xsd:int">257</multiRef>
</soapenv:Body>
</soapenv:Envelope>
```

Das erwartete Ergebnis ist die *257*.

[edit: mehr infos...]


----------



## Bleiglanz (2. Nov 2005)

beobachte mal das ganze auf TCP/IP Ebene 

```
java org.apache.axis.utils.tcpmon
```

ist natürlich eigentlich strange, wenn du den Stub von einem anderen Tool erzeugen lässt als den Endpunkt (und noch dazu von einem normalen Interface ausgehst)

hast du die Client-Stubs aus dem Java-Interface generiert (schlecht) oder das von Axis gelieferte WSDL (besser)??


----------



## Krabat (2. Nov 2005)

Bleiglanz hat gesagt.:
			
		

> hast du die Client-Stubs aus dem Java-Interface generiert (schlecht) oder das von Axis gelieferte WSDL (besser)??



Ich habe das WSDL benutzt. Dem WSCOMPILE gibt man eine config Datei mit (config-wsdl.xml), die den Ort der WSDL Datei enthält: _http://localhost:8080/axis/services/pminfo?WSDL_




			
				Bleiglanz hat gesagt.:
			
		

> ist natürlich eigentlich strange, wenn du den Stub von einem anderen Tool erzeugen lässt als den Endpunkt...



hmm... ich bin bisher davon ausgegangen, daß es egal sei. Der WebService kann auch unter .NET entstanden sein und trotzdem kann ich einen passenden java client schreiben, ohne .NET zu integrieren, oder habe ich da etwas falsch aufgefasst?




			
				Bleiglanz hat gesagt.:
			
		

> beobachte mal das ganze auf TCP/IP Ebene



Danke für den Tipp, das schaue ich mir jetzt an.


----------



## Krabat (2. Nov 2005)

Habe mir das ganze unter TCPMon angeschaut, aber bin mir noch immer ein bischen unsicher, wie die Ergebnisse richtig zu interpretieren sind.

Die Anfrage:

```
POST /axis/services/pminfo HTTP/1.1
Content-Type: text/xml; charset=utf-8
Content-Length: 523
SOAPAction: ""
User-Agent: Java/1.5.0_05
Host: 127.0.0.1:8081
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: keep-alive

<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" 
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:enc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns0="http://test.webservice.qsgrimm.de" 
xmlns:ns1="http://localhost:8080/axis/services/pminfo" 
env:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><env:Body><ns0:sayHello>
<s xsi:type="enc:string">Duke!</s></ns0:sayHello></env:Body></env:Envelope>POST /axis/services/pminfo 
HTTP/1.1
Content-Type: text/xml; charset=utf-8
Content-Length: 478
SOAPAction: ""
User-Agent: Java/1.5.0_05
Host: localhost:8081
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: keep-alive

<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" 
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:enc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns0="http://test.webservice.qsgrimm.de" 
xmlns:ns1="http://localhost:8080/axis/services/pminfo" 
env:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><env:Body><ns0:getDbResult/>
</env:Body></env:Envelope>
```


Die Antwort:

```
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-Type: text/xml;charset=utf-8
Transfer-Encoding: chunked
Date: Wed, 02 Nov 2005 13:06:29 GMT

222
<?xml version="1.0" encoding="utf-8"?><soapenv:Envelope 
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><soapenv:Body><ns1:sayHelloResponse 
soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" 
xmlns:ns1="http://test.webservice.qsgrimm.de"><sayHelloReturn xsi:type="soapenc:string" 
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">Hello 
Duke!</sayHelloReturn></ns1:sayHelloResponse></soapenv:Body></soapenv:Envelope>
0

HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-Type: text/xml;charset=utf-8
Transfer-Encoding: chunked
Date: Wed, 02 Nov 2005 13:06:31 GMT

289
<?xml version="1.0" encoding="utf-8"?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><soapenv:Body><ns1:getDbResultResponse 
soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" 
xmlns:ns1="http://test.webservice.qsgrimm.de"><getDbResultReturn 
href="#id0"/></ns1:getDbResultResponse><multiRef id="id0" soapenc:root="0" 
soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="xsd:int" 
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">257</multiRef></soapenv:Body>
</soapenv:Envelope>
0
```

Auffällig sind meiner Meinung nach zwei Dinge, zum einen ist der Inhalt der _SOAPAction: ""_ leer (muss das so sein?), zum anderen wird das richtige Ergebnis geliefert: "257". Komisch...


[edit: Formatierung]


----------



## Bleiglanz (2. Nov 2005)

> hmm... ich bin bisher davon ausgegangen, daß es egal sei. Der WebService kann auch unter .NET entstanden sein und trotzdem kann ich einen passenden java client schreiben, ohne .NET zu integrieren, oder habe ich da etwas falsch aufgefasst?


ja, du bist auf die Werbung reingefallen 

das funktioniert natürlich schon so, aber es gibt eben auch fundamentale Unterschiede zwischen den Sprachen, die man durch den Einsatz von WSDL nicht so einfach auflösen kann


----------



## Bleiglanz (2. Nov 2005)

funktioniert eigentlich der erste Teil

System.out.println(hello.sayHello("Duke!")); // kommt das?


----------



## Krabat (2. Nov 2005)

Bleiglanz hat gesagt.:
			
		

> das funktioniert natürlich schon so, aber es gibt eben auch fundamentale Unterschiede zwischen den Sprachen, die man durch den Einsatz von WSDL nicht so einfach auflösen kann



Die Limitation besteht doch darin, daß primär nur einige wenige Basis-Datentypen eingesetzt werden können, die zB. durch JAX-RPC in definierte XML/WSDL Basistypen umgewandelt werden. So sollte genauso wie bei Java JAX-RPC (http://java.sun.com/j2ee/1.4/docs/tutorial/doc/JAXRPC4.html#wp130550) eine Umwandlung genauso in anderen Sprachen vorgenommen werden, oder?

Zurück zu meinem eigentlichen Problem: Kann es sein, daß die Kodierung/Dekodierung durch verschiedene Bibliotheken entsteht? Leider kenne ich mich zu wenig aus, um genau sagen zu können, welche lib jeweils genau zum Einsatz kommt...


----------



## Krabat (2. Nov 2005)

Bleiglanz hat gesagt.:
			
		

> funktioniert eigentlich der erste Teil
> 
> System.out.println(hello.sayHello("Duke!")); // kommt das?



Doch das funktioniert... 

```
Endpoint address = [url]http://localhost:8080/axis/services/pminfo[/url]
Hello Duke!
--------------------
*ERROR* caught! ...
```

Das ist eben, was mich so verwundert...
Mit dem DB Zugriff dürfte es eigentlich nichts zu tun haben, oder? wenn der browser das richtige Ergebnis liefert?


----------



## Krabat (3. Nov 2005)

So, um das Problem besser einkreisen zu können, habe ich den client mittels Axis WSDL2Java generiert und damit funktioniert es eigenartigerweise einwandfrei. Sieht so aus, als müßte ich Dir, Bleiglanz doch recht geben. 
Gibt es da soo große Unterschiede? 
D.h. wenn ich meinen WebService mal veröffentliche, muß ich stets dazu angeben, womit der client generiert werden muss... grmpf! Ist irgendwie "unschön".


----------



## Bleiglanz (3. Nov 2005)

na ja, bei ints und strings sollte das schon passen

vergleich mal die konfituration von axis/wscompile sofern du was eingestellt hast (und welche Defaultwerte diese Tools verwenden)

-> lieber "Document/Literal" beim Encoding
-> Namespaces
-> usw.


----------

