Apr 23 2009
Java client and WCF server
WCF’s fundamental communication mechanism is SOAP-based Web services. Because WCF implements Web services technologies defined by the WS-* specifications, other software which is based on SOAP and supports WS-* specifications can communicate with the WCF-based applications.
To build up a cross-platform WCF server, you can use Metro. Metro is a Web Services framework that provides tools and infrastructure to develop Web Services solutions for the end users and middleware developers. It depends on Java programming language. The latest version of Metro is 1.4.
In the development process of SCM Anywhere (a SCM tool, with fully integrated version control, Issue Tracking and Build Automation, developed with WCF and METRO/WSIT), we found that METRO is NOT as mature as WCF. There are lots of small issues in METRO/WSIT. Luckily, METRO is an open source project and keeps evolving all the time. Our experience is that if you find some features are not working properly in METRO, keep downloading the latest version from Java.net. Several weeks later, you may discover that the features are working properly.
To implement a Java client to communicate with the WCF server, you can follow the steps below:
1. Download METRO/WSIT from the home page of Metro: https://metro.dev.java.net.
2. Download Eclipse. We use Eclipse + Metro to develop Dynamsoft SCM Anywhere.
3. Install Metro by executing the command: java –jar metro-1_4.jar. The installation folder of Metro contains some documents, tools and samples. You can find the documents in the “docs” folder.
4. Use the C# project “WcfService1″ (provided in my WCF client and WCF service article) as the WCF server. Go to Property of the WCF project, and set the server port to one that is not occupied by other services. Here we used 8888 for example. In the “web.config” file, change the string “wsHttpBinding” to “basicHttpBinding”.

5. This is the key step. We use the wsimport tool included in Metro to generate the Java client code. Create a file named “service1.xml” and copy the following code to the file:
<bindings
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
wsdlLocaption="http://localhost:8888/Service1.svc?wsdl"
xmlns="http://java.sun.com/xml/ns/jaxws">
<bindings node="wsdl:definitions">
<enableAsyncMapping>true</enableAsyncMapping>
</bindings>
</bindings>
The parameter “enableAsyncMapping” means generating the asynchronous method communicating to WCF server. Save this file, and execute the following command:
bin\wsimport -extension -keep -Xnocompile -b TestService.xml http://localhost:8888/Service1.svc?wsdl
Then you can find two new directories in Metro folder: “org” and “com”. They are the generated Java code.
6. Open Eclipse IDE, create a new Java project named “SimpleWCFClient”, and copy the two new directories “org” and “com” to the “src” folder of the project. Refresh the project, and you can find that some new code files are in the project.
7. Create a test class named “WCFTest” and write the following code to the file:
import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.ws.BindingProvider;
import org.tempuri.IService1;
import org.tempuri.Service1;
public class WCFTest {
public static void main(String[] strArgs)
{
try
{
Service1 service1 = new Service1(new URL("http://localhost:8888/Service1.svc?wsdl"), new QName("http://tempuri.org/", "Service1"));
IService1 port = service1.getBasicHttpBindingIService1();
((BindingProvider)port).getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, "http://localhost:8888/Service1.svc");
int input = 100;
String strOutput = port.getData(input);
System.out.println(strOutput);
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
8. Four .jar files need to be added to the Java project. You can get these files in the “lib” folder of Metro: webservices-api.jar, webservices-extra.jar, webservices-extra-api.jar, webservices-rt.jar. Then go to Property of the project and add these jars to the project.
9. Compile and run the Java project. If the Eclipse console outputs “You entered: 100″, congratulations, you are successful.
You can download these code from here. When you are familiar with these, you will find it’s very convenient to write a Java application communicating with a WCF client.
Links:
Previous article >>>>: WCF client and WCF service
Next article >>>>: Data types between Java and WCF
WCF & Java Interop series home page: WCF & Java Interop
26 Responses to “Java client and WCF server”
I have implemented both the VWD Server/Client and the WCF Server/Java Client schemes. The first one works just fine, as I stated before. However, with the second I have run into a big problem. My Java client runs into a “Permission denied: connect.” wall when attempting to access the WSDL. I thought that, since I am running under Vista (6SP1) that perhaps it was UAC that was causing the problem, but that is not it. Nor was it a binding mismatch. I think that because the Java side is coming in through a remote socket that Windows authentication is blocking the access. Perhaps you have some suggestions as to how to get around this?
Here is something interesting. I imported the Eclipse project into Netbeans 6.5.1 and it ran perfectly. So the problem is with Eclipse.
It is possible to use javax.xml.ws.Dispatch to communicating with WCF Service?
How would you create a java client when you have a WCF service running on net tcp binding.
Thanks for this really good Tutorial. I am having some issue right now. I am able to generate the proxy classes following your step.
Problem 1: All the strings in Method are JAXBElement
Solution i have found so far is using this bind.xml file instead of yours
Is there any way i can combine both of yours and this one?
Problem 2: I am getting NullPointerException, when execution client code..It occurs in the first line in Main function.
Exception:
java.lang.NullPointerException
at com.sun.xml.ws.model.wsdl.WSDLOperationImpl.freez(WSDLOperationImpl.java:147)
at com.sun.xml.ws.model.wsdl.WSDLPortTypeImpl.freeze(WSDLPortTypeImpl.java:91)
at com.sun.xml.ws.model.wsdl.WSDLBoundPortTypeImpl.freeze(WSDLBoundPortTypeImpl.java:215)
at com.sun.xml.ws.model.wsdl.WSDLModelImpl.freeze(WSDLModelImpl.java:241)
at com.sun.xml.ws.wsdl.parser.RuntimeWSDLParser.parse(RuntimeWSDLParser.java:147)
at com.sun.xml.ws.client.WSServiceDelegate.parseWSDL(WSServiceDelegate.java:265)
at com.sun.xml.ws.client.WSServiceDelegate.(WSServiceDelegate.java:228)
at com.sun.xml.ws.client.WSServiceDelegate.(WSServiceDelegate.java:176)
at com.sun.xml.ws.spi.ProviderImpl.createServiceDelegate(ProviderImpl.java:104)
at javax.xml.ws.Service.(Unknown Source)
at org.tempuri.BPAExecutionServerWCFServer.(BPAExecutionServerWCFServer.java:42)
at WCF.WCFTest.main(WCFTest.java:20)
Code:
package WCF;
import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.ws.BindingProvider;
import org.datacontract.schemas._2004._07.automate.ClientType;
import org.datacontract.schemas._2004._07.automate_messages.OpenSessionRequestMessage;
import org.datacontract.schemas._2004._07.automate_messages.OpenSessionResponseMessage;
import org.tempuri.IBPAExecutionServerHTTPServiceContract;
import org.tempuri.BPAExecutionServerWCFServer;;
public class WCFTest {
public static void main(String[] strArgs)
{
try
{
BPAExecutionServerWCFServer service1 = new BPAExecutionServerWCFServer(new URL(“http://209.223.157.111:7102/BPAExecutionServer/?wsdl”), new QName(“http://tempuri.org/”, “BPAExecutionServerWCFServer”));
IBPAExecutionServerHTTPServiceContract port = service1.getBasicHttpBindingIBPAExecutionServerHTTPServiceContract();
((BindingProvider)port).getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, “http://209.223.157.111:7102/BPAExecutionServer/?wsdl”);
OpenSessionRequestMessage request = new OpenSessionRequestMessage();
request.setAttemptRegistration(true);
request.setClientType(ClientType.PROCESS_AGENT);
OpenSessionResponseMessage strOutput = port.openSessionRequest(request);
System.out.println(strOutput);
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
Is it possible to implement two way communication (Callback operation) using metro?
Hi Kevin,
Can you give an example of Java client when the WCF service is deployed on a IIS server with “windows Integrated security” security enabled. The client should be able to respond to “Negotiate , NTLM” authentication scheme. I couldn’t figure out how to supply the windows credentials for the NTLM challenge using METRO/WSIT.
I appreciate your insights into this security issue.
I created service1.xml with
true
My JAVA_HOME is set to jdk1.6.0_14.
I put it in the metro directory. Then I ran
bin\wsimport -extension -keep -Xnocompile -b TestService.xml http://localhost:8888/Service1.svc?wsdl
I got this error
“Exception in thread “main” com.sun.xml.ws.streaming.XMLReaderException: Unable to create StAX reader or writer”
I cannot proceed with your tutorial because of this. Any ideas on how I could fix this?
Thanks
Jose
Jose,
I also ran into this error and I think there is typo in wsimport step. Either you create a file named TestService.xml in previous step or use service1.xml in the wsimport step.
bin\wsimport -extension -keep -Xnocompile -b service1.xml http://localhost:8888/Service1.svc?wsdl
thank . this what i was looking for.
works well
Java sucks, how could be so hard to create a simple proxy… I can’t understand this philosophy… Instead of improve the proccess of creating solutions Java-boys complicate themshelf.
I could not agree more with Ariel. If this is the simplest way to create a Proxy from a WSDL with Java, SHOOT ME… .NET is not “free”, but it’s light years ahead
I am usign metro 2.0 with Netbeans ide, i consumed a webservice WCF but
i am get error Object reference not set to an instance of an object i probe the webservice with a simple object and its works fine but I inlcude others data type
its get error.
Any idea ?
I probe this Webservice with WCF client and it work
Kevin/Sumant,
Were you guys able to figure out using the Metro/WSIT kerberos authentication with the WCF service? I was able to get basic kerberos working with the krb5.ini and login.conf and getting authenticated, but the Netbeans setup is throwing errors while calling the webservice….
.NET *IS* free. VS is not. But it’s worth it
Hi Kevin
Could you please give an example of java client transfer data object that content byte[]
for example one method of the object generated by ws
public void setDocData (byte[] data)
I got HTTP 400 bad request when I tried to send the object to wcf service
Thanks
Hi,
I have created a java client using CXF I keep getting
Value cannot be null. Parameter name s message.
The WS security for the message seems to be working but the server
which is WCF keeps stating the message Value cannot be null. Parameter name s
Mahesh
Mahesh,
I see that you’ve found the same forum on this problem with the null parameter “s”…hahaha
Did you get any response from anyone?
Phuong
I am still getting error, I have my service1.xml created and placed at bin
Exception in thread “main” com.sun.xml.ws.streaming.XMLReaderException: Unable t
o create StAX reader or writer
at com.sun.xml.ws.api.streaming.XMLStreamReaderFactory.create(XMLStreamR
eaderFactory.java:145)
at com.sun.tools.ws.wscompile.WsimportOptions.parseBindings(WsimportOpti
ons.java:426)
at com.sun.tools.ws.wscompile.WsimportTool.run(WsimportTool.java:171)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.
java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAcces
sorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.sun.tools.ws.Invoker.invoke(Invoker.java:116)
at com.sun.tools.ws.WsImport.main(WsImport.java:52)
Caused by: java.io.FileNotFoundException: D:\apps\metro\service1.xml (The system
cannot find the file specified)
at java.io.FileInputStream.open(Native Method)
at java.io.FileInputStream.(FileInputStream.java:106)
at java.io.FileInputStream.(FileInputStream.java:66)
at sun.net.www.protocol.file.FileURLConnection.connect(FileURLConnection
.java:70)
at sun.net.www.protocol.file.FileURLConnection.getInputStream(FileURLCon
nection.java:161)
at java.net.URL.openStream(URL.java:1010)
at com.sun.xml.ws.api.streaming.XMLStreamReaderFactory.create(XMLStreamR
eaderFactory.java:143)
… 8 more
Got the solution, basically you need to give full path for xml file.
I am getting below error message, please can you tell me what I am doing wrong here?
Exception in thread “main” java.lang.Error: Unresolved compilation problems:
The method getBasicHttpBindingIService1() is undefined for the type EncForms
The method getData(int) is undefined for the type IEncForms2011
thanks in advance.
I got below warning message when I execute the wsimport command
sorry, didn’t mention the warning message in my last post.
WARNING: Service1 uses a non-standard SOAP 1.2 binding.
Hi
I am getting the following error message
com.sun.xml.ws.client.ClientTransportException: The server sent HTTP status code 404: Not Found
at com.sun.xml.ws.transport.http.client.HttpTransportPipe.checkStatusCode(HttpTransportPipe.java:311)
at com.sun.xml.ws.transport.http.client.HttpTransportPipe.createResponsePacket(HttpTransportPipe.java:260)
at com.sun.xml.ws.transport.http.client.HttpTransportPipe.process(HttpTransportPipe.java:218)
at com.sun.xml.ws.transport.http.client.HttpTransportPipe.processRequest(HttpTransportPipe.java:137)
at com.sun.xml.ws.transport.DeferredTransportPipe.processRequest(DeferredTransportPipe.java:138)
at com.sun.xml.ws.api.pipe.Fiber.__doRun(Fiber.java:641)
at com.sun.xml.ws.api.pipe.Fiber._doRun(Fiber.java:600)
at com.sun.xml.ws.api.pipe.Fiber.doRun(Fiber.java:585)
at com.sun.xml.ws.api.pipe.Fiber.runSync(Fiber.java:482)
at com.sun.xml.ws.client.Stub.process(Stub.java:323)
at com.sun.xml.ws.client.sei.SEIStub.doProcess(SEIStub.java:161)
at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:113)
at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:93)
at com.sun.xml.ws.client.sei.SEIStub.invoke(SEIStub.java:144)
at $Proxy41.myRemoteMethod(Unknown Source)
at driver.Main.main(Main.java:42)
I have checked in the browser and I can confirm that my service is running. Nothing shows up on fiddler. (Neither client side or server side message are generated)
I am seriously confused… Please help
P.S. When I ran wsimport, I use the service1.xml instead because I am not sure where TestService.xml came from
I.E.
wsimport -extension -keep -Xnocompile -b TestService.xml http://localhost:8888/MyWCFService?wsdl
can i setup metro/wsit on android phone? because i want to connect android phone(client use java) to laptop(server use wcf)
Your “https://metro.dev.java.net/” this url is not working. Please replace the url with “http://metro.java.net/2.2/”