Java Client
The creation of a Java Client allows for an easy integration with an existing Jolie service from a Java application by simply using the sodep protocol. In this case you don't need to introduce a rest interface over a http protocol, or a SOAP communication layer, you can just exploit the easiest way offered by Jolie for building a service: the protocol SODEP.
In the following picture we briefly represent how the final architecture of the Jolie Client appears.
The Java client for a Jolie service can be automatically built starting from a Jolie outputPort declaration. In particular, the client takes the form of a package of classes where all the Jolie types declared in the interfaces used at the input port, are converted into classes in Java. Moreover, all the Jolie interfaces available at the given port are converted into one Java interface. An implementation of the Java interface is provided in order to easily call the Jolie service by exploiting the Jolie Java client.
There are two possible ways for generating the Java client starting from an outputPort:
- Using the tool jolie2java from command line
- Using the jolie2java-maven-plugin
jolie2java
The tool jolie2java
is distributed together with the jolie engine. If you have already installed jolie you can run it in a simple way just typing the following command on a console:
jolie2java --help
You will see the following message on the console:
Usage: jolie2java --format [java|gwt] --packageName package_namespace [--targetPort outputPort_to_be_encoded] [ --outputDirectory outputDirectory ] [--buildXml true|false] [--addSource true|false] file.ol
where all the possible arguments to the tool are specified. They are:
--format
: it can bejava
orgwt
depending on the target technology. The default isjava
. Note that the generation of the gwt classes is deprecated--packageName
: it is the name of the package which will contain all the generated classes. It is a mandatory argument.--targetPort
: it is the name of the outputPort to be converted. It could be useful where the jolie file contains more than one outputPort and we just need to convert one of them. If it is not specified all the output ports will be converted.--outputDirectory
: it is the name of the output directory where the generated files will be stored. The default value is./generated
--buildXml
: it specifies if the tool must generate also the filebuild.xml
which can be used by ant for building the generated classes and provide a unique library file in the form of a jar file. The default istrue
.--addSource
: when the generation of the filebuild.xml
is enabled it specifies if adding also the sources (files .java) to the jar. The default isfalse
. In case the argumentbuildXml
is set tofalse
it is ignored.
Let us now try to apply the tool jolie2java
to the simple example at this link. Here there is a Jolie service which implements two operations getTemperature
and getWind
. The interface which describes them follows:
type GetTemperatureRequest: string {
.place?: void {
.longitude: string
.latittude: string
}
}
type GetWindRequest: void {
.city: string
}
interface ForecastInterface {
RequestResponse:
getTemperature( GetTemperatureRequest )( double ),
getWind( GetWindRequest )( double )
}
The client declaration we want to convert in a Java Client is defined within the file client.ol
which is reported below:
include "ForecastInterface.iol"
outputPort Forecast {
Interfaces: ForecastInterface
}
main {
nullProcess
}
It is worth noting that the minimal definition we require in order to generate a Java Client is the declaration of an outputPort and its related interfaces. The main scope is defined but it is empty (nullProcess
) just because we need to respect the minimal requirements for a service definition, otherwise a syntax error would be triggered by the tool.
Download in a folder both the main.ol
and the ForecastInterface.iol
file and run the following command from the same folder.
jolie2java --packageName com.test.jolie client.ol
As a result you will find a folder called generated
whose content is:
-- build.xml
-- com
----|
----test
------|
------jolie
--------|
--------types
----------|
----------GetTemperatureRequest.java
----------GetWindRequest.java
--------Controller.java
--------ForecastImpl.java
--------ForecastInterface.java
--------JolieClient.java
The file build.xml
can be used under ant for building a distributable jar file. See the subsection below for more details. The structure of the directories com/test/jolie
corresponds to the package name given as argument to jolie2java
.
Files Controller.java
and JolieClient.java
actually implement the client for sending requests to a Jolie service. The file ForecastInterface.java
is the Java interface which corresponds to the Jolie ones available at the converted outputPort. The file ForecastImpl.java
is the actual implementation of the ForecastInterface.java
and it exploits the JolieClient
class for directly invoking the operations of the Jolie service. The folder types
contains all the classes which represent the types declared in the Jolie interface. In this example there are only two types: GetTemperatureRequest
and GetTemperatureRequest
.
Some important notes to the type conversion
Native types are converted into Java classes as it is described below:
- int -> Integer
- string -> String
- double -> Double
- long -> Long
- bool -> Boolean
- raw -> ByteArray (it is an class available from the jolie.jar library)
- undefined -> Value (it is an class available from the jolie.jar library)
- any -> Object
Structured types are converted by introducing inner classes inside the main one. For example, the type GetTemperatureRequest
contains a subnode place
which is mapped with an internal class called placeType
as it is shown below where we report the first lines of the GetTemperatureRequest.java
.
public class GetTemperatureRequest implements Jolie2JavaInterface {
public class placeType {
private String latittude;
private String longitude;
public placeType( Value v ) throws TypeCheckingException {
...
Root values. When a Jolie type requires a root value like in type GetTemperatureRequest
where a string
is requested as root type, in Java it is converted introducing a private filed called rootValue
which can be accessed by using methods getRootValue
and setRootValue
.
Create a distributable jar with ant
In order to use the generated classes in a Java project it is possible to copy them by hand and then compile them. Note that you need to import also the directories which define the package name given as argument com/test/jolie
. It is worth noting that you need to add the following libraries to your project in order to satisfy the dependencies:
jolie.jar
:libjolie.jar
sodep.jar
jolie-java.jar
It is possible to retrieve all of them in the installation folder of Jolie. In particular, jolie.jar
is in the installation folder, libjolie.jar
and jolie-java.jar
are in the folder lib
and, finally, sodep.jar
is in the folder extensions
.
Alternatively, if you are confident with ant you can directly compile a distributable jar by exploiting the generated file build.xml
. In this case it is sufficient to run the following command on the console from the same folder where the file build.xml
is:
ant dist
The command generates three folders:
built
: it contains the compiled Java classesdist
: it contains the distributable jar of the Jolie Java clientlib
: it contains all the jar dependencies of the Jolie Java client
Using the Jolie Java client in a project
Let us now to show how to use the generated client into a Java project. First of all, include the following jar files in the classpath of your project:
jolie.jar
:libjolie.jar
sodep.jar
jolie-java.jar
JolieClient.jar
: it is the distributable jar of the client obtained compiling the sources with ant as described in the previous section.
In the following we show the code necessary to invoke the Jolie service of the example presented above. Here we assume that such a service is running on localhost at port 8000.
import com.test.jolie.ForecastImpl;
import com.test.jolie.JolieClient;
import com.test.jolie.types.GetTemperatureRequest;
import java.io.IOException;
public class JavaApplication
{
public static void main( String[] args ) throws IOException, InterruptedException, Exception
{
JolieClient.init( "localhost", 8000 );
ForecastImpl forecast = new ForecastImpl();
GetTemperatureRequest request = new GetTemperatureRequest();
request.setRootValue( "Cesena" );
System.out.println( forecast.getTemperature( request ));
}
}
- before using the client, it is necessary to initialize the location and the port of the service to invoke. The first row of the main does this:
JolieClient.init( "localhost", 8000 );
- then it is necessary to instantiate the object which implements the Java interface of the service:
ForecastImpl forecast = new ForecastImpl();
- now it is possible to prepare the request message:
GetTemperatureRequest request = new GetTemperatureRequest(); request.setRootValue( "Cesena" );
- finally, it is possible to perform the invocation:
forecast.getTemperature( request )
Using the jolie2java-maven-plugin
For those who are using maven for managing their Java projects, it is possible to use jolie2java
within a specific maven plugin: jolie2java-maven-plugin
. Just add the following lines to the pom of your project and the jolie2java
tool can be used within the maven Lifecycle:
<!--dependencies-->
<dependency>
<groupId>jolie</groupId>
<artifactId>jolie</artifactId>
<version>1.8.1</version>
</dependency>
<dependency>
<groupId>jolie</groupId>
<artifactId>libjolie</artifactId>
<version>1.8.1</version>
</dependency>
<dependency>
<groupId>jolie</groupId>
<artifactId>jolie-java</artifactId>
<version>1.8.1</version>
</dependency>
<dependency>
<groupId>jolie</groupId>
<artifactId>sodep</artifactId>
<version>1.8.1</version>
</dependency>
<!-- maven plugin -->
<build>
<plugins>
<plugin>
<groupId>jolie</groupId>
<artifactId>jolie2java-maven-plugin</artifactId>
<version>1.0.0</version>
<configuration>
<joliePath>...</joliePath>
<outputDirectory>...</outputDirectory>
<packageName>...</packageName>
<includePath>...</includePath>
</configuration>
<executions>
<execution>
<goals>
<goal>joliegen</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
where the configuration parameters are:
- joliePath: the path where the jolie files which describe the client can be found by maven
- outputDirectory: the outputDirectory where the generated classes must be copied
- packageName: the name of the package to be used in the generated classes
- includePath: the path where the jolie standard library include files are stored. Default
/usr/lib/jolie/include
.
Note that the jolie2java-maven-plugin
will be run during the generated-sources
phase of maven, thus before the compilation one. So, take care to specify an outputDirectory inside your project which can be accessed by maven during the compilation.