Friday, August 28, 2009

Enabling https support

Enabling https support for restlet server and client:

1) Create your keys and certificate. I tried both 'keytool' and IBM's
KeyMan to do this (KeyMan is easier, but more work to obtain, as you need
to register, etc...). Using keytool from a command prompt you need to
enter two commands - the first one creates the keystore file with the
keys, the second certifies it (self-certification, ok for testing). The
most important thing is that the name of the machine you will be using the
certificate on matches what you specify (in the example below, my machine
is called 'serverX'):

keytool -genkey -dname "CN=serverX, OU=IT, O=JPC, C=GB" -alias serverX
-keypass password -keystore serverX.cer -storepass password -keyalg "RSA"
-storetype "PKCS12" -provider sun.security.provider.Sun

keytool -selfcert -alias serverX -keystore serverX.cer -storepass password
-storetype "PKCS12"

The keystore file has now been created and self-certified: in this example
it is called 'serverX.cer' and was saved in the current directory. There
are two passwords: one for the keys and one to access the keystore. I set
them both to 'password' for testing. The name of the keystore file
('serverX.cer') is not important, I just used that for consistency.

2) To prevent warnings in a browser, add the keystore to the 'Trusted Root
Certification Authorities' on your computer. In Windows XP, I just used
Internet Options (via IE7 or Control Panel - Internet Options). On the
'Content' tab, click 'Certificates', then go to 'Trusted Root
Certification Authorities' tab, click 'Import...' and follow the steps to
import your keystore file (in my example, 'serverX.cer'). It will give
warnings about not being verified, which is ok for testing (but it must be
properly signed for production).

3) In order for Java security to recognise the certificate, it needs to be
added to \lib\security\cacerts, which is the Java certificates file.
This is important when you use a Restlet client to connect to the server
via HTTPS (but it did not seem to be needed by my browser - it needed the
IE options update described in point 2). On my system, 'cacerts' is
"C:\Program Files\Java\jre6\lib\security\cacerts". I had some trouble
adding my 'serverX' certificate to it, but the following keytool commands
work if you know the password for cacerts ('changeit' is the default I
believe):

keytool -export -alias serverX -file serverX.jks -storetype "PKCS12"
-keystore serverX.cer -keypass password
keytool -import -alias serverX -file serverX.jks -noprompt -trustcacerts
-keystore "C:\Program Files\Java\jre6\lib\security\cacerts"
(when prompted for password give ‘chageit’)

The first command exports the certificate from PKCS12 format into X.509
(JKS) format, which is what cacerts needs. In my case, I had to use
KeyMan to set the password for the 'cacerts' file (I set it back to the
default of 'changeit'), so when I ran 'keytool -import ...' I could enter
the correct password. There may be a better/easier way to do this.

4) In your Java Restlet server program, in addition to the standard
Restlet jar files, you also need jar files for HTTPS. The only HTTPS
connector I could get to work correctly was 'Simple', which uses these jar
files:

lib/com.noelios.restlet.ext.simple_3.1.jar
lib/org.simpleframework_3.1/org.simpleframework.jar
lib/com.noelios.restlet.ext.ssl.jar
lib/org.jsslutils_0.5/org.jsslutils.jar

(Grizzly compiled and ran, but gave inconsistent results - appeared to be
missing requests; Jetty threw an error saying it couldn't register
'AjpServerHelper').

5) Your Restlet server code should then look something like this:

package com.jpc.samples;

import org.restlet.Component;
import org.restlet.Server;
import org.restlet.data.Parameter;
import org.restlet.data.Protocol;
import org.restlet.util.Series;

public class SampleServer {

public static void main(String[] args) throws Exception {
// Create a new Component.
Component component = new Component();

// Add a new HTTPS server listening on port 8183
Server server = component.getServers().add(Protocol.HTTPS, 8183);

Series parameters = server.getContext().getParameters();
parameters.add("sslContextFactory",
"com.noelios.restlet.ext.ssl.PkixSslContextFactory");

//use com.noelios.restlet.util.DefaultSslContextFactory instead of PkixSslContextFactory
parameters.add("keystorePath", "serverX.cer");
parameters.add("keystorePassword", "password");
parameters.add("keyPassword", "password");
parameters.add("keystoreType", "PKCS12");

// Attach the sample application.
component.getDefaultHost().attach("", new SampleApplication());

// Start the component.
component.start();
}
}

The HTTP examples all show
'component.getContext().getParameters().add(...) but this doesn't seem to
work for any HTTPS connectors. Using the
server.getContext().getParameters().add(...) does work but this doesn't
seem to be clearly documented anywhere.

If everything works, you should get a console message like this when you
start the server:

21-Nov-2008 00:08:44 com.noelios.restlet.ext.simple.SimpleServerHelper
start
INFO: Starting the Simple server

6) You can test it using a browser, going to https://serverX:8183/restlet>

7) If you want to write a Restlet client program you need to add the
following jar file (which has an HTTPS client connector):

com.noelios.restlet.ext.net.jar

8) Your Restlet client code then looks something like this:

package com.jpc.samples;

import java.io.IOException;

import org.restlet.Client;
import org.restlet.data.Form;
import org.restlet.data.Protocol;
import org.restlet.data.Reference;
import org.restlet.data.Response;
import org.restlet.resource.Representation;

public class SampleClient {

public static void main(String[] args) throws IOException {

// Define our Restlet HTTP client.
Client client = new Client(Protocol.HTTPS);

// The URI of the resource "list of items".
Reference samplesUri = new Reference("https://serverX:8183/sample");

// Create 9 new items
for (int i = 1; i < 10; i++)
{
Sample sample = new Sample(Integer.toString(i), "sample " + i, "this
is sample " + i + ".");
Reference sampleUri = createSample(sample, client, samplesUri);
if (sampleUri != null) {
// Prints the representation of the newly created resource.
get(client, sampleUri);
}
}

// Prints the list of registered items.
get(client, samplesUri);
}

Thursday, July 9, 2009

Converting JPG image to BMP image in Java

Hello,
Here is utility to convert JPG image to Bitmap image:

BufferedImage loadImg = ImageIO.read(new File("D:\\testimages\\test.jpg");
ImageIO.write(loadImg, "bmp", new File("D:\\testimages\\test.bmp"));

Problem with above conversion is, bitmap generated will always have 24bpp (bits per pixel).
I needed 1bpp bitmap image. Unfortunately google didn't help.

Here is what I tried,

BufferedImage loadImg = ImageIO.read(new File("D:\\testimages\\test.jpg"); //image to be converted to bmp

BufferedImage img = new BufferedImage(loadImg.getWidth(), loadImg
.getHeight(), BufferedImage.TYPE_BYTE_BINARY);
//create new image with type as TYPE_BYTE_BINARY for 1bpp, there are other options too for other bpp like 8, 24 etc
for (int y = 0; y < loadImg.getHeight(); ++y)
for (int x = 0; x < loadImg.getWidth(); ++x)
img.setRGB(x, y, loadImg.getRGB(x, y)); //copy RGB data from original image to new image
ImageIO.write(img, "bmp", new File("D:\\testimages\\test.bmp")); // now convert the above image to bmp

The above code gave me 1 bpp bitmap image.

Now image can be of any size, how to compress image to desired size ?
Here is answer:

//proved xfactor and y factor i.e width and heigth compression factor
AffineTransform tx = new AffineTransform();
tx.scale(xfact, yfact);
AffineTransformOp op = new AffineTransformOp(tx,
AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
img = op.filter(img, null);

You can calculate xfactor and yfactor from the desired width -height and actual width - height of the image.

More on image manipulation in java can be found at http://www.javalobby.org/articles/ultimate-image/

Thanks,
Anand

Tuesday, April 28, 2009

Using Websphere Dynamic Object Cache Feature

Hello,

Web sphere has provided very nice feature to cache your objects. Suppose you have some static data in database which does not gets updated frequently, but you need to access that data frequently. You can fetch data once in object and you can cache this object in webspheres DynamicObjectCache, so when required it can fetched from cache reducing expensive db calls.

Lets see how we can configure this cache in Websphere v6.1:

1) Login to admin console
2) Go to Resources -> Cache instances -> Object cache instance
3) Create new cache instance by provinding cache name, jndi name, cache size etc

Using object cache instance in your code:

InitialContext ic = new InitialContext();
DistributedMap dmap = (DistributedMap) ic.lookup("jndiName");

For DistributedMap you need "was-runtime-6.1.0.jar"

Now you can use this map to store and get your objects.
dmap.put("key", object);
dmap.get("key"); ...

Default size of this maps is 2000. You can set desired size from admin console.

More info on object cache setting can be found at :
http://publib.boulder.ibm.com/infocenter/wasinfo/v6r0/index.jsp?topic=/com.ibm.websphere.express.doc/info/exp/ae/udyn_cacheinstancescollection.html

Detailed article on the object cache can be found at:
http://www.entrepreneur.com/tradejournals/article/117988840_5.html

Thanks,
Anand

Tuesday, August 19, 2008

SCWCD 5.0 Help

Hi,

Here are some useful links for those who are planning to go for SCWCD 5.0 exam.

* Exam Syllabus and details :
http://www.sun.com/training/catalog/courses/CX-310-083.xml

* Books to be referred :
Head First Servlets and JSP by By Bryan Basham, Kathy Sierra, Bert Bates
(http://oreilly.com/catalog/9780596516680/)

* Forum to get your questions answered :
http://saloon.javaranch.com/cgi-bin/ubb/ultimatebb.cgi?ubb=forum&f=18

* After you are done with reading Head First Servlets and JSP, take mock exams from JWebPlus
http://www.enthuware.com/jwebplus/index.html

Hope this helps you too ...

Thanks,
Anand