Monday, January 20, 2014

RESTful web services with jetty and jersey

Recently I was thinking if there is a way to start a web server in java just as easy as it is in node.js, if you don't know node.js you can check this link nodejs.org, so in node you just write a few lines and you have a server like this:


I thought that with something like this you can easily test your code without the burden of deploy it, and also saving some resources. 

So I start looking if there is something similar in java and I found several projects to start a web server or a minimal server, but I decided to go with jetty www.eclipse.org/jetty, so I'm going to show you how to run some restful web services using jetty. 

Also I'm going to use jersey jersey.java.net which simplifies the development of RESTful Web services and their clients in Java.

So you can download the jars from these projects or configure them through maven to your project to start using them, in these links www.eclipse.org/jetty , jersey.java.net you can check the instructions to do it.

So to create a web server with jetty is as easy as the following code:


If you run the code and check the http://localhost:8080/hello url you can see that your servlet is running, so basically in the code you create a Server object and set the port the Servlets and the servlets to run and that's it.

With jetty you can do much more than this, but for the purpose of this blog I will no go further, you can check the jetty documentation.

The following would be to create and deploy the RESTful web services, now we will use jersey to this.

The first thing to do is to create the services that we will deploy, for the example I will create two services one using JSON and other using XML, I will create two objects used to transfer the data.



In the classes above you can see two classes Employee with a nested class Address and Student, the only thing to notice from these classes are the annotations @XmlRootElement and @XmlAttribute, these annotations are used to do the parsing from object to the protocol used (XML, JSON) and from protocol to object.

The following would be to create the classes for the services.




The classes above use the standard Java EE specification for RESTful web services they use the @Path annotation at the top level to set the service path and each method use the @GET, @POST annotations to describe the type of service and the @Produces annotation to set the type of protocol to use.

The method getStudent of the class XMLStudentSvc has also the @Path("/student/{name}")  this specifies a path for this method, also note that it receives a parameter named "name" through the path and this parameter will be mapped to the parameter of the method.
For more about how define RESTful web services check the specification https://jcp.org/en/jsr/detail?id=311

Another thing to notice is that both classes are in a package called "rest", so the following to do would be to deploy these services in jetty as long as the jersey configuration.

This is the class for the server:



See in the class above all what it needs to configure jersey, a ServletHolder object is created to set the parameters, note that is indicated the package where the services are located and jersey will automatically deploy them. The ServletHolder object is passed to a ServletContextHandler object, and that's it with this the services should be up and running.

The last thing to do is to create a client for our services, for the client I will use jersey to help.

This is the client for the JSON service:


The client will call two methods, the first will be to the GET method and it uses the url with the path specified for this method ("http://localhost:9999/employee/getEmployee"), this method returns a response in JSON, then this response is unmarshal to a object with the call to "response.getEntity(Employee.class)".

If the JSON response is needed instead of the actual object all what is need to do is change the type to String in the unmarshal "response.getEntity(Employee.class)".

The other method specified in this client is the POST method this call doesn't return a thing,  it uses the url with the path specified for this method ("http://localhost:9999/employee/postEmployee") and it sends back the same object the client is receiving, you should see an output in the server since the service method is printing the object it is receiving.

This is the client for the XML service:


It is almost the same as the JSON client, the only difference is that a parameter is include in the url "http://localhost:9999/xmlServices/student/James", because the service is expecting it.

After running these examples I notice how easy and fast is to run the services and the few resources that required, I'm using at most 30Mb of memory.

Monday, January 6, 2014

JDK 7 securtiy issues with web start

With the latest updates java increased its security and new features were added to the web start applications, so basically if you have a web start application and is not properly signed it will not run over the latest version of the JVM (1.7.45), giving  you a warning like the following, and more errors.



This is what happened to me and I will explain what I had to do to get over this new security requirements and kept your application running.

The first step is get a code signing certificate with an certificate authority (CA), there are different CA and here are some of them:
The process to get the certificate is the following:

First you will have to request the CA for a certificate, and for this you will need a Keystore and a Certificate Signing Request (CSR), these are generated with the keytool.

For generate the keystore use the following command:

keytool -genkey -alias Alias -keyalg RSA -keysize 2048 -keystore Keysotre.jks

And for generate the CSR use the following command:

keytool -certreq -alias Alias  -file Cert.csr -keystore Keysotre.jks 

Each command will ask you for a password, after generating these files you will send the CSR file to the CA.

After the CA generates the certificate, it will send you the certificate, it is a file with probably one of the following extensions: PEM, DER, P7B, PFX, depending in the type of certificate, you can find more about the certificate types in this link: www.sslshopper.com/ssl-converter.html

Once you have the certificate with you, you will have to import it using the keytool, with the following command:

keytool -import -trustcacerts -alias Alias -file CAcert.p7b -keystore Keysotre.jks

Make sure you use the same keystore file used in the generation of the CSR file. You can find more information of the keytool command in the following link:

With this the jars files can be signed using the jarsigner command:

jarsigner -keystore Keysotre.jks -storepass password file.jar Alias

With these steps the jar file gets signed, but there is much more about this process of signing a jar.

Before the new features that were added in the latest releases of the JVM (1.7.XX) this was all you have to do to meet the security requirements for a web start application just sign the jars of the application.

These are some of the new features:

The META-INF/MANIFEST.MF file of the jar files must have the following attributes to grant permissions

Manifest-Version: 1.0
Permissions: all-permissions
Codebase: https://example.com

In this link you can find the new attributes of the Manifest file http://docs.oracle.com/javase/7/docs/technotes/guides/jweb/manifest.html


Another feature is to sign the JNLP file, the oracle documents says the following in order to sign a JNLP file: 

"To create a signed JNLP file you don't sign the JNLP file itself, but you include the JNLP file inside the directory structure before the JAR file is created and then signed. The JNLP file must be named APPLICATION.JNLP and is included in the JNLP-INF subdirectory. The JAR file is then created and signed in the usual manner. When a web start application is started, the JNLP file used must be identical to the JNLP file in the signed JAR in order for the application to run".

You can find more information about signing JNLP files in the following link: http://docs.oracle.com/javase/7/docs/technotes/guides/jweb/signedJNLP.html

Well these are some of the new requirements in order to run properly a web start application, I hope with this blog you can now have an idea of what to do if your web start application does not run because of security issues.