Saturday, December 6, 2008

Fullscreen of Fedora10 installed on Vista using VirtualBox

Installing Fedora10 on Windows Vista using Virtual Box was very straight forward. I used a live disk or the iso initially and once the virtual machine booted up, I used the option of install to hard disk to avoid using the iso or the Live CD. The complex issue was that the screen size is too small i.e. the highest available resolution was 800 x 600. My Vista is using 1280 x 800, hence the Fedora on Virtual Box looked very small. I was able to make it full screen by following certain steps mentioned as below:
  • Run the Virtual Machine installed using VirtualBox. Go to the Devices menu and select the "Install Guest Addons . . ." option. Reboot the machine.
  • When the virtual machine is shutdown, you should be able to see that in the settings "CD/DVD-ROM" section will be configured for the "VBoxGuestAdditions.iso".
  • On the Virtual Machine startup, you shall be able to see this iso mounted and have icon on the desktop.
  • Before these Addons can be installed certain dependencies like make, gcc, kernel-headers and kernel-devel needs to be installed. These can be done using the following commands:
      • #] yum install make
      • #] yum install gcc-c++
      • #] yum install kernel-headers
      • #] yum install kernel-devel
  • When the dependencies are installed, we proceed installing the addons
      • #] cd /media/VBOXADDITIONS_2.0.6-39755/
      • #] sh ./VBoxLinuxAdditions-x86.run
  • Reboot the Virtual Machine. Now fire the commands to get the Display in the System > Administration menu.
      • #] yum install system-config-display
  • Now you can open the System > Administration > Display window. In the Hardware tab, select the VBoxVideo drivers in the Video Card configuration. Press OK two times and reboot the machine.
  • On restart, again open the Display window. If the desired resolution is not being displayed then you have to manually modify the /etc/X11/xorg.conf file.
  • Open the /etc/X11/xorg.conf file . Modify the Section "Screen". You need to add the Modes.
  •       Section "Screen"
             Identifier "Screen0"
             Device     "Videocard0"
             Monitor    "Monitor0"
             DefaultDepth     24
             SubSection "Display"
                 Viewport   0 0
                 Depth     24
                 Modes "1024x768"
             EndSubSection
          EndSection
  • Reboot the machine. On restart, you shall see the Virtual Machine will start with the new resolution. To have full screen press the host + F keys. By default the host key for Virtual Box is Right Control key.

Tuesday, November 11, 2008

Checking network connection using Java

At times it is required to check whether the machine is still connected to network or not. One way to find it using JDK1.6 by using the code is as below.
Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
while (interfaces.hasMoreElements()) {
    NetworkInterface nic = interfaces.nextElement();
    System.out.print("Interface Name : [" + nic.getDisplayName() + "]");
    System.out.println(", Is connected : [" + nic.isUp() + "]");
}
Additionally several new useful methods such as isLoopBack(), isPointToPoint() and many more have been added in JDK 1.6 release. Refer to the Javadocs for more information on NetworkInterface class in java.net package.

Tuesday, October 21, 2008

Best way to check for all alphabetic, alphanumeric or numeric strings

The best way of checking whether the string is a pure alphabetic, alphanumeric or numeric is to use the String class's matches method by using the regex pattern as a parameter.
  if ("!abc123".matches("[a-zA-Z]*")) {
      System.out.println("Pure alphabetic string");
  } else {
      System.out.println("Not pure alphabets");
  }

Sunday, October 5, 2008

Auto Injection of a Logger into Spring beans

Dependency injection using Spring provides an easy way of injecting logging implementations to beans configured using Spring. Spring inherently use (JCL) Jakarta Commons Logging which may cause class loading issues.
Refer to this post http://www.qos.ch/logging/classloader.jsp .
After searching for a while I found out that we can replace JCL with SLF4j by just replacing the commons-logging.jar with the SLF4j provided jcl-over-slf4j.x.x.x.jar implementation (Please add the required dependencies). SLF4j provides a lot of good features over good old logging implementation.
Please refer to http://www.slf4j.org.
Not going into further details lets start with our implementation of
Logger. The first step is to create a Logger annotation. The Logger annotation is shown below.

/**
* Indicates Logger of appropriate type to
* be supplied at runtime to the annotated field.
*
* The injected logger is an appropriate implementation
* of org.slf4j.Logger.
*/
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

@Retention(RUNTIME)
@Target(FIELD)
@Documented
public @interface Logger {
}
Now lets define a class that actually does the job of injecting the logger implementation.
/**
 * Auto injects the underlying implementation of logger into the bean with field
 * having annotation Logger.
 * 
 */
import java.lang.reflect.Field;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.util.ReflectionUtils;

import static org.springframework.util.ReflectionUtils.FieldCallback;

public class LoggerInjector implements BeanPostProcessor {

 public Object postProcessAfterInitialization(Object bean, String beanName)
   throws BeansException {
  return bean;
 }

 public Object postProcessBeforeInitialization(final Object bean,
   String beanName) throws BeansException {
  ReflectionUtils.doWithFields(bean.getClass(), new FieldCallback() {
   public void doWith(Field field) throws IllegalArgumentException,
     IllegalAccessException {
    // make the field accessible if defined private
    ReflectionUtils.makeAccessible(field);
    if (field.getAnnotation(Logger.class) != null) {
     Log log = LogFactory.getLog(bean.getClass());
     field.set(bean, log);
    }
   }
  });
  return bean;
 }
}
Using it is even simpler. Just add the Logger annotation created above to the Log field in the required class. The class DemoBean below shows a field annotated this way. The import class Log is actually present in the jcl-over-slf4j.x.x.x.jar and does not depend on the JCL anymore.
import org.apache.commons.logging.Log;

public class DemoBean {

 @Logger
 private Log log;

 public void doSomething() {
  log.info("message");
  log.error("Lets see how the error message looks...");
 }
}
Just define the above bean in your spring application context defition. (I used XML configuration). Also you need to define a bean using the class LoggerInjector. Application contexts can auto-detect BeanPostProcessor beans in their bean definitions and apply them before any other beans get created.

Thursday, September 18, 2008

Solution to the issue with List's in wsimport generated POJO classes

This topic is in extension to " It is not necessary to use wsimport generated POJO Files " post on this blog. Lets consider that our Employee class has another property called addresses . This addresses property is a List of strings. So our modified Employee shall look like:
import java.util.List;

public class Employee {
 private int age;
 private String name;
 private List<String> addresses;

 public Employee() {
 }

 public Employee(int age, String name, List<String> addresses) {
  super();
  this.age = age;
  this.name = name;
  this.addresses = addresses;
 }
 
 //write getter setter for properties to comply to Java Bean/POJO standard
}
and the Web Method is:
@WebMethod
 public Employee printEmployee(Employee e) {
  System.out.println(e.getName() + " - " + e.getAge() + " - " e.getAddresses);
  return e;
 }
As a result of generating the client using wsimport, the generated Employee looks like:
@XmlAccessorType(XmlAccessType.FIELD) 
 @XmlType(name = "employee", propOrder = {  "addresses",  "age",  "name" }) 
 public class Employee {  
  @XmlElement(nillable = true)  
  protected List addresses;  
  protected int age;  
  protected String name;
 }

and strangely enough there is no setter method for the list of addresses. There is a clear explanation for the same in the comments above the getter for the addresses property as:
This accessor method returns a reference to the live list, not a snapshot. Therefore any modification you make to the returned list will be present inside the JAXB object. This is why there is not a <CODE>set</CODE> method for the addresses property.
Solution: But this doesn't mean that this is a dead end. As mentioned in the original blog, you can replace the generated Employee class with the one that you used in the Web Service. With that you shall have the setter method for addresses list and the client invokes the Web Service perfectly.

Monday, September 15, 2008

Exposing JAX-WS web service using Spring

We start by creating a web project in Eclipse. I used Sysdeo Tomcat plugin.This will create a basic web application structure. Note that this does not create a web.xml file in the WEB-INF folder.
Add the following jar files to the WEB-INF\lib folder

activation.jar
commons-collections.jar
commons-logging.jar
FastInfoset.jar
http.jar
jaxb-api.jar
jaxb-impl.jar
jaxb-xjc.jar
jaxws-api.jar
jaxws-rt.jar
jaxws-spring-1.7.jar
jsr173_api.jar
jsr181-api.jar
jsr250-api.jar
resolver.jar
saaj-api.jar
saaj-impl.jar
sjsxp.jar
spring.jar
stax-ex.jar
streambuffer.jar
xbean-spring-2.8.jar

You are required to download the jaxws-spring-1.X.jar from https://maven2-repository.dev.java.net/source/browse/*checkout*/maven2- repository/trunk/www/repository/org/jvnet/jax-ws-commons/spring/jaxws-spring/1.8/jaxws-spring-1.8.jar?rev=3913 (This is the latest available version. I used 1.7 version.)
If you are using Java SE 6 some of the jars may not be required. Also if you need to use the latest version of JAX-WS with Java SE 6 you will need to use the endorsed mechanism for loading the JAX-WS libraries.I am using Java SE 5. Here is the simple web service class:

import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.jws.soap.SOAPBinding.Style;
import javax.jws.soap.SOAPBinding.Use;

/**
* Please run the wsgen if you are using Style.DOCUMENT
* Style.RPC used only for demo purpose.
* @author
*
*/
@WebService
@SOAPBinding(style = Style.RPC, use = Use.LITERAL)
public class HelloService {

   @WebMethod
   public String sayHello(@WebParam(name="name")String name) {
       return "Hello " + name;
   }

}
Create an applicationContext.xml file in the WEB-INF folder as shown.


   
   

   

Create a web.xml file in the WEB-INF folder and add the following entries to it.

    contextConfigLocation
    /WEB-INF/applicationContext.xml




   
       org.springframework.web.context.ContextLoaderListener
   




   jaxws-servlet
   
      com.sun.xml.ws.transport.http.servlet.WSSpringServlet
   



   jaxws-servlet
   /hello



This service is configured using the <wss:binding> tag in the applicationContext.xml file as described above. <wss:binding> definitions define what services are exposed to which part of the URL space. You can also use the nested syntax for the configuration as shown below:
 
    
        
    

Server side Handlers for the service can also be configured using the <ws:service> definition as shown below:




If the service uses more than one handler, handlers can be nested.

   
       
       
   

Deploy the web project on tomcat (tested on Tomcat 6.0). The service WSDL can be accessed using the following URL http://<your-ip>:<tomcat-port>/<project-name>/hello?wsdl
Also I would suggest to have a look at Apache CXF.

Thursday, September 11, 2008

Using annotated classes as web method params or return types

Some time back one of my friends was writing a web service in which certain web methods either returned or received Entity classes as parameters. When ever the wsgen command was fired an error as below was generated:
C:\eclipse\workspace\TopLinkExample\bin>wsgen -cp . service.TopLinkImpl .\org\acme\entity\Order.class: warning: Cannot find annotation method 'name()' i n type 'javax.persistence.Table': class file for javax.persistence.Table not fou nd .\org\acme\entity\Order.class: warning: Cannot find annotation method 'strategy( )' in type 'javax.persistence.GeneratedValue': class file for javax.persistence. GeneratedValue not found Problem encountered during annotation processing; see stacktrace below for more information. java.lang.NullPointerException at com.sun.tools.internal.ws.processor.modeler.annotation.WebServiceAP.i sSubtype(WebServiceAP.java:418) at...
After pondering for a while we figured out that the required classes (persistence related jars) were not in the class path.
So the following command got our stuff working:
C:\eclipse\workspace\TopLinkExample\bin>set CLASSPATH=%CLASSPATH%;C:\eclipse\wor kspace\TopLinkExample\lib\ejb3-persistence.jar;C:\eclipse\workspace\TopLinkExamp le\lib\jboss-ejb3x.jar;C:\eclipse\workspace\TopLinkExample\lib\toplink-essential s.jar;.; C:\eclipse\workspace\TopLinkExample\bin>wsgen -cp %CLASSPATH%;. service.TopLinkImpl
Even though this seems to be a very simple problem, during the time we were searching for the solution, we found that most of the people had this problem and didn't know the solution, whereas the -cp . in the wsgen command was going unnoticed.

It is not necessary to use wsimport generated POJO Files

When we have a Web Service in which we either pass the POJO object as a parameter or as a return type, by running wsimport command in order to generate Web Service Client similiar POJO classes are generated.
Suppose you have a Web Service with a Web Method that takes and returns a POJO of Class Employee:-
public class Employee {
 private int age;
 private String name;

 public Employee() {
 }

 public Employee(int age, String name) {
  super();
  this.age = age;
  this.name = name;
 }
 
 //write getter setter for properties to comply to Java Bean/POJO standard
}
and the Web Method is:
@WebMethod
 public Employee printEmployee(Employee e) {
  System.out.println(e.getName() + " - " + e.getAge());
  return e;
 }
On generating the client, an Employee POJO is automatically generated but with some XML stuff and no constructor i.e. default constructor:
@XmlAccessorType(XmlAccessType.FIELD)  
 @XmlType(name = "employee", propOrder = {"age", "name"})  
 public class Employee {  
  protected int age;  
  protected String name;  
  // Setters and Getters for the properties are also generated 
 }
There seems to be two things about this generated POJO that irritates me:
  1. The newly generated Employee POJO has a lot of XML stuff that does not do any work in service invocation.
  2. I miss the constructor that takes in values for the POJO i.e. new Employee("name", 23);
Solution is simple:- Delete the generated POJO's from the client generated by wsimport command and copy the POJO's from the Web Service side to the generated client code. The package name of the POJO need not be the same on the Web Service and the Client side i.e. on the Web Service it can be pack.Employee where as in client it can be client.Employee. It works without any problems.

Monday, September 8, 2008

Setting network b/w Linux machines using USB cable

To setup the USB network between two linux machines perform the following steps :- 1) Attach both the Linux machines using a USB cable. 2) Open the terminal window on each of the machines and type the following command (On first machine) ]# ifconfig usb0 10.100.10.101 netmask 255.255.255.0 (On second machine) ]# ifconfig usb0 10.100.10.102 netmask 255.255.255.0 Once done, try to ping the other machine using the assigned ip i.e. 10.100.10.101. This technique has been tested with two machines with Fedora 9 on one machine and busybox on other. It should be able to work on other combinations of linux too.

Sunday, September 7, 2008

Java Socket client issue on Linux

In the case that the socket client is on the windows and server on linux & the server goes down, the client on windows identified immediately and gives an exception. For a scenario vice versa i.e. socket client on linux and server on any other machine (currently tested on windows), the client waits for too long for a timeout. To deal this situation instead of opening a socket client like:
 Socket socket = new Socket(“10.1.25.186”, 8080);
You should use:
InetAddress inetAddr = InetAddress.getByName(“navnit.tempo.local”);  
SocketAddress socAddr = new InetSocketAddress(inetAddr, 8080);  
Socket socket = new Socket();  socket.connect(socAddr, 5000); // 5000 is the timeout in millis.

Extracting text from documents using Java

Extracting the text from the HTM/HTML document i.e. pulling all the text except the HTML tags is done as:
URL url = new URL("http://localhost:8080/index.jsp");  
EditorKit kit = new HTMLEditorKit();  
Document document = kit.createDefaultDocument();  
kit.read(url.openStream(), document, 0);  
System.out.println(document.getText(0, document.getLength()));
For PDF text extraction use pdfbox from www.pdfbox.org
URL url = new URL("http://localhost:8080/Document.pdf");  
PDDocument document = PDDocument.load(url.openStream());  
PDFTextStripper pdfStripper = new PDFTextStripper();  pdfStripper.setSortByPosition(false);  
pdfStripper.setStartPage(1); //from which page to start  
pdfStripper.setEndPage(3);  //on which page to end
System.out.println(pdfStripper.getText(document));  
document.close();
For MS Office Suite documents text extraction use Apache POI ( http://poi.apache.org/ ) Sample code for extracting text from a .doc file is as follows:-
POIFSFileSystem doc = new POIFSFileSystem(new FileInputStream("c:/Resume.doc"));
WordExtractor extractor = new WordExtractor( doc );
System.out.println(extractor.getText());
A good article on the same can be found at http://www.informit.com/guides/content.aspx?g=java&seqNum=354

Precision subtraction of floats

The normal subtraction of the double values in java result in a very long answer e.g. System.out.println(0.123 - 0.100); will result in 0.022999999999999993 as opposed to the expected 0.023. The Math.round function won't work here as it Returns the closest long/int to the argument.This precision problem can be fixed using the BigDecimal class.
BigDecimal first = new BigDecimal(0.123);
BigDecimal second = new BigDecimal(0.100);
System.out.println(first.subtract(second, new MathContext(2)));
The above program rounds off the answer to a precision of 2. i.e. the result will be 0.023.

Socket connection via proxy

To make the hits to internet programmatically via a proxy, you need to launch the program with the following JVM arguments. The program ConnectionTest contains the code to connect to some server on the internet and if in order to do so it needs to go via a proxy then run it as follows.
 
>java -Dhttp.proxyHost=proxy2.temp.org -Dhttp.proxyPort=8888 pack.ConnectionTest

Running the above code without the JVM arguments, it won't connect.

Generating same hashcode for similiar objects

Always override hashCode method if you are overriding the equals method of a java class. A POJO containing the same values in the properties can generate different hashCodes by default. If you need a way to generate the same hashCodes for POJO’s with same properties, instead of writing your own logic like adding properties or any other method, consider using apache’s commons-lang class HashCodeBuilder. This is specially worth considering if the objects are being added to data structures that use hashing mechanism for storing objects e.g. HashSet, HashMap, etc.

@Override  
public int hashCode() {
    return HashCodeBuilder.reflectionHashCode(this);
}

Wednesday, July 9, 2008

Reasons I like Wicket

I have been using Struts for a long time now. Also I have used other frameworks like JSF and WebWork. But Wicket seems to a breeze of fresh air. Lots of information is already available on Wicket and how it compares with other frameworks in general, so here I will try to focus on what I experienced. 1. Wicket uses plain Java with plain HTML. Goodbye to XML configuration files for building web applications (web.xml still remainsJ). You just need a good IDE. NetBeans and Eclipse already have some plug-in support to facilitate RAD.

2. Creating a component in Wicket is really easy and requires writing an HTML file and a plain Java class. Being a component oriented framework reusability of components can be achieved easily. In other frameworks reuse of components at the UI layer has been a big hassle. In wicket you make subclasses of existing components (e.g. Panel) and provide your own version of it leading to an OO design.

3. Wicket imposes minimal requirements on the mark-up templates. It does not introduce any special syntax to HTML. It extends HTML in a XHTML standards way via Wicket namespace. Thus the nice side-effect of using Wicket is a XHTML compliant web page. This promotes the almost as is use of templates from the UI designers. Changes if required in later stages can be done by UI designers easily in their favourite IDE. I’m sure that this is a big deal for most development teams. Wicket renders clean HTML code which can later be used for making adjustments to the UI.

4. Wicket provides a large set of components, not to forget their Ajax counterparts. Developing Ajax enabled applications has never been easier. If advanced functionality is required on top of the existing one existing components can be extended to build new custom components. Libraries for integration with well know JavaScript frameworks like script.aculo.us, Prototype and DOJO also exist. All of the above in few minutes with a few lines of Java code. The custom components and ideas are shared and thus the component palette is ever increasing.

5. Out of the box Ajax support is the most killer feature of Wicket. I tried playing around with DOJO and also DWR in some of my Struts applications. But the AJAX support in Wicket is refined with virtually no JavaScript to write. The very useful Ajax debug popup that automagically appears on your web pages in development mode. So using Ajax is as simple as telling Wicket that instead of showing or hiding a component using a full-page refresh do that using Ajax partial-updates to a page. And it just works on any kind of component.

6. Wicket has some cool features I explored out of necessity. Unlike other frameworks like Struts where you have to choose say commons-fileupload and manually include the JAR, I was pleasantly surprised to see that Wicket supports multipart forms / file uploading out of the box. Wicket also provides a download file link component specifically for this purpose. You can get those bookmarkable “friendly URLs” with the use of URL mounting feature provided in Wicket. Wicket provides a good form binding support for POJO’s. Component validation support in Wicket is good with Ajax validation easy to implement.

7. Very active community.

8. Fairy good documentation with working sample code.

Sure there is some learning curve but I think it’s worth the effort. Wicket is an excellent framework and seems that it has been developed keeping in mind the problems a common development team faces. Enjoy J

Friday, July 4, 2008

Singleton In Different Way

public class Singleton {
    private Singleton() {
    }
    private static class SingletonHolder {
        private static final Singleton singleton = new Singleton();
    }
    public static Singleton getInstance() {
        return SingletonHolder.singleton;
    }
}
Whenever a class is first loaded by JVM it's static variable and static initialiser bloacks are executed. In the above example when the class Singleton is loaded by the JVM, the class goes through initialization. Since the class does not have any static variables and initializer blocks, the initialization completes simply. The JVM will not load the static class definition SingletonHolder within Singleton class until you touch something in the SingletonHolder class. Hence the static variable is not initialized until the JVM determines that SingletonHolder must be loaded or executed. The static class SingletonHolder is only executed when the static method getInstance is invoked on the class Singleton.
The first time when this class will be loaded by the JVM the static variable singleton will be initialized by executing the (private) constructor for the outer class Singleton. As per the Java Language Specification (JLS) the class initialization phase is guaranteed to be serial, i.e., non-concurrent, no further synchronization is required in the static getInstance method during loading and initialization. As the initialization phase initializes the static variable singleton in synchronized manner, all subsequent concurrent invocations of the getInstance will return the same correctly initialized singleton without incurring any additional synchronization overhead.

Monday, June 30, 2008

Few Tips On Serialization

  1. Static fields are like the Transient fields and they are not serialized with the object. The reason is that they are associated with the class rather then object's state.
  2. If we have a sub class which extends a super class and implements Serializable interface and super class doesn't implement Serializable interface then:
  • While serializing the sub class object, only its state excluding the super class visible variables will be serialized.
  • While de-serializing the sub class state will restored from the serialized data. The super class state will be initialized by invoking the no-arg constructor of super class.
  • The no-arg constructor should be visible to the sub class otherwise an exception will be thrown at runtime.
  1. If the super class also implements Serializable interface then the state of the subclass object including the super class visible variables will be serialized. And while de-serializing the sub class and super class state will be restored from the serialized data only instead of no-arg constructor for super class.
  2. If there is an arg constructor in the super class and there is no default constructor then the subclass constructor should specify the call to the specific super (arg...) constructor. Otherwise there will be a compile-time error.

Saturday, April 26, 2008

Basic Security on JAXWS 2.0

You can apply basic realm security to your webservice. In the web.xml, you have to paste certain tags given below. Don’t apply the Basic Realm for GET. The client code makes a GET request to get the port. Apply Basic Realm for POST. The client code will put the authentication values in the headers as:
 Calculator calculator = (new CalculatorService()).getCalculatorPort(); 
 BindingProvider provider = (BindingProvider) calculator; 
 provider.getRequestContext().put(BindingProvider.USERNAME_PROPERTY, "navnit"); 
 provider.getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, "leo");
The web.xml section is as below:

 
  Protected Site
  
  /*
  
  DELETE
  POST
  PUT
 
 
 
  
  CalculatorUser
 




 BASIC
 Example Basic Authentication




 Test role
 CalculatorUser

You also need to create a role in the tomcat-users.xml and a user/password.


Change the foreground and background selection color of a JMenuItem.

JCheckBoxMenuItem standard = new JCheckBoxMenuItem(); 
standard.setUI(new chkboxMenuItem(menuSelFore,menuSelBack)); 

class chkboxMenuItem extends BasicCheckBoxMenuItemUI { 
    public chkboxMenuItem(Color selFore,Color selBack) { 
        selectionForeground = selFore; 
        selectionBackground = selBack; 
    } 
}

Changing the swing submenu expanding orientation

To set the orientation of the menu to open the submenus in the left direction ( <-- ) instead of default right direction ( --> ) use :
JMenu prefMenu = new JMenu();
prefMenu.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);

Wednesday, January 16, 2008

Using JAXWS 2.1 on Java 6.0

To use JAX-WS 2.1 on Java 6.0 and Tomcat 6.0, place all the libraries in the JAXWS 2.1 in “<TOMCAT_HOME>\endorsed” directory. To run the client, you have to have the JAX-WS 2.1 library (jaxb-api.jar) in your bootstrap. For this put the jaxb-api.jar from the JAX-WS 2.1 distribution in the "<JAVA_HOME>/jre/lib/"endorsed.

Friday, January 11, 2008

Why SiteMesh instead of Tiles?

  1. SiteMesh is much easier to configure and use (less typing and easier to understand)
  2. Using Tiles, you need to have your forwards go to a "tiles page" versus the direct JSP. SiteMesh takes the approach that your page (your JSP) doesn't even know or care that it's being decorated.
  3. Using Tiles, each individual page you want to go to has to be associated with a layout - Major pain! Every time you create a new JSP that you want to forward to, you have to create another tiles definition and associate it with a layout and forward to the Tile page (versus the JSP). With SiteMesh you can simply set up a URL pattern and all your pages are decorated with the layout you choose.
On the other hand there is downside of using SiteMesh. SiteMesh stores the entire content of your HTML body into memory before it decorates it. If you have some very large pages, such as might happen in a reporting application where you don't have pagination implemented and end up with one large page of rows, you could end up with severe memory problems.
You can read this http://today.java.net/pub/a/today/2004/03/11/sitemesh.html post by Will Iverson about how to use SiteMesh.