This post demonstrates how to create a simple SOAP Web Service with Kotlin. Moreover, it uses the same techniques we use to develop SOAP Web Services in Java.
Requirements
We use the following items for this post.
- Kotlin 1.1
- Java Development Kit 8
Kotlin To Java public final methods
By default, methods in Kotlin classes become public final for the underlying Java 8 run time environment. For example, consider these Kotlin codes.
1 2 3 4 5 6 7 8 9 | /** * Initial class. Still needs to be modified to be a * SOAP-based web service class. */ class HiHelloWS { fun sayHello() : String { return "Hello" } } |
The codes above are equivalent to these Java codes and they will cause a runtime error. Therefore, we will modify the Kotlin class a bit later in this post.
1 2 3 4 5 6 | public final class HiHelloWS { public final String sayHello() { return "Hello"; } } |
Therefore, using public final methods in SOAP Web Services causes the following error. To fix this problem, simply avoid using public final methods in Kotlin for this case.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | Exception in thread "main" com.sun.xml.internal.ws.model.RuntimeModelerException: runtime modeler error: @WebMethod is not allowed on a static or final method public final java.lang.String com.turreta.kotlin.soap.HiHelloWS.sayHello() at com.sun.xml.internal.ws.model.RuntimeModeler.isWebMethodBySpec(RuntimeModeler.java:508) at com.sun.xml.internal.ws.model.RuntimeModeler.processClass(RuntimeModeler.java:466) at com.sun.xml.internal.ws.model.RuntimeModeler.buildRuntimeModel(RuntimeModeler.java:305) at com.sun.xml.internal.ws.db.DatabindingImpl.<init>(DatabindingImpl.java:85) at com.sun.xml.internal.ws.db.DatabindingProviderImpl.create(DatabindingProviderImpl.java:59) at com.sun.xml.internal.ws.db.DatabindingProviderImpl.create(DatabindingProviderImpl.java:43) at com.sun.xml.internal.ws.db.DatabindingFactoryImpl.createRuntime(DatabindingFactoryImpl.java:105) at com.sun.xml.internal.ws.server.EndpointFactory.createSEIModel(EndpointFactory.java:453) at com.sun.xml.internal.ws.server.EndpointFactory.create(EndpointFactory.java:269) at com.sun.xml.internal.ws.server.EndpointFactory.createEndpoint(EndpointFactory.java:144) at com.sun.xml.internal.ws.api.server.WSEndpoint.create(WSEndpoint.java:563) at com.sun.xml.internal.ws.api.server.WSEndpoint.create(WSEndpoint.java:545) at com.sun.xml.internal.ws.transport.http.server.EndpointImpl.createEndpoint(EndpointImpl.java:308) at com.sun.xml.internal.ws.transport.http.server.EndpointImpl.publish(EndpointImpl.java:231) at com.sun.xml.internal.ws.spi.ProviderImpl.createAndPublishEndpoint(ProviderImpl.java:126) at javax.xml.ws.Endpoint.publish(Endpoint.java:240) at com.turreta.kotlin.soap.HiHelloWSKt.main(HiHelloWS.kt:26) ... |
Our SOAP Web Service Codes In Kotlin
These are the complete codes for our sample web service. Note that we use the open keyword in our Kotlin class to ensure the JVM can extend it to create a SOAP Web Service. In the same Kotlin file, we create the main function to publish (or start) our web service at a specified port number.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | package com.turreta.kotlin.soap import javax.jws.WebMethod import javax.jws.WebService import javax.xml.ws.Endpoint /** * Created by turreta.com on 23/6/2017. */ @WebService class HiHelloWS { @WebMethod open fun sayHello() : String { return "Hello" } } /** * Make the web service available. To retrieve the WSDL, use * * http://localhost:8080/?wsdl * */ fun main(args: Array<String>) { Endpoint.publish("http://localhost:8080/", HiHelloWS()) } |
Next, we can retrieve the WSDL to create a SOAP client in Kotlin. To do so, go to HTTP://localhost:8080/?wsdl.
Then, we can test our Web Service using a client in Kotlin.