Java client and WCF server

This article is a part of WCF & Java Interop

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: http://metro.java.net/2.2/.

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

  • Pingback: Fix Webservices-api.jar Errors - Windows XP, Vista, 7 & 8

  • KYAW KYAW OO

    Hi Kevin

    Really nice blog and I would like to have working WSDL from WCF Application for the Jax-WS so far couldn’t achieve it.

    My Web Service with multiple is working well with IIS and SOAPUI but I couldn’t manage to generate the contracts need using Jax-WS.

    Pls advise me since I was stuck on it so long and hope to close the case asap.

    Thanks and best regards

    My intention is to use my WCF Web Service(Server) side with Java Client

  • Govind Lohiya

    Hi Kevin,

    I have a WCF web service which implements WS Discovery. I want to create a java client which can automatically find the service response by sending a probe message.

    Note: The java Client does not know the wsdl URL. The service should broadcast the message with wsdl URL embedded and tha Java Client should be able to extract the information.

    Is this possible? Could you please help.

  • Pingback: All in One- Bookmarks Throught Career | MUHAMMAD ARSHAD

  • http://www.kevingao.net/ Kevin Gao

    Thanks for reminding me.

  • http://foyzulkarim.blogspot.com Foyzul Karim

    Your “https://metro.dev.java.net/” this url is not working. Please replace the url with “http://metro.java.net/2.2/”

  • hungbkh

    can i setup metro/wsit on android phone? because i want to connect android phone(client use java) to laptop(server use wcf)

  • Peter Hsu

    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

  • Leo

    sorry, didn’t mention the warning message in my last post.

    WARNING: Service1 uses a non-standard SOAP 1.2 binding.

  • Leo

    I got below warning message when I execute the wsimport command

  • Leo

    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.

  • Shah

    Got the solution, basically you need to give full path for xml file.

  • Shah

    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

  • ptn77

    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

  • http://mayoo.com Mahesh

    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

  • HHO

    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

  • Kahuna

    .NET *IS* free. VS is not. But it’s worth it πŸ˜‰

  • Ravi

    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….

  • Waltero

    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

  • http://www.omniscient.ca Francois

    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 :)

  • Ariel

    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.

  • africa

    thank . this what i was looking for.
    works well

  • var

    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

  • Jose

    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

  • Sumant

    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.

  • Yograj Patil

    Is it possible to implement two way communication (Callback operation) using metro?

  • Ronak

    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();
    }
    }
    }

  • NItin

    How would you create a java client when you have a WCF service running on net tcp binding.

  • Julisa

    It is possible to use javax.xml.ws.Dispatch to communicating with WCF Service?

  • Anaristos

    Here is something interesting. I imported the Eclipse project into Netbeans 6.5.1 and it ran perfectly. So the problem is with Eclipse.

  • Anaristos

    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?