Saturday, November 16, 2019

SOAP Web Services with Java Enterprise Edition done with a Maven project

This post is an update of another post I did a few years ago before I used Maven. My goal is to create a simple SOAP Web Service and use it from a client. In theory, the main difficulty is the Maven configuration, but I found it troublesome to successfully conclude the client, due to a persistent problem with the Java versions. Hopefully I can provide some help in the process.

Server

The source code of the server is not very realistic, but this is only for illustration purposes. I wrote the server and completed all the necessary steps on the server with Java 12 and WildFly 18. For the client I was forced to use a different version. Since I am using a Maven project, I started a new project from scratch without any archetype. The project had this structure:



From here I created the Java code for the server:

import java.util.Hashtable;
import java.util.Map;

import javax.jws.WebMethod;
import javax.jws.WebService;


@WebService
public class MyAgenda {
 private static Map<String, String> agenda = new Hashtable<>();
 
 @WebMethod
 public String sayHello(String name) {
  return "Hello " + name;
 }
 
 @WebMethod
 public String getPhone(String name) {
  if (agenda.containsKey(name))
   return agenda.get(name);
  else
   return null;
 }
 
 @WebMethod
 public void setPhone(String name, String phone) {
  agenda.put(name, phone);
 }
}

Next, I need to write the pom.xml file. This has a few important details: the packaging, the ws dependency and the plugins that control the war packaging and the deployment on a WildFly server (keep reading if you don't use WildFly). I configured the file for it to work without a web.xml file inside the webapp directory:

<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>is</groupId>
<artifactId>play-webservices</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>playwebservices Maven Webapp</name>
<url>http://maven.apache.org</url>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>

<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/com.sun.xml.ws/jaxws-rt -->
<dependency>
<groupId>com.sun.xml.ws</groupId>
<artifactId>jaxws-rt</artifactId>
<version>2.3.2</version>
<type>pom</type>
</dependency>
</dependencies>
<build>
<finalName>play-webservices</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>12</source>
<target>12</target>
</configuration>
</plugin>

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.3</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>

<plugin>
<groupId>org.wildfly.plugins</groupId>
<artifactId>wildfly-maven-plugin</artifactId>
<version>2.0.1.Final</version>
<configuration>
<hostname>localhost</hostname>
<port>9990</port>
</configuration>
</plugin>
</plugins>
</build>

</project>

If you use WildFly, once you start the server you may then set the following maven phases:

(mvn) clean install wildfly:deploy

to compile the project, build the war file (into the target directory) and finally deploy the project in WildFly. You may skip this last step to get the war file and deploy it manually in your server (even in WildFly).

Once this is properly set up you should be something like this in the server console:

11:20:16,416 INFO  [org.jboss.ws.cxf.metadata] (MSC service thread 1-7) JBWS024061: Adding service endpoint metadata: id=MyAgenda
 address=http://localhost:8080/play-webservices/MyAgenda
 implementor=MyAgenda
 serviceName={http:///}MyAgendaService
 portName={http:///}MyAgendaPort
 annotationWsdlLocation=null
 wsdlLocationOverride=null

 mtomEnabled=false

You now may go to the browser and look for the following URL: http://localhost:8080/play-webservices/MyAgenda?wsdl

to get this result:




Client

The client, in a different project, is as simple as the server (mind a detail about Java versions below):

import artifact.MyAgenda;
import artifact.MyAgendaService;

public class HelloAppClient {
 private static MyAgendaService service = new MyAgendaService();

 public static void main(String[] args) {
  MyAgenda agenda = service.getMyAgendaPort();
  System.out.println(agenda.sayHello("world"));

  agenda.setPhone("Paula", "9626341");
  
  System.out.println(agenda.getPhone("Paula"));
 }
 
}

Unfortunately, it will not compile because it misses a number of classes that we must generate with the help of the wsimport tool. This brought me to a problem: wsimport ceased to exist in the newer Java versions as a standalone program (refer to my previous version of this example for additional details). We need to execute wsimport via Maven. Sadly, due to a problem I could not use Java 12 and had to revert to Java 8 (which would probably have wsimport by the way...), but kept the principle of using Maven (hopefully this will be fixed in future versions of the jaxws-maven-plugin):

<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>is</groupId>
<artifactId>play-webservices-client</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>

<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/com.sun.xml.ws/jaxws-rt -->
<dependency>
<groupId>com.sun.xml.ws</groupId>
<artifactId>jaxws-rt</artifactId>
<version>2.3.2</version>
<type>pom</type>
</dependency>
</dependencies>
<build>
<finalName>play-webservices</finalName>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxws-maven-plugin</artifactId>
<version>2.5</version>
<executions>
<execution>
<goals>
<goal>wsimport</goal>
</goals>
</execution>
</executions>
<configuration>
<!-- The name of your generated source package -->
<packageName>artifact</packageName>
<wsdlUrls>
<wsdlUrl>
http://127.0.0.1:8080/play-webservices/MyAgenda?wsdl
</wsdlUrl>
</wsdlUrls>
<verbose>true</verbose>
<target>2.1</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>8</source>
<target>8</target>
</configuration>
</plugin>


</plugins>
</build>
</project> 

Once we run Maven with the goal "generate-sources", we get the following additional files (in target/generated-sources/wsimport), possibly after refreshing the IDE:


We are now able to run the project and the get the following (astounding!) results:

Hello world
9626341

5 comments:

  1. We are really grateful for your blog post. You will find a lot of approaches after visiting your post. I was exactly searching for. Thanks for such post and please keep it up. Great work.

    Justpaste Mystrikingly Articleted Medium Bloglovin

    ReplyDelete
  2. This all information are very useful to build a any software such as workshop management software free trail for today book.

    ReplyDelete
  3. I want to share a testimony on how Mr Pedro loan offer helped my life,
    It isn't a good idea to use a payday loan on a regular basis. In the event that you endlessly prolong your repayment date and borrow often towards your subsequent paycheck, it could run you a good amount of money. However, it is just as sensible to decide on payday loans as they can be swiftly approved exactly the same day you put in your loan application form. You can contact Mr Pedro loan offer because my payday loan was very fast to proceed, email pedroloanss@gmail.com to request any kind of loan. Whatsapp +18632310632

    ReplyDelete
  4. Wynn Casino & Resort, Las Vegas (NV) - MapYRO
    Wynn 양산 출장마사지 Las 포항 출장안마 Vegas is a shimmering gold 18-story, 11 안산 출장마사지 story 영천 출장마사지 high-rise building in Las Vegas, Nevada, 과천 출장안마 U.S.A.. View a detailed profile of the structure 1010, including further data

    ReplyDelete
  5. Your article was very impressive; I really appreciate the research you’ve done and that helps make your article rich. Overall you’ve done great work.

    Online Certificate Courses in Drug Regulatory Affairs

    ReplyDelete