Friday, January 29, 2010

Things to watch out for Java novices


In the process of learning Java one encounters many points to which a novice should pay special attention. Doing Sun tutorials obviously helps people to come to grips with some of these points but some salients points have been highlighted here in random order.
No constructor can have a return type (not even void).
We can override a private member of a superclass in the subclass with a private/public/protected member. Effectively it is not override as subclass is not even aware of the superclass private member and sees it as a new definition. The rules of overriding do not apply, so you can make this newly-declared-but-just-happens-to-match method declare new exceptions, or change the return type, or anything else you want to do with it.
No modifier means method has default access. Default is similar to protected. However in protected subclass can be in different package but in default access it has to be in the same package.
default = package; protected = package+subclasses access.
Protected member can be accessed through inheritance but not not through access to an instance of parent object, if it is in a different package. Once the subclass-outside-the-package inherits the protected member, that member (as inherited by the subclass) becomes private to any code outside the subclass.
There is never a case where an access modifier can be applied to a local variable. It will not compile. We can only use 'final' modifier for local variables.
A reference variable marked final can’t ever be reassigned to refer to a different object. The data within the object, however, can be modified, but the reference variable cannot be changed. There are no final objects, only final references.
If you declare a final instance variable, you’re obligated to give it an explicit value, and you must do so by the time the constructor completes.
Static methods can’t be overridden, they are hidden.
You can put as many classes in a source code file as you like, but only one (or none) can be public. The file name should match the name of the public class, but if no public class is in the file, you can name it whatever you like. The order in which the classes appear makes no difference.
Not having a proper main() method is a runtime error, not a compiler error!
All variables defined in an interface must be public, static, and final, ie only constants. If we don't give these modifiers or give only part of them, they are automatically given these three characteristics.
An interface is free to extend multiple interfaces.
An inner class instance has access to all members of the outer class, even those marked private.
Just because a series of threads are started in a particular order doesn't mean they'll run in that order.
sleep() and yield() static methods always affect the thread that's currently executing and not another thread.
If a thread goes to sleep, it holds any locks it has—it doesn't release them.
Default exception handler
– Provided by Java runtime
– Prints out exception description (e.getMessage())
– Prints the stack trace (e.printStackTrace()) , ie hierarchy of methods where the exception occurred
– Causes the program to terminate
Collections.disjoint(l1, l2) — determines whether two Collections are disjoint; that is, whether they contain no elements in common.
All enums implicitly extend java.lang.Enum. Since Java does not support multiple inheritance, an enum cannot extend anything else.
The constructor for an enum type must be package-private or private access.
An enum cannot be declared within a method.
As an inner non-static class is associated with an instance, it cannot define any static members itself. An inner class must be static to be called from static method.
Polymorphism doesn't apply to static methods.
Polymorphism only applies to instance methods and not instance variables
System class maintains aProperties object that describes the configuration of the current working environment. To maximize portability, never refer to an environment variable (extracted from System.getnnv) when the same value is available in a system property (extracted from System.getProperties). Use latter value.
For example, to get the value of path.separator, use the following statement: System.getProperty("path.separator");
System.exit, which terminates the Java virtual machine with an exit status, invokes SecurityManager.checkExit to ensure that the current thread has permission to shut down the application.
By convention, an exit status of 0 indicates normal termination of the application, while any other value is an error code.The exit status is available to the process that launched the application.
All byte stream classes are descended from InputStreamand OutputStream.
All character stream classes are descended from Readerand Writer.
To use line-oriented I/O use two classes BufferedReader andPrintWriter. Latter is used in servlets.
Channel I/O reads a buffer at a time.
There are four buffered stream classes used to wrap unbuffered streams:BufferedInputStream andBufferedOutputStream create buffered byte streams, whileBufferedReader andBufferedWritercreate buffered character streams. They improve I/O performance.
When you need to create a formatted output stream, instantiate PrintWriter, notPrintStream.
Data streams support binary I/O of primitive data type values (boolean, char, byte, short, int,long,float, and double) as well as String values. All data streams implement either theDataInput interface or theDataOutput interface.
Just as data streams support I/O of primitive data types, object streams support I/O of objects.
Using a int as a return type on byte input stream allows read()to use -1 to indicate that it has reached the end of the stream. We can use (char) cast to see the value of int read, ie int 65 is same as 'a' after cast. For line-oriented I/O use inputStream.readLine() != null to detect end of file.
Notice that DataStreamsdetects an end-of-file condition by catching EOFException, instead of testing for an invalid return value.
When a method accepts a varargs argument, you can pass it a comma-separated list of values or an array of values. The vararg has to be the last argument and there can be only one vararg.
String s = "Java"; s.concat( " Rules); System.out.println(s); will give 'Java' not 'Java Rules' as the output of s.concat(0 is not placed in our reference for s. To get 'Java rules' we have to say s = s.concat(). Without this syntax the newly created string has no reference. In the case of StringBuffer sb, sb,.append() will append the value without assigning to the reference.
Static variables are never saved as part of serialisation as they belong to class and not object.
If serializable subclass is serialised and parent is non-serialiazable then parent will have initial values as per creation of new object.
When using classpath the last directory in the classpath must be the super-directory of the root directory of the package, ie if package is com.my... then the classpath should have directory which has com as subdirectory.
Put jar file in jre\lib\ext and java finds it without specifying in classpath.
Static imports can be used when we want to use a class's static members.
Collection (singular) is an Interface, but Collections (plural) is a helper class.
equals() returns false if the wrapper object types are different. It does not raise a compiler error.
No inner class (non-static inner class) can have a static member.

Sunday, January 24, 2010

Java EE journey



As people are looking forward to new version of Java to arrive in March, I thought it would be a good idea to highlight where we are in Sun's own words. It has been a tremendous journey and becoming stronger by the day.

Thursday, January 21, 2010

Understanding inner classes

We are accustomed to classes having variables and methods. However in JDK1.1 inner classes were introduced. They are effectively a class nested within a class, hence also known as nested classes. Their introduction respected the design principles of encapsulation and cohesiveness. Any functionality which naturally merited a special class but was so intertwined with a given class that it was deemed logically necessary to define it within the context of that class gave birth to inner class. For example the event handling class is inextricably linked to GUI class so is a natural candidate for becoming an inner class. The key advantage is that the nested class instance has access to the instance members of the outer class, including those with private modifier. This power to access private members could be deemed to flout encapsulation.

On compiling the basic minimum Java code for an inner class

class TestOuter {
class TestInner {}
}

we get TestOuter.class and TestOuter&TestInner.class files. The class file name for the inner class makes it clear that it is within the context of outer class. These inner classes can be public, private, protected or default-package.

They come in four flavours:

- the normal inner class
- static nested inner class
- method-local inner class
- the anonymous inner class

1. The normal inner class

The normal inner class follows the code pattern below:

public class TestOuter {

private String name = "Rajeev";
public static void main(String[] args) {
TestOuter myOuter = new TestOuter();
// the syntax for instantiating inner class makes use of outer class object
TestOuter.TestInner myInner = myOuter.new TestInner();
myInner.innerMethod();
}

public class TestInner {
public void innerMethod() {
System.out.println("hello " + name + " from outer");
}
}
}

The code produces the output ‘hello Rajeev from outer’ and clearly shows the instantiation process and inner class object accessing private members of outer object. The key thing to note is that new is invoked on object of outer class. The instantiation of outer class does not automatically instantiate the inner class.

The inner class can access outer class variables with the same name with the syntax:

OuterClassName.this.variableName

Within inner class this refers to the inner class object so to get hold of outer class reference we need to use OuterClass.this

2. The static nested inner class

All the modifiers which are applicable to any member of outer class can be equally applied to inner class. Therefore when we use the static modifier on inner class it becomes the ‘static nested inner class’. Obviously an outer class can never be static.

public class TestOuter {
static class TestInner {}
}

The static just means that the inner class can be accessed without an object of the outer class. The syntax for reference to this static class is

TestOuter.TestInner n = new TesterOuter.TestInner();

We can then invoke any method of this static class on this object. However, the key is that a static inner class does not have access to the instance variable of outer class and not does it have access to non-static methods of outer class as there is no associated object of outer class.

3. The method-local inner class

When we place the inner class within a method of the outer class then we get a method-local inner class. No other method has access to this class. This class is most suitable for checking pre- and post-conditions in Design-By-Contract. Within the body of a method we can define an AssertionChecker class to check for the method’s conditions through assert mechanism. This way the initial value of all the variables required for post-condition check can be saved if necessary in the AssertionChecker object. For example in banking system we may be interested in saving the value of initial balance prior to depositing new amount to check that the post-condition of correct amount update has been met. With this approach, once the assertion mechanism is switched off it doesn’t have any side-effects.

public void myMethod(final int myVar) {
// a method-local inner class for checking pre- and post-conditions
class AssertionChecker {
// define variables so they don’t have side effect when we don’t need these checks
private int assertionVar;
boolean precondition() {…}
boolean postcondition() {…}
}
// check the method’s pre-condition
AssertionChecker check = null;
// cannot declare within assert so above reference has to be done outside
assert (check = new AssertionChecker()) !- null && check.precondition;
//
// code the method’s logic
//
// check the method’s postcondition
assert check.postcondition();
}

The parameter to myMethod was marked as final as this type of inner class only has access to method local variables thus marked and cannot access method’s other local variables. This requirement happens because the class can still exist while the method’s variables have been removed from the stack. Just as local variables do not have private, public, static etc modifiers, we cannot apply these to method-local inner class either.

4. The anonymous inner class

These nameless inner classes effectively subclass an existing class or implement an interface and the code just happens to follow the initiation.

Let us say we have an existing Animal class with an eat() method and we use the syntax

Animal myPet = new Animal() {public void eat() {
System.out.println(“The pet is eating”) }
}; // note the semicolon termination of the anonymous block

We now have myPet object which refers not to Animal but to an anonymous subclass of Animal. The runtime polymorphism comes in play whenever we invoke methods on myPet object.

Incidentally if Animal were actually an interface (OK its name would have been Animality) rather than class then the anonymous definition becomes the implementation of the interface. We could have this type of anonymous implementation in mrethods arguments as well. The syntax become myMethod(new Animal() {// definition}); Note the peculiar }); ending in the syntax. We can see how the logic for ActionListener be implemented within our GUI with each component using these type of anonymous classes.

myButton1= new JButton();

myButton.addActionListener(
new java.awt.event.ActionListener()
{
public void actionPerformed(java.awt.event.ActionEvent e)
{
// do something
}
}
);

The article should have given flavour of the number of ways we can use inner classes and their syntax.


Tuesday, January 12, 2010

Is SaaS a throw back to computer bureaux of yore?

Computer bureaux date back to the era when computers were expensive and batch processing and dumb terminals multiplexed into central mainframe to maximise usage were the norm. A discrete service like payroll or accounting systems was offered on a centralised server on time-sharing basis for multiple-clients and the client data was transferred via magnetic tapes and disks for batch processing. The charging was usage-based for the computer time needed. The SaaS offerings provide web-based, installation-free access to managed services on centralised hosts providing integrated applications like enterprise resource planning systems or customer relationship management. The latter are truly distributed offerings, whereby data from the central repository could be manipulated on the local PC. The charging is normally based on user population and concurrent users. The motivation in 60-70s was sharing expensive resources but nowadays concerns like availability, scalability, reliability and security are paramount. The disjointed, slow, batch and cumbersome approach of the bureaux has acquired 24x7 availability, responsiveness and seamless-integration in SaaS world. The whole burden of performing license-management, version-control, resilient-configuration, secure-access, disaster recovery etc is devolved on ASP which is more complex nowadays. We have moved from pseudo-parallelism of bureau to distributed, concurrent environment of SaaS. So despite the surface level similarity in their approach they are two distinctly different beasts. In both cases the application resides outside the enterprise but the expectations, operations, technology, rationale and scope are totally different.

The computers were bulky, slow and expensive resource in pre-70s so it made sense to share them for common business functions like payroll amongst a number of clients. The rapid advances in technology heralded advent of PC in 80s, then subsequent increase in memory availability, faster CPUs and faster communication speeds made it viable to have in-house LAN-based client-server offerings to support these functions. The PCs were cheap enough to allow individuals ownership without worrying about idle time. Also the business users sought decision-support systems to complement transactional systems and the IS/IT departments started in the companies thus fading time-sharing.

The complexity involved in deploying and upgrading software in distributed environment, the consequential difficulties in negotiating relevant licenses, the interoperability issues, ubiquity of browser-based client, fast-and-cheap communication, affordable scalability, the trend towards outsourcing etc have all aided the drive towards SaaS. Hardware and software technology is seen as purchasable commodity and the organisations prefer to concentrate on their core competencies, expecting secure and resilient service from experts. The ASPs also feel confident that benchmarks exist to provide requisite concurrency and performance from their server farms, allowing them to focus on their domain-expertise. Also the approach is usually cheaper than in-house solution when TCO is taken into account. All these factors mean that SaaS offerings will continue to grow in foreseeable future.

Tuesday, January 5, 2010

Use servlets and JSP judiciously

All the sizeable Java EE applications use a framework like Struts, Java Server Faces etc where the controller is invariably a servlet object. The key disadvantage of servlet technology is that even a minor modification to static content requires changes to the Java code to output HTML. The JSP overcomes this shortcoming by combining HTML and Java. The static part can be pure HTML where as the dynamic aspect can be managed by including code in JSP tags for directive, scripting and action. (Incidentally, JSP tag libraries and JSP expression language are preferred vehicles for including Java code into JSP nowadays). A combination of JSP and servlets provides horses for courses. Historically, the servlet technology is the forerunner to JSP for dynamic content and, unsurprisingly, each JSP page translates to servlet code prior to execution. Thus it is common to use both servlet and JSP technologies in applications as servlets are inevitable but JSP provides convenience, simplicity and ease of development. It also facilitates segregation of responsibilities amongst development teams as the web designers can focus on rather static presentation aspects in JSP whilst the Java developers concentrate on processing logic in servlets and custom tag libraries. This can be enforced by declaring some JSP pages as scriptless in the deployment descriptor of the application. Also in the prevalent model-view-controller architecture, the servlets act as controller whilst the JSP pages provide views. Both technologies are capable of invoking each other so we can focus on the best solution for the task at hand.

However, in the real world to create a truly interactive web application we will go a step further and use Java Server Faces (JSF) technology which builds on these two technologies. With JSF2.0, it is even deemed that JSP is deprecated for creating views.

Why P2P?

The peer-to-peer (P2P) software architecture has been instrumental in changing the landscape of the music industry. The drive by the music industry to have the free Napster file sharing service outlawed in 2004 to protect their intellectual capital points to the negative impact on their revenue. However, groups like Arctic Monkeys have seen it as an opportunity to deliberately share their demo CDs free of charge to build fan base with a little marketing outlay.

In pure P2P architecture all the participating computers have equal roles and can act as both client and server. There is no concept of centralised server so there is no single point of failure. Without any centralised server, the P2P application will keep track of users with installed software, locate them and search for the files in their P2P storage area. A hybrid P2P like Napster had a centralised server keeping an index of all the available files and the currently signed on users with their available files to facilitate searches. The essential feature of P2P file transfer is that once a host server has been established which has the required file, the communication is directly between the requesting client and the responding host. The network doesn’t suffer from degraded performance when more clients are connected as in traditional client-server architecture; as each new client brings its own resources (ie storage, bandwidth and CPU processing power) to the table to increase network capacity. Also the files are available from a number of connected clients so there is potential for selecting from the most responsive host and there is built-in fault tolerance as the files are available on a number of hosts.

Saturday, January 2, 2010

Access restrictions and integrity constraints clarified

Access restrictions are enforced by the DBMS facility that ensures that only authorised users gain access to the DBMS. For example, a valid user is allowed to manipulate a table with given access rights.

Integrity constraints are constraints that maintain the consistency and correctness of data.

They protect the contents of the database in totally distinct ways. When a DBMS restricts access to a user to do certain things, like granting right to only view a table rather than update it, then it is ensuring that the data providers with responsibility for maintaining the accuracy of the data content enters, updates and deletes the data while the data consumers just have the privilege to review data for their proper functioning. Also the sensitive company data pertaining to finance and personnel functions can be shielded from the prying eyes of those who have no need for direct access to this data by not authorizing access to these data areas. Essentially, access restriction is ensuring that only the data necessary and sufficient for carrying out a job is made available to the person and the rest of the data is hidden from him. Through access restrictions we can segregate responsibilities within the organisations by providing access authorization to data horizon necessary for a role. These security access restrictions are centrally defined and DBMS automatically enforces them while accessing the database (Block1,p24). The data correctness is achieved by proper responsibility sharing through access privileges and obviating the potential for unauthorised rogue data manipulations. Any SQL statement issued by a user can only be commensurate with his authorised access profile or DBMS will not execute it.

Integrity constraint ability to enforce consistent and correctness is best understood through example. If we have a geographical hierarchy with levels of company, country, region and world (eg Unilever UK, UK, Europe, Global held in COMPANIES, COUNTRIES, REGIONS and WORLD tables) then while defining a company in COMPANIES table it ensures that it is only linked to the valid countries defined in the COUNTRIES table in the database and countries and linked to the valid regions in REGIONS table. If we had linked a company to an undefined country in the database, then while aggregating regional data this rogue country would have been missed in table linkages as it is not part of the hierarchy. Also if we try to delete a region in our REGIONS table while there are countries linked to that region in the COUNTRIES table then integrity constraint could either prevent us from carrying out this operation or cascade the delete to all the records in COUNTRIES table that are linked to REGIONS table with region_id as the foreign key. All these type of rule governing referential integrity are stored in the system catalog managed by the DBMS and are automatically enforced by DBMS without required any programming intervention by the developer (Block1,p24). Although we have focussed on the referential integrity in our example, we can see the data integrity being enforced by DBMS when it enforces user-defined rules like date of birth has to be lower than date of school start or numeric phone number should not have any arithmetic operations performed on them. We can define a number of integrity constraints like email address must include ‘@’, the values for a particular column must be within 100-800 range or area code is restricted to a subset of predefined codes etc. These are all examples of integrity constraints defined to ensure the correctness and validity of the data contained in the database. The integrity constraints could also be implemented through pre-insert, pre-update, pre-delete triggers etc on the tables.

In brief, the access restriction forces correctness through security measures whilst the integrity constraints enforce correctness and consistency of contents through defined constraints on columns in the table. With access restriction no person would be able to insert, update or delete information in a table without appropriate privilege. Whilst the integrity constraint will ensure that the authorised personnel can only add data which conforms to pre-defined rules.