Posted by Unknown on 1:45 PM
Labels:

Yahoo’s YUI Compressor is the tool (jar), which does a fantastic job of compressing down both .js and .css files.Running your JavaScript code through YUI Compressor results in tremendous savings by default, but there are things you can do to increase the byte savings even further. Manually it can be invoked on each js and css file but it will be great if we automate this compression process as part of our Ant build process (build.xml) for fornt-end view generation application.

How it works?
The YUI Compressor is written in Java (requires Java >= 1.4).It starts by analyzing the source JavaScript file to understand how it is structured. It then prints out the token stream, omitting as many white space characters as possible, and replacing all local symbols by a 1 (or 2, or 3) letter symbol wherever such a substitution is appropriate.The CSS compression algorithm uses a set of finely tuned regular expressions to compress the source CSS file.

Observations:
I have checked with the 25KB JS script sample file, (48KB CSS file).After running this tool, JS is compressed to 6KB (CSS is compressed to 26KB). That means through the wire less than 1 /10th of file size bytes will be passed to client side (with gzip encoding).
Hence it will provide highest degree of throughput time in terms of front end view generation performance.



Statistics after YUI Compression,



Compression by command line:
The following command line (x.y.z represents the version number):
java -jar yuicompressor-x.y.z.jar myfile.js -o myfile-min.js

will minify the file myfile.js and output the file myfile-min.js. For more information on how to use the YUI Compressor, please refer to the documentation included in the archive.
The charset parameter isn't always required, but the compressor may throw an error if the file's encoding is incompatible with the system's default encoding. In particular, if your file is encoded in utf-8, you should supply the parameter.
java -jar yuicompressor-x.y.z.jar myfile.js -o myfile-min.js --charset utf-8

Compression by automated build through NetBeans:
Step 1: Download YUIAnt.jar and yuicompressor-2.3.5.jar
Step 2: Put these two jars at C:\Program Files\NetBeans 6.1\java2\ant\lib
Step 3: Add following ant script at build.xml of web project of NetBeans.


Your comments/suggestions are welcome.

Posted by Unknown on 7:12 AM
Labels:

GZip is based on the DEFLATE algorithm, which is a combination of LZ77 and Huffman coding. gzip is often also used to refer to the gzip file format, which is:

1. a 10-byte header, containing a magic number, a version number and a time stamp.
2. optional extra headers, such as the original file name.
3. a body, containing a DEFLATE-compressed payload.
4. an 8-byte footer, containing a CRC-32 checksum and the length of the original uncompressed data.

Although its file format also allows for multiple such streams to be concatenated (zipped files are simply decompressed concatenated as if they were originally one file), gzip is normally used to compress just single files . Compressed archives are typically created by assembling collections of files into a single tar archive, and then compressing that archive with gzip. The final .tar.gz or .tgz file is usually called a tarball.

Most of the FE view generation time is tied up in downgrading all the components in the page: like html, images, stylesheets, scripts, ActiveX components and static resources.
Using gzip compression technique we can drastically reduce the size (almost 1/10th of original response content size ,as per spec) of the resources which takes less time, bandwidth to traverse through the wire interns increase the view generation performance.
It Also it provides transport layer encoding.




Steps to Implement

1. Write a GZipFilter through which all request/response should pass to/from Web app Servlet.
2. In filter Check if the requester (For web app its browser) can support gzip encoding or not. by checking "Accept-Encoding" header value of request. This check is necessary because if the requester client does not support gzip encoding then normal operation should be performed without encoding.
4, If client supposts gzip encoding set a response header "Content-Encoding" with value "gzip". It's needed for browser to understand about the meta-data of coming response content.
3. If it's supports gzip encoding set the object of GZipOutputStream in HTTPServletResponseweb app servlet.
4. Web app will write the response byte Stream in GZipOutputStream instead of simple OutputStream and browser will take care of the rest.

Your queries/suggestions are welcome, please put it into the comment section.

Posted by Unknown on 10:22 AM
Labels:

XStream is a simple library to serialize objects to XML and back again.


Features of XStream
A. Ease of use. A high level facade is supplied that simplifies common use cases.
No mappings required. Most objects can be serialized without need for specifying mappings.
B. Performance. Speed and low memory footprint are a crucial part of the design, making it suitable for large object graphs or systems with high message throughput.
C. Clean XML. No information is duplicated that can be obtained via reflection. This results in XML that is easier to read for humans and more compact than native Java serialization.
D. Requires no modifications to objects. Serializes internal fields, including private and final. Supports non-public and inner classes. Classes are not required to have default constructor.
E. Full object graph support. Duplicate references encountered in the object-model will be maintained. Supports circular references.
F. Integrates with other XML APIs. By implementing an interface, XStream can serialize directly to/from any tree structure (not just XML).
G. Customizable conversion strategies. Strategies can be registered allowing customization of how particular types are represented as XML.
H. Error messages. When an exception occurs due to malformed XML, detailed diagnostics are provided to help isolate and fix the problem.
I. Alternative output format. The modular design allows other output formats. XStream ships currently with JSON support and morphing.

Below is the small POC to serialize/de-serialize non-serializable objects. Have to include XStream jar into classpath.

Foo Object
public class Foo {
private String foo ;
public void setFoo(String s) {
foo = s;
}
public String getFoo() {
return foo;
}
}

Object Helper
public class FooHelper {
public static void write(Object f, String filename) throws Exception {
XMLEncoder encoder = new XMLEncoder(new BufferedOutputStream(new FileOutputStream(filename)));
encoder.writeObject(f);
encoder.close();
}
public static Object read(String filename) throws Exception {
XMLDecoder decoder = new XMLDecoder(new BufferedInputStream(new FileInputStream(filename)));
Object o = decoder.readObject();
decoder.close();
return o;
}
}

XStream Wrapper
public class FooWraper implements Serializable{
String xstreamStr;
public String getXstreamStr() {
return xstreamStr;
}
public void setXstreamStr(String xstreamStr) {
this.xstreamStr = xstreamStr;
}
}

Object Helper
public class ObjectHelper {
private ObjectHelper(){ }
public static Object fromBytes(byte[] aBBytes) {
Object mOReadObj = null;
try {
final ObjectInputStream mVOis = new ObjectInputStream(
new ByteArrayInputStream(aBBytes));
mOReadObj = mVOis.readObject();
mVOis.close();
} catch (Exception ex) {
ex.getStackTrace();
}
return mOReadObj;
}
public static byte[] toBytes(Object aOObject) throws IOException {
final ByteArrayOutputStream mVBaos = new ByteArrayOutputStream();
final ObjectOutputStream mVOos = new ObjectOutputStream(mVBaos);
mVOos.writeObject(aOObject);
mVOos.close();
final byte[] mBVal = mVBaos.toByteArray();
mVBaos.close();
return mBVal;
}
}

Caller Class
public class FooTest {

public static void main(String[] args) throws Exception {
Foo f1 = new Foo();
f1.setFoo("Crédito de cuerdas");
//Using Xtream ..............
byte[] b = new byte[4048];
XStream xstream = new XStream();
long stime = System.currentTimeMillis();
String xml = xstream.toXML(f1);
FooWraper wrap = new FooWraper();
wrap.setXstreamStr(xml);
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File("c:/foo.txt")));
byte[] f = ObjectHelper.toBytes(wrap);
bos.write(f);
bos.close();
long ltime = System.currentTimeMillis();
System.out.println("Elapsed time for Serialization =>" + (ltime - stime));
stime = System.currentTimeMillis();
System.out.print(xml);
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("c:/foo.txt"));
bis.read(b);
bis.close();
FooWraper f2 = (FooWraper) ObjectHelper.fromBytes(b);
Foo foo = (Foo) xstream.fromXML(f2.getXstreamStr());
System.out.println("\n" + foo.getFoo());
ltime = System.currentTimeMillis();
System.out.println("Elapsed time for deserialization =>" + (ltime - stime));
System.exit(0);
}
}

Posted by Unknown on 9:59 AM
Labels:

A thread can be in one of the following states: NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING, TERMINATED. Now its a internal implementation of Spring ThreadPoolTaskExecutor how it manipulates the thread state after invoking execute(). That's why getActiveCount() can't give exact numbers but approximate.


Instead of injecting ThreadPoolTaskExecutor object I am extending ThreadPoolExecutor class, which is giving extra callback method (afterExecute()) to check number of active threads or catching exceptions.

ThreadPoolExecutor object can also be injected through Spring context.

Client/Caller Class

package test.hiren;

/**
*
* @author Hiren
*/
public class GenerateReportServiceHelperImpl {

public boolean needProgress;
TaskExecutor threadPool;

public static void main(String[] args) throws Exception {
GenerateReportServiceHelperImpl obj = new GenerateReportServiceHelperImpl();
obj.reportExecution();
}

public void reportExecution() throws Exception {
int listSize = 4;//in your case its rpt list size
threadPool = new TaskExecutor();
threadPool.setCallbackInvoker(this);
threadPool.setComparableThreadCount(listSize);
for (int i = 0; i <>
threadPool.execute(new RetrieveDataFromDataPowerTask());

}
if(needProgress == false){
Thread.sleep(200);
}
System.out.println("I am here");
}

public void callbackInvoker() {
needProgress = true;
System.out.println("Counter =>" + needProgress);
threadPool.shutdownNow();

}

}

Runnable Class

package test.hiren;

/**
*
* @author Hiren
*/
class RetrieveDataFromDataPowerTask implements Runnable {
public void run() {
System.out.println("I am at Run");
}
}

Executer Class
Callback method is synchronized to ensure that decrement operation after thread completion should not have any ambiguities.AfterExecute() is the callback method invoked by Spring callback handler when thread execution is completed or stopped (in case of any exception).

package test.hiren;

import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
*
* @author Hiren
*/
public class TaskExecutor extends ThreadPoolExecutor {

private GenerateReportServiceHelperImpl callbackInvoker;
private int comparableThreadCount;
TaskExecutor() {
super(10, 10, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue());
}

@Override
protected void beforeExecute(Thread t, Runnable r) {
}

@Override
protected void afterExecute(Runnable r, Throwable t) {
callback(r, t);
}

public synchronized void callback(Runnable r, Throwable t) {
comparableThreadCount = comparableThreadCount - 1;
System.out.println("comparableThreadCount=>" + comparableThreadCount);
if (t != null) {
System.out.println("ThreadPool Runnable's Exception caught!");
} else {
System.out.println("ThreadPool Runnable's gave no Exception");
if (comparableThreadCount == 0) {
System.out.println("Returning to Callback");
callbackInvoker.callbackInvoker();
}
}
}

public void setCallbackInvoker(GenerateReportServiceHelperImpl callbackInvoker) {
this.callbackInvoker = callbackInvoker;
}

public void setComparableThreadCount(int comparableThreadCount) {
this.comparableThreadCount = comparableThreadCount;
}
}