Building a web service endpoint in Java

Ok, so what is a web service?

I provide an overview of what Web Services (WS) are in this post, An introduction to Web Services. Give it a read and pop back here Smile

Seriously, Java? The most insecure software platform ever?

Yes, Java. The platform agnostic software environment that is taught in a lot of University CS courses and has had a consistently high spot in the tiobe programming language popularity chart (Currently #2, with only .2% less market than the number one, C).

Its also worth bearing in mind that the security issues that have plagued Java in recent months are usually related to the use of a web plug in. This plug in causes issues as Java is a powerful, fully featured platform which when combined with a web plugin introduces a large number of attack vectors. From a Desktop/Server application perspective Java is quite safe and in many ways safer than native code due to its Bytecode interpreting sandboxed process virtual machine.

Which Web Service technology will be used here?

In this example SOAP based web services will be used to provide a quick example. For large production systems you may prefer to look at JSON (Message format) and REST (communication strategy) based WS.  This example will be built using Netbeans.

Plug-in and communicate

What??? I’m quite I read a lot so I’m plugged in but I‘m a stereotypical Socially Awkward Penguin, I don’t like the talky talk. Not fair!!!

Not that type of plugged in and communicate, to develop WS in Java we need to install a  development plugin. To do this go to the Tools –> Plugins menu.

image

In the plugin interface go to Available plugins and install the Java web and EE option. After installation restart Netbeans.

image

Once the  WS support is enabled a hosting server is needed, this can be specified or isntaleld from the Tools-> Servers menu. Click Add Server

image

Next choose a server, I have chosen the Glassfish server below.

image

If you have the installed already you may specify the path or download the server. To download tick the agreement then select Download Now. Then go through the Installation process. Follow the screen shots below

image

image

image

image

Now that your environment is ready you can now create a project.

Time to make a project.

Create a New ‘Web Application’ Project as shown below.

image

image

Yes, I am aware I forgot the ‘l’, I have another Example Application in the same folder and am a little lazy.

image

image

Do not click any of these frameworks as they are not needed for this tutorial.

image

Codey Time!

Under web services click New –> Web Service and then specify customization.

image

image

image

You should now be presented with a source file which contains some boiler plate code. To this code a small math operation should be added. image

The code in question will go into a class called MathFun and will calculate the Pearson product-movement coefficient.  A walkthrough of calculating this is shown here. This code accepts 2 arrays containing Doubles and returns a double as a reply.

image

Once the code has been added to a class it can then be called by the service endpoint code by specifying a @WebMethod.

This code follows this form.

   1: private MathFun mathFun = new MathFun();

   2:  

   3: @WebMethod(operationName = "CalculatePearson")

   4: public Double CalculatePearson(Double  a1[], Double  a2[]) {

   5:     return mathFun.CalcPearsonCorrelation(a1,a2);

   6: }

image

Once the code is complete and tested it is then possible to test the web service with a useful Open Source tool called SoapUI.

image

And we are done!!

Yes, it is that easy to set up a WS. The next step involves consuming it from a device/web browser. This is simple enough as most development environments support SOAP.

Java–Serial Killer

Its about time a public mourning took place for people who are allergic to coffee…

Although I do feel pity for the people who are allergic to coffee (what a horrible existence… i would hate not being able to have the best addiction)  this is not the topic of this post.

Ahhh so are you taking about the mass deprecation that takes place in Java?

Although the deprecation of components in Java does annoy me (Java 7 Deprecations, J6 Deps) it is a necessity in most cases  but this is not the choice of topic.

I get it, you are taking about all the nuclear facilities that had faulty Java control software in place which caused a meltdown or 2!!

Eh no, the java agreement requires that “You acknowledge that Licensed Software is not designed or intended for use in the design, construction, operation or maintenance of any nuclear facility”

Im taking about the state of communicating with RS232 devices from Java.

That’s simple just use java.comm

Exactly what I thought too but it appears that the write once run anywhere promise of Java has been broken further, back in the day it was possible to write windows Java apps that could use Java.comm but it appears that it is no longer possible to use this functionality outside of Linux, Mac OS X and Solaris.

I recently discovered this when I developed a web service component that uses a RS232 sensor on linux where it worked fine and I was a happy coder but when I brought it over to windows I was left astonished and searching for a solution.

RXTX to the rescue

After doing some searching around I found a beautiful LGPL product called rxtx which provides platform agnostic RS232 support through a native library and jar class file combination.

The native library goes into the the /bin sub folder of both the Java runtime and Development Kit folders and the .jar file goes into the companion /lib subfolders of those directories.

The API is easy to use and clear with a fairly logical structure for example to detect COM ports on a system the following code fragment is used

 1: List <String> list = new ArrayList<String>();
 2: Enumeration portList = CommPortIdentifier.getPortIdentifiers();
 3: 
 4: while (portList.hasMoreElements()) {
 5: 
 6:      CommPortIdentifier portId = (CommPortIdentifier) portList.nextElement();
 7: 
 8:      if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {
 9: 
 10:           list.add(portId.getName());
 11:      }
 12: }

The rxtx project lives at  http://rxtx.qbang.org/wiki/index.php/Main_Page where you can get a variety of downloads and a wealth of documentation

A MySQL Time Machine

N.B. This post is required for MySQL 5.1 (or earlier) and will likely be needed for newer editions of the RMDBS as well

Did Doc Emmet Brown not invent time travel 10 years before MySQL was initially released?

He did and the laws of known physics haven’t been broken yet, what I am explaining here is representing temporal state of an element (e.g an account) whose historical state can be queried for any given point of time and future state(s) can be set in advance.

 

image

In the above illustration the Account is active for the timestamp of the query, Green represents an active account

The tables to be used in this effort will look similar to this

image

Account table

image

Account actions table

The account table has the usual fields:

  • Account_ID
  • Name
  • Credit card number
  • etc

The  account_actions table records :

  • A unique action ID
  • An Action_Type – this is an enumeration of an account action
  • An Action_Date – the point where this account action takes come into effect
  • Created_Date – the date that this action was created

Can I not simply do this with a JOIN and a WHERE?

Oh like this?

 1: SELECT
 2:     Account.Name,Account_actions.Action_Type
 3: FROM
 4:     Account
 5: JOIN
 6:     Account_actions
 7: ON
 8:     account.Account_ID = Account_actions.Account_ID
 9: WHERE
 10:     Account_actions.Action_Date < NOW();
 11: 

In the above example we hope to obtain the account name from the Account table and the previous action_type from the Account_Actions table with the account action corresponding to the most recent one, this will produce erroneous results as that JOIN operation does not apply sorting of the results from the joined table to the join even if we were to add an ORDER BY.

In most cases the Action_Type returned would likely be the first one stored into the Account_actions table in the subset of data created from that WHERE clause.

It is entirely possible that this erroneous implementation could lay in wait ready to trip up even experienced SQL Query Craftspeople as it seems to be a correct logical Command

Is there a solution?

Yes in place of joining a pre-existing table we JOIN a table generated by an inline SELECT command which has the necessary sorting and filtering in place.

So to correctly implement this goal we would use the following command

 1: SELECT
 2:     Account.Account_ID, Generated_account_actions.Action_Type
 3: FROM
 4:     Account
 5: JOIN
 6:     (
 7:         SELECT
 8:             scheduled_actions.Account_ID, scheduled_actions.Action_Type
 9:         FROM
 10:             scheduled_actions
 11:         WHERE
 12:             scheduled_actions.Action_Date < NOW()
 13:         ORDER BY
 14:             scheduled_actions.Action_Date DESC
 15:     ) AS Generated_account_actions
 16: ON
 17:     account.Account_ID = Generated_account_actions.Account_ID;

This query uses a the results from the filtered and ordered table (under an alias of Generated_account_actions) to perform a JOIN and return the most recent action state for this user account.

I hope this post helps you when making your next killer MySQL backed App, these queries may be performance optimised but I wish to illustrate a point.

Using Java Classes in a .NET project

Let me guess,Witchcraft ?

No witchcraft was involved (directly anyway, I did sacrifice a lamb to get some blue mountain coffee to keep myself awake when looking through alternative solutions), neither is mangling JAVA source code into C# form.

But .NET has everything!!!!

Java has a rich ecosystem with many reusable projects in existence for it which is great if you are working in a Java environment but if you need to develop a program using Microsoft .NET technologies and wish to leverage a Java class then you may be SOL (sadly outta luck).

I was in this situation a while ago when integrating some JAVA-only semantic web tools (Pellet and JENA) into a .NET web project, the solution I came to was to use an implementation of JAVA for Mono/.NET called IKVM.

IKVM allows cross-compilation of Java JAR files to .NET compatible DLL files which can be then be imported into your .NET project

This conversion process looks similar to

image

Lets go!

Download the iKVM toolset and extract it to a memorable location (e.g. c:\ikvm) and then compile or download a .JAR file for the Java classes that you wish to use.

Once you have obtained your .JAR file you need to compile this to the .DLL to do this put the .JAR into the same folder as your ikvmc.exe file (above this extracted this to c:\ikvm\bin ) and then perform the conversion.

The command to run the conversation may vary if your JAVA component has dependencies, to read more about this go to the IKVM documentation.

A simple conversion of the Jena.JAR files

   1:  ikvmc .\jena\*.jar -target:library -out:.\dotNet-Libs\jena.dll -version:2.5.4.0 -nowarn:IKVMC0109

This operation will be performed on the following Jena related .JAR files

imageThis produces the following output the warnings refer to dependencies that Jena requires that have not been satisfied in this cross compile, these will be compiled to DLL files in another process.

image

This will produce a single jena.dll file in the dotNet-Libs folder, this DLL file will need to be imported into the .NET project in addition to all of the standard  IKVM.OPENJDK and IKVM reflection and runtime DLL files (these provide a runtime).

To compile the entire set of Pellet 1.5.2, MSSQL JDBC driver, Jena 2.5.2 JAR  files (with dependencies) it may be best to run a batch file with the following series of operations (assuming you have the correct jar files in the listed folders)

   1:  mkdir dotNet-Libs 
   2:  mkdir pellet 
   3:  mkdir sqldriver 
   4:  move aterm-java-1.6.jar .\pellet 
   5:  move pellet-core.jar .\pellet 
   6:  move pellet-jena.jar .\pellet 
   7:  move servlet.jar .\pellet 
   8:  move sqljdbc.jar .\sqldriver 
   9:  rem Convert Pellet 1.5.2 auxiliary libraries 
  10:  ikvmc .\xsdlib\*.jar -target:library -out:.\dotNet-Libs\xsdlib.dll -version:1.5.2.0 -nowarn:IKVMC0109 
  11:  ikvmc .\jetty\*.jar -target:library -out:.\dotNet-Libs\jetty.dll -version:1.5.2.0 -nowarn:IKVMC0109 
  12:  ikvmc .\junit\*.jar -target:library -out:.\dotNet-Libs\junit.dll -version:1.5.2.0 -nowarn:IKVMC0109 
  13:  ikvmc .\owlapi\*.jar -target:library -out:.\dotNet-Libs\owlapi.dll -version:1.5.2.0 -nowarn:IKVMC0109 
  14:  rem Convert Jena 2.5.4 
  15:  ikvmc .\jena\*.jar -target:library -out:.\dotNet-Libs\jena.dll -version:2.5.4.0 -nowarn:IKVMC0109 
  16:  rem Convert Pellet 1.5.2 libraries 
  17:  ikvmc .\pellet\*.jar -target:library -reference:.\dotNet-Libs\xs dlib.dll -reference:.\dotNet-Libs\jetty.dll -reference:.\dotNet-Libs\junit.dll -reference:.\dotNet-Libs\owlapi.dll -reference:.\dotNet-Libs\jena.dll -out:.\dotNet-Libs\pellet.dll -version:1.5.2.0 -nowarn:IKVMC0109 
  18:  rem Convert Microsoft jdbc SQL Driver 1.2 
  19:  ikvmc .\sqldriver\*.jar -target:library -out:.\dotNet-Libs\sqldriver.dll -version:1.2.0.0 -nowarn:IKVMC0109 
  20:  copy IKVM.*.dll .\dotNet-Libs\ 
  21:  pause

Once you have generated all the Java origin DLL files you will need to import these into your .NET project in the usual way (if you don’t know how to do this i suggest that you trawl MSDN for a few hours to learn all the basics of .NET development).

Bumps in the road?

Yes, you need to be wary of Namespace conflicts, e.g. if both .NET  and Java have an available object called shinyObject your will need to explicitly call the FULL name of this object in your code as shown when creating the JENA statement and GenericRuleReasoner objects in the following code snippet

   1:  using System;
   2:  using System.Data;
   3:  using System.Configuration;
   4:  using System.Linq;
   5:  using System.Web;
   6:  using System.Web.Security;
   7:  using System.Web.UI;
   8:  using System.Web.UI.HtmlControls;
   9:  using System.Web.UI.WebControls;
  10:  using System.Web.UI.WebControls.WebParts;
  11:  using System.Xml.Linq;
  12:  using System.IO;
  13:  using SpeechLib;
  14:  using System.Media;
  15:   
  16:  using System.Collections;
  17:   
  18:  //Java Functionality
  19:  using ikvm.io;
  20:  using java.io;
  21:  using ikvm.lang;
  22:   
  23:  //Import Pellet
  24:  using org.mindswap.pellet;
  25:  using org.mindswap.pellet.jena;
  26:   
  27:  //IMPORT JENA TOOLS
  28:  using com.hp.hpl;
  29:  using com.hp.hpl.jena;
  30:  using com.hp.hpl.jena.db.impl;
  31:  using com.hp.hpl.jena.ontology;
  32:  using com.hp.hpl.jena.rdf.model;
  33:  using com.hp.hpl.jena.reasoner;
  34:  using com.hp.hpl.jena.query;
  35:  using com.hp.hpl.jena.util.iterator;
  36:   
  37:  //JENA TDB
  38:  using com.hp.hpl.jena.tdb;
  39:  using com.hp.hpl.jena.tdb.store;
  40:  using com.hp.hpl.jena.tdb.@base.file;
  41:   
  42:   
  43:  /* 
  44:   * 
  45:   * 'Statement' is an ambiguous reference between 'SemWeb.Statement' and 'com.hp.hpl.jena.rdf.model.Statement'
  46:   * 
  47:   */
  48:   
  49:   
  50:  public class sourMash
  51:  {
  52:   
  53:    
  54:      //A Jena Model RDF Statement
  55:      private static com.hp.hpl.jena.rdf.model.Statement jenaStatement = null;
  56:   
  57:        //Generate a Rule Reasoner
  58:        com.hp.hpl.jena.reasoner.rulesys.GenericRuleReasoner reasoner = null;
  59:   
  60:  }

 

I hope this helps you in the beginning of your search for harmony between your development tools.

For convenience I have attached all the required JAR files, DLL Files, tools and scripts (ik-com.bat) required to compile and import PELLET and JENA in .NET here:  Pellet and Jena dotNET to Java Archive (this archive requires the excellent open source 7-ZIP file manager)