Friday, April 25, 2008

Return code

- In Java, invoke a sub-process


Process p = Runtime.getRuntime().exec(cmd);

Get the return code by p.waitFor() (not p.exitValue() which is not block-waiting and may get Exception). See this article for details.

- Return code in Java program
System.exit(n) where n is the status code, by convention, a nonzero status code indicates abnormal termination. It is different from the return value by method, which is returned to JVM. The exit code is returned from JVM to the machine.

- Check and return code in DOS batch
# invoke a java program ..
# check the program's exit code and abort with return code 2 (or we can log it), which will be digested
# by the caller of this batch file, e.g. C++ code in installer shield
if ERRORLEVEL 2 exit 2

The IF ERRORLEVEL n test succeeds if the error level is n or more.
See: ERRORLEVEL is not %ERRORLEVEL%

Tuesday, April 22, 2008

dynamic class reload

- Use different child classloader to reload the class and create new instance
- Apply proxy pattern to delegate the invocation to new instance, so that changes to the dynamic class become transparent to its caller.


// The dir contains the compiled classes.
File classesDir = new File("/temp/dynacode_classes/");

// The parent classloader
ClassLoader parentLoader = Postman.class.getClassLoader();


// Load class "sample.PostmanImpl" with our own classloader.
URLClassLoader loader1 = new URLClassLoader(
new URL[] { classesDir.toURL() }, parentLoader);
Class cls1 = loader1.loadClass("sample.PostmanImpl");
Postman postman1 = (Postman) cls1.newInstance();

/*
* Invoke on postman1 ...
* Then PostmanImpl.java is modified and recompiled.
*/

// Reload class "sample.PostmanImpl" with a new classloader.
URLClassLoader loader2 = new URLClassLoader(
new URL[] { classesDir.toURL() }, parentLoader);
Class cls2 = loader2.loadClass("sample.PostmanImpl");
Postman postman2 = (Postman) cls2.newInstance();

/*
* Work with postman2 from now on ...
* Don't worry about loader1, cls1, and postman1
* they will be garbage collected automatically.
*/

The Java reflection API includes a handy utility for creating proxies. The class java.lang.reflect.Proxy provides static methods that let you create proxy instances for any Java interface.

InvocationHandler handler = new DynaCodeInvocationHandler(...);
Postman proxy = (Postman) Proxy.newProxyInstance(
Postman.class.getClassLoader(),
new Class[] { Postman.class },
handler);

public class DynaCodeInvocationHandler implements InvocationHandler {


public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

// Get an instance of the up-to-date dynamic class
Object dynacode = getUpToDateInstance();

// Forward the invocation
return method.invoke(dynacode, args);
}
}

Reference link

Wednesday, April 16, 2008

MVC/MVP pattern

MVC


There are three components: the Model, View, and Controller The purpose of the MVC pattern is to decouple the user interface from the internal application state and the business logic that manages that state. To accomplish this, the MVC pattern relies heavily on events so that the interface between the three components are not tightly coupled. In fact, only one object, the Model, is usually physically shared between the View and the Controller. In order to maintain the highest degree of flexibility with the MVC pattern, there are some rules to follow:

1. The Model manages all state information
2. The Model notifies the View of state changes through events rather than direct calls
3. The View manages all user interface state and display information
4. The View only queries the Model for state information--it never changes the Model's state
5. The View responds to user gestures and informs the Controller of those gestures using events
6. The Controller responds to View events
7. The Controller queries the Model for state information
8. The Controller can change the Model state using methods exposed by the Model
9. The Controller often constructs the Model and the desired View
10. The Controller implements the business logic of the application with regards to responding to user gestures

Martin Flower's view:
* Make a strong separation between presentation (view & controller) and domain (model) - Separated Presentation.
* Divide GUI widgets into a controller (for reacting to user stimulus) and view (for displaying the state of the model). Controller and view should (mostly) not communicate directly but through the model.
* Have views (and controllers) observe the model to allow multiple widgets to update without needed to communicate directly - Observer Synchronization.

MVP

* View contains the Presenter instance (view "knows" presenter)
* Presenter is the only class knowing how to reach to model and retrieve the data needed for performing business logic
* Presenter talks to the View through the view interface (abstracted representation of the View without UI specific attributes)
* View doesn't know nothing about the Model

Advantage of MVP: dummy slave view (also called Passive View) make stub testing easier


MVC vs. MVP

A comparison is discussed here

MVP design pattern implementation has a view totally unaware of model. Presenter is the one exclusively communicating with the model and sending DTO (in case of Supervising controller) to model or performing direct manipulation with the view UI elements.

On the other hand, in MVC we have next two "read data" cases:

* a view reading data directly from model and perform "declarative data binding" of its controls or
* controller retrieving data from model, pass that context data to view while loading the appropriate view and view then binds to that sent context data

In most of the "update data" use cases we have a view sending updated context data to controller, where controller performs some validation and/or business logic and updates the model with that data.

Wednesday, April 2, 2008

Performance tuning

Whenever your application is connecting to a resource, such as a database, running in another process, you should optimize by focusing on the time spent connecting to the resource, the time spent sending or retrieving data, and the number of round-trips.

- HTTP: apply caching, HTTP compression
- Database: connection pooling, store procedure (save round trips)

To add cache control in Apache config httpd.conf


<Directory "C:/webnms/webclient">
   <Files ~ "\.(gif|jpe?g|png|css|js)$">
     Header set Cache-Control "public,max-age=3600"
   </Files>
</Directory>