Rules about classpath

Source : http://mindprod.com/jgloss/classpath.html

Rules About Classpaths

  1. Simply copying or moving your jar files to the ext directory pointed to by the system property java.ext.dirs =C:Program Filesjavajre6libext automatically puts them on the classpath without having to mention them explicitly. This is a great way to prune back an overblown classpath. It is safest to put your jars in all the ext directories:
    where to look for ext directories :

    You never know for sure where your javac.exe or java.exe is going to look. Grrr. You can change the location of the

    java.exe -Djava.ext.dirs=C:mylibs mypackage.MyClass

    See the ext dirs entry for details.

  2. Class names are always fully qualified with the complete package name. There is no way to ever abbreviate the higher levels.
  3. Each element of the CLASSPATH provides a starting point to look for a fully qualified package and class name, identical to the way it appeared in the package or import statement.
  4. If the element of the CLASSPATH is the name of a directory, Java will look in that tree for directory names matching the package name structure. It looks at one place only. It does not search. The class file sought must be filed under the one and only precise fully qualified pathname, or it won’t be found. It wants to find a *.class file (or*.java file), at the precisely correct spot in the directory tree. You must get an exact match on the fully qualified name. The name of the directory specified in the CLASSPATH itself is totally immaterial in determining the package name.
  5. If the element of the CLASSPATH is a jar, Java will look in the internal directory structure of the jar for an exact match on the fully qualified name. It looks; it does not search. The class file sought must be filed under the one and only precise fully qualified pathname, or it won’t be found. The location of the jar is totally immaterial in determining the name of the package. If you peek inside the jar with WinZip you should see pathnames on each class file matching the package structure. Download and examine any of my jars and the corresponding source to see how it works.
  6. An alternative, ultimately more confusing way of looking at it, is that you specify part of the operating system’s name for a class file in the CLASSPATH and part in the package name. Java source imports and package statements, javac.exe and java.exe command lines specify only the fully qualified package name, not the higher order part handled by the CLASSPATH. The higher levels that are handled by the CLASSPATH (which could appear on the command line via -classpath option), are effectively invisible to your Java programs. However, you are not at liberty to shuffle levels of qualification between your import and classpath unless you adjust all your package statements and recompile as well.

Clustering J2EE Applications

All mission critical applications need to be have high Availability and Scalability features built-in. Any incident or outage in such applications can have huge implications – like business loss or legal issues faced by the company. Clustering helps in application scalability (through load balancing) as well as high availability (through failover).


Clustering J2EE Applications
Never assume that stand-alone applications can be transmit transparently to a cluster structure.
Most of the leading application server vendors like IBM (Websphere) and Oracle (BEA Weblogic) support clustering their servers and provide for built-in load balancing among them.




It might seem that Clustering is a deployment or server related activity and we as normal Java developers might not be concerned with it. This is not true. There are various aspects which the Java developers need to take care while working on design, coding and testing for creating cluster aware, scalable J2EE applications.


Figure 1: Visualize Clustering



Application Design and Coding Considerations
Below are some basic points to consider while developing and maintaining applications – which will ultimately be deployed in a clustered environment in production.


User Session
HttpSession object is responsible for maintaining user session across requests. Session object is tracked by a unique session id.


To provide transparent failover in a cluster, application servers need to ‘replicate’ session state on multiple servers. As a result, based on the vendor implementation, session id might vary across client requests.

  • ‘session id’ should not be used in an application for operations synonymous to user id or should not be used to mark any transaction because it may not remain same throughout the user session. For such purposes, user id would be a more appropriate choice.
  • All objects stored in the session must be made Serializable. If any Java object, say Hashtable or any user defined object, is to be kept in session then that object must implement java.io.Serializable interface.
  • Object serialization and de-serialization are very costly in performance especially in the database persistent approach. In clustered environment, storing large or numerous objects in the session should be avoided.
  • Updating data in HttpSession – While updating any session attribute, use HttpSession.setAttribute() explicitly. This call will make sure that updated object is reflected in all session copies maintained on different servers by the application server.
  • Setting and getting values to-from HttpSession – Deprecated APIs getValue(), putValue(), removeValue() should not be used. Instead getArribute(), setAttribute() and removeAttribute() should be used.

Static Variables and Singletons

  • Do not use static variables for any logic/data that is at an application level. Simple reason being that a variable value will not be available to the JVMs in other machines and next client request can go to any server.
  • Avoid use of Singleton class that encapsulates logic for whole application (across JVMs in a cluster). In a single machine on one JVM singleton class will work. But in a cluster with multiple JVMs, having single instance will not be possible.

Data Caching

  • Application may have data cached in memory from secondary storage like database. It would be much faster to access reference data and data that doesn’t change frequently from memory.
  • Synchronize Cache – In a clustered environment, each JVM instance will maintain its own copy of the cache, which should be synchronized with others to provide consistent state in all server instances. Sometimes this kind of sync will bring worse performance than no caching at all.

File Access


Although not recommended by the J2EE specification, the external I/O operations are used for various purposes.

  • Since components will be deployed across machines in a cluster, file system must be accessible in a uniform way to all the machines.
  • To achieve this, either common network file system (like SAN) could be mounted or
  • Files could be replicated on all the machines in a cluster.
  • Instead of a file, maintain required information in the database.
  • Application logging – If application uses file to log messages then evaluate whether single file per cluster or separate file per server in cluster is required to be maintained.

Other Services

  • There are some functionalities and services which makes sense in stand-alone mode only. For example Timers/Schedulers and Email Notifications Services. These services are trigged by events instead of requests, and should only be executed only once. These services are hard to migrate to a cluster environment.
  • Some products have prepared for such services. For example, JBoss uses “clustered singleton facility” to coordinate all the instances to guarantee to execute these services once and only once. Spring Quartz (batch scheduler API) also provides clustering support.

Third Party Software


In an enterprise application usually other software/tools are used like Rule Engines, OR Mapper, third party cache manager, messaging software, logging component etc. Some of these third party software may not support clustering. This should be looked upon at design time before selecting these tools.


Application Testing Considerations


Test plans should be created to test application in cluster environment. Test cases should cover cluster objectives, which are load balancing, scalability and failover. To test cases, it might be required to create test stubs. Test cases should also cover any application specific and cluster sensitive services like file access, static data caching, and Singleton.


Brief Terminology


Scalabilty – Scalability refers to a system’s ability to support fast increasing numbers of users. One way to is to add resources (memory, CPU or hard disk) to a server. Clustering allows a group of servers to share the heavy tasks, and operate as a single server logically.
High Availability – Single server solution to scalability (adding more resources) is not a robust one because of its single point of failure. It is required that mission critical services are accessible with reasonable/predictable response times at any time. Clustering is a solution to achieve this kind of high availability by providing redundant servers in the cluster in case one server fails to provide service.
Load balancing – Load balancing is one of the key technologies behind clustering, which is a way to obtain high availability and better performance by dispatching incoming requests to different servers. In addition the load balancer should perform other important tasks such as “session stickiness” to have a user session live entirely on one server and “health check” to prevent dispatching requests to a failing server.
Fault Tolerance – Highly available data is not necessarily strictly correct data. A fault tolerant service always guarantees strictly correct behavior despite a certain number of faults.
Failover – Failover is a key technology behind clustering to achieve fault tolerance. By choosing another node in the cluster, the process will continue when the original node fails.


References:
• http://www.ibm.com/developerworks/websphere/library/techarticles/0606_zhou/0606_zhou.html


• http://onjava.com/pub/a/onjava/2004/07/14/clustering.html

Premature end of file when running junits

Problem:

Premature end of file error when running Junits

[junitreport] [Fatal Error] :-1:-1: Premature end of file.
[junitreport] The file /tmp/repository/Yogesh/task2652_story1984/modulesmgr/junit_report/out/xml/TEST-com.coresecurity.ctrlsvc.modules.ModulesImportAndBasicCRUDTest.xml is not a valid XML document. It is possibly corrupted.

Observations:
1) TESTS-testsuites.xml was coming out to be empty.
2) The resulting xml file was getting too large in size.

Solution:
Hibernate logging was enabled which was leading to large size of XML.
We disabled logging in config.xml as given below
Earlier it was true, we made it false








org.hibernate.dialect.MySQL5InnoDBDialect
false
update
true
5
20
300
50
3000


Equals and hashCode mystery resolved

Equals and hashCode mystery resolved

Hi,

Try executing the code in the attached files first by commenting the hashcode() method in Test1.java and then by uncommenting.

The output differs.

In first case the objects are equal based in the criteria defined in the overridden equals method but when u try to put these two “equal” objects in a hashtable it allows you inspite of the fact the keys (objects) are equal.

Here: both objects are equal but hashtable consider them different so allows two entries.

In second case when we have overridden the hashcode() method for objects of class Test1 uncommented then the hashtable doesn’t allow to put the equal objects twice.

Here: both objects are equal and hashtable consider them equal because of overridden hashtable method so allow only one entry

import java.util.Hashtable;
public class RunTest
{
public static void main (String args[])
{
Test1 test1= new Test1("start", 10);
Test1 test2= new Test1("start", 10);
Hashtable ht = new Hashtable();
System.out.println("test1.hashCode=" + test1.hashCode());
System.out.println("test2.hashCode=" + test2.hashCode());
System.out.println("test1.equals(test2) = " + test1.equals(test2));
if(test1.hashCode()!=test2.hashCode())
{
System.out.println("hashCodes are different --> means Objects are unequal");
if(test1.equals(test2))
{
System.out.println("Please note test1.equals(test2) returns " + test1.equals(test2));
System.out.println("Still it considers the objects to be unequal");
}
System.out.println("and adds it to hashTable");
}
else
{
System.out.println("hashCodes are same");
System.out.println("means");
System.out.println("Objects can be equal or unequal");
System.out.println("Now it'll check equals method");
System.out.println("test1.equals(test2) = " + test1.equals(test2));
if(test1.equals(test2))
{
System.out.println("Since equals method returns true, it'll not allow 2 equal elements to be added");
}
}
ht.put(test1,"first");
ht.put(test2,"second");
System.out.println("the size of ht is :" + ht.size());
}
}
public class Test1
{
String s;
int t ;
public Test1(String s, int t)
{
this.s= s;
this.t=t;
}

public boolean equals(Object obj)
{
if(this == obj)
{
return true;
}
if(!(obj instanceof Test1))
{
return false;
}
Test1 test = (Test1)obj;

return (s.equalsIgnoreCase(test.s) && t==test.t);
}

public int hashCode()
{
return (this.s.hashCode() + this.t);
}
}

use OnClick with caution

JSP Code :

<a href="abc.jsp" onclick='’>LOGOUT

The above statement gets converted to Servlet CODE :


out.write("<a href="abc.jsp" onclick='");

session.invalidate();

out.write("'>LOGOUT");


Conclusion:

What ever scriplet you write in onclick, will get executed every time the JSP is called. Not only on onclick as can be wrongly assumed.

BUG in struts2

Actually I used

Now, I have specified type as button, so I expected that it will not go to action on click on the button.

But what happens is

when I click on button, it asks if I want to close the window,
Now, even I click NO, it still goes to action specified in form.

Solution : This is a BUG in struts2.

the HTML tag that is generated is something like:

<button type="submit” id=”test_0″ value=”Submit” class=”button positive save”>Submit

Please note that we have given type=button in s:submit tag, and the HTML generated still contains type=submit.

Can get some information from http://www.ericmmartin.com/struts-2-bug-submit-button-tag-rendering/

Internationalization tips for JSP

In order to display the complex script characters like Japanese, Chinese, etc in the browser window, the following changes need to be made at the beginning of each JSP file:

<%@ page language="java" 
contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

Wherever input controls are present, the following additional steps need to be taken:
Add the following code before reading any parameters in the previous JSP file:

request.setCharacterEncoding("UTF-8"); // Set the request encoding

While sending output to a browser:

response.setContentType ("charset=UTF-8");

Color of Error Messages in struts 2

Problem:

I am working on struts 2.
I have one text field and have put validation (with xml)on the text field if its blank, throw an error.
But the field error I am getting is in black colour.
Does anyone have idea how to display the field error in red colour.

Solution:

U can the use the following tag in your .css Stylesheet file

.errorMessage {
color: red;
font-size: 0.8em;
}

And include this Stylesheet in the file where u have the text field.

Source : http://www.roseindia.net/struts/struts2/validations/Struts2-annotations.shtml

Can wait be resume without Notify??

A thread can also wake up without being notified, interrupted, or timing out, a so-called spurious wakeup. While this will rarely occur in practice, applications must guard against it by testing for the condition that should have caused the thread to be awakened, and continuing to wait if the condition is not satisfied. In other words, waits should always occur in loops, like this one:

synchronized (obj) {

while (someCondition()==false)

obj.wait(timeout);

... // Perform action appropriate to condition

}

Reading data from Internet

This URL seems to be pretty useful for this purpose.

http://java.sys-con.com/node/39248

Always use BufferedReader while reading InputStreams. Not using BufferedReader would lead to corrupt data and may not give correct results.

Code snippet is as given below :


HttpURLConnection hpCon;
hp = new URL(url);
hpCon = (HttpURLConnection)hp.openConnection();
InputStream in = hpCon.getInputStream();
InputStreamReader inStream = new InputStreamReader(in);
BufferedReader input = new BufferedReader(inStream);

String tempString="";
while(true)
{

tempString = input.readLine();
if(tempString == null) break;
output.append(tempString);
}
hp = null;
hpCon = null;