Tuesday, March 17, 2020

Charts in PDF using iText, JFree Chart and Orson Charts

Came across a use case where one dataset has to be compared against a set of other datasets.
A simple example is to compare salary against the sum of tax, rent, car and other expenses. An obvious choice is to display salary as a bar and other expenses in a stacked area so that we can easily check which dataset value is higher.

Used JFreeChart library to create the chart and iText to create the PDF. There is a limited support to create charts in Java. JFreeChart is the only popular library available. It has various examples but this particular example is not covered anywhere.
http://www.jfree.org/jfreechart/samples.html


Here is the final chart shown in the PDF. It is generated using a BarRenderer and multiple AreaRenderers.



Here is the source code for download.

https://drive.google.com/file/d/1raQE8q4pLnArnrDdbub7kVFLhr8VCY5u/view?usp=sharing


Tuesday, July 24, 2012

Create and Drop Database Schemas

Unlike other DB queries, schema object creation look straight forward but in reality it is not. It took sometime for me to figure out and come up with right SQL statements.

Create DB schema Greeting and a table test_table in it:

CREATE user Greeting Identified by Greeting DEFAULT TABLESPACE users TEMPORARY TABLESPACE temp QUOTA UNLIMITED ON users

GRANT CREATE SESSION, CREATE RULE, CREATE TABLE, CREATE SEQUENCE, CREATE TRIGGER, CREATE VIEW, CREATE PROCEDURE, CREATE OPERATOR, CREATE TYPE TO Greeting

CREATE TABLE Greeting.test_table (ID VARCHAR2(30) PRIMARY KEY,name VARCHAR2(30) NOT NULL, type VARCHAR2(15) NOT NULL);


Now a table test_table is created in the schema Greeting. Try 'desc Greeting.test_table' to verify

Drop DB schema:


Drop user Greeting cascade;


These queries are for Oracle DB;

Wednesday, September 14, 2011

java.lang.UnsatisfiedLinkError: Native Library HelloWorld.dll already loaded in another classloader

Continuation of the previous post.


Some workarounds to overcome the problem are:

1) Load the dll in system classloader that is available to all child
classloaders
2) Always load the dll with a different name - Bad approach
3) Unload DLL by cleaning up ClassLoader cache. I tried this approach after some analysis as option1 was not feasible in my case.

Whenever a native library is loaded in a classloader, the following private static fields get updated - loadedLibraryNames and nativeLibraries.
Refer java.util.ClassLoader javadocs for more info on these fileds.

java.util.ClassLoader creates a ClassLoader$NativeLibrary(local inner class) class object
for each and every native library it loads and also maintains a cache containing the names of the DLL files that are loaded. 
  
I have used reflection to fetch the fields - loadedLibraryNames and nativeLibraries - from ClassLoader and cleared all the entries corresponding to the DLL that i wanted to unload.
This solution worked in my case and I need not wait till the ClassLoader is garbage collected inorder to call a native method from different classloaders.

The complete source code can be downloaded from 
  
https://docs.google.com/viewer?a=v&pid=explorer&chrome=true&srcid=0BxW5CDXA1SsmNGY3NWE5MmItZDJkMC00MTVlLTg0ZjQtZmI3ODIzY2NmZjQ3&hl=en_US

Phani Kumar Bandanakanti: java.lang.UnsatisfiedLinkError: Native Library Hel...

Phani Kumar Bandanakanti: java.lang.UnsatisfiedLinkError: Native Library Hel...: Problem: There's no way to unload a dll loaded by a classloader. DLL will be unloaded only during classloader garbage collection. Also a d...

java.lang.UnsatisfiedLinkError: Native Library HelloWorld.dll already loaded in another classloader

Problem:

There's no way to unload a dll loaded by a classloader. DLL will be unloaded only during classloader garbage collection.
Also a dll cannot be loaded more than once in a jvm even if we use distinct classloaders.

This is a known issue in JDK and more information can be found in the links below.

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4225434
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5075039

Update from bugs.sun.com

A native library can not be loaded into two live ClassLoaders objects
at the same time and the reasoning for this is obvious -- native code
that caches JNI IDs will get wrong answers.  The long term fix for
this is a way for the native library to tell the VM (on JNI_OnLoad)
that it is multiple-ClassLoader safe.  That would be an RFE.

However when the ClassLoader has died, the ClassLoader.NativeLibrary
finalizer could unload the library.  Currently we do not do this
and this is intentional -- unloading libraries is an MT unsafe
operation on NT and there are troubles with runFinalizersOnExit.
A workaround would be to have the class that loads a native library
be loaded by a shared classloader (through the parenting mechanism of
ClassLoaders in 1.2).

Sample code to reproduce the problem:

1) Created a class HelloWorld.java that declares a native method.
2) Generated the C header file, wrote the C implementation and created a DLL file. All these steps are clearly explained in the following link.
http://java.sun.com/docs/books/jni/html/start.html
3) To reproduce the problem, i wrote a simple java class which loads the DLL file and calls the native method multiple (three) times.
Each time it tries to load the native library and calls the native method in a different classloader.
The code snippet is shown in the image below.
Complete codesnippets and workarounds to overcome the problem will be provided in the next post.

Friday, August 27, 2010

Red Pineapple ?

Saw this at one of the hotels where I stayed. I saw a pineapple tree for the first time and that too a red colored one.

Monday, August 23, 2010

XML2PDF-Text as document watermark

This one is long due. Some time back I was working on a task that takes XML input, XSL stylesheet and runs Apache FOP processor to create a PDF document.
The PDF document should contain different sections like headers, footers, invoice lines (table) and a watermark. Each section may contain different blocks of data.
There were some different types of pages so I have developed a couple of XSL stylesheet to handle this. Please note that this was not a dynamic thing which can be used for any kind of XML2PDF conversion.

The main challenges I have faced with FOP.
1) For some reason, I had issues with my final PDF document layout. Even if everything thing looked fine, I had some overlap problems between lines. Finally figured out that was the problem with using Saxon Transformer Factory.
Setting the Xalan Transformer Factory as the default solved the problem.
System.setProperty("javax.xml.transform.TransformerFactory", "org.apache.xalan.processor.TransformerFactoryImpl");

 
2) Creating a dynamic watermark/banner.
i.e. I get some text data as part of the input document and I need to set this as PDF watermark.
Most of the APIs easily support images as watermarks but there's no direct support for using text content as watermark.
Luckily I found the solution for this by using Batik API to draw watermarks and integrated that in my stylesheet using "fo:instream-foreign-object" in FOP.
The below snippet shows the XSL code for this.

Here I wanted the watermark to be in the diagonal shape so I transformed the text, rotated it by 45degrees and did some final finishing. Here's a quick snapshot of the final outcome. You can see the 'Test Watermark' which is generated using the above XSL.

Monday, March 15, 2010

Windows file lock issue in eclipse - classloader problem

File lock issue in windows when using URLClassloader objects.

Brief overview of the problem:

In our eclipse application, we configure various services. Each service has its own property sheet (dialog). While launching a service dialog in eclipse platform, we create a custom URLClassloader objects using all its dependencies/ resources (jar files). Once this dialog is Finished/Closed the jar files still get locked up in windows platform and this caused problems.

Normally to handle such locks, we create a custom URLStreamHandlerFactory that implements java.net.URLStreamHandlerFactory where we create our own handlers for different protocols. Sample code is present in Listing 1.

This perfectly works for most of the cases but since my process is an eclipse process and eclipse is already setting its own URLStreamHandlerFactory I couldn't directly use the code in Listing 1 since URL.setURLStreamHandlerFactory(customFactory); has to be called only once in a jvm.


However, I tried some workarounds like using reflection to reset the URLStreamHandlerFactory and to specifically use the following URL constructor.
URL jarUrl = new URL("jar", "", -1, resourceFileUrl.toString()+ "!/");
Iam able to accomplish the task but later I discovered that this broke some other areas and I keep on getting NoClassDefFoundErrors even if the class is available in the classpath and loaded by the same classloader.

Finally Iam able to resolve this with a simple workaround which does 2 things - Setting the field defaultUseCaches in URLConnection class to false, using some utility code to close all Jar connections. The solution is posted below.

Solution that Worked:

1. There is a field defaultUseCaches in URLConnection class. This field has to be set to false when the application loads.

static {
    try{
        Field defaultUseCaches = URLConnection.class.getDeclaredField("defaultUseCaches");
        defaultUseCaches.setAccessible(true);
        defaultUseCaches.set(defaultUseCaches, false);
    } catch(Exception e){
        //do something
    }
}

Note: If this is set to false then setting useCaches to false is not required as in Listing 1.


2. Used an utility class to release all the resources held by URLClassloader when a service dialog is closed.
Used releaseLoader(URLClassLoader classLoader, List jarsClosed) method in sun.misc.ClassLoaderUtil to close the jarfiles. The source code is available here.

http://www.docjar.com/html/api/sun/misc/ClassLoaderUtil.java.html

The classloader problem was resolved after this.

Note: ClassLoaderUtil uses classes like URLClassPath which are restricted by default in eclipse.
To overcome this the following setting has to be changed in eclipse preferences.
Navigate to Preferences -> Java -> Compiler -> Errors and Warnings -> Deprecated and Restricted API and change the value of  Forbidden Reference to Warning.


Listing 1:
Lists the sample custom URLStreamHandlerFactory class and a simple JarHandler. Same code can be used in other handlers like FTP, File etc.
Note: This cannot be used for eclipse process. Works for normal java processes.

-------------------MyURLStreamHandlerFactory -------------------------
import java.net.URLStreamHandler;
import java.net.URLStreamHandlerFactory;
import java.util.Hashtable;

public class MyURLStreamHandlerFactory implements URLStreamHandlerFactory {


private Hashtable handlers;
public MyURLStreamHandlerFactory() {
    handlers = new Hashtable();
}

public URLStreamHandler createURLStreamHandler(String protocol) {
    URLStreamHandler ush = (URLStreamHandler) handlers.get(protocol);
    if (ush == null) {
        if (protocol.equalsIgnoreCase("file")) {
            URLFileHandler fileHandler = new URLFileHandler();

            ush = fileHandler;
            handlers.put(protocol, fileHandler);
        } else if (protocol.equalsIgnoreCase("jar")) {
            URLJarHandler jarHandler = new URLJarHandler();
            ush = jarHandler;
            handlers.put(protocol, jarHandler);
        } else if (protocol.equalsIgnoreCase("ftp")) {
            URLFtpHandler ftpHandler = new URLFtpHandler();
            ush = ftpHandler;
            handlers.put(protocol, ftpHandler);
        } else if (protocol.equalsIgnoreCase("http")) {
            URLHttpHandler httpHandler = new URLHttpHandler();
            ush = httpHandler;
            handlers.put(protocol, httpHandler);
        } else if (protocol.equalsIgnoreCase("https")) {
            URLHttpsHandler httpsHandler = new URLHttpsHandler();
            ush = httpsHandler;
            handlers.put(protocol, httpsHandler);
        }
    }
return ush;
}


/**
* Clears the URLStream Handler(s) hash table.

*/
public void clear() {
    handlers.clear();
}


}

--------------------- MyURLStreamHandlerFactory --------------

------------------------- URLJarHandler---------------------------
import java.net.URLConnection;
import java.net.URL;
import java.io.IOException;


/**
* Jar URL Stream Handler . It has all the attributes of a URLStreamHandler for the 'jar' protocol.
* openConnection method overriden to prevent locking & caching of file on windows os.
*/
public class URLJarHandler extends sun.net.www.protocol.jar.Handler {

protected URLConnection openConnection(URL url) throws IOException {
    URLConnection u = super.openConnection(url);
    u.setUseCaches(false);//prevents locking&caching of file on windows by jvm.
    return u;
}
 }
-------------------------------URLJarHandler------------------

Thursday, May 22, 2008

IPL 2008 - KolkataKnightRiders Vs Deccan Chargers
















Though the performance of Deccan Chargers in IPL 2008 was disappointing, we still enjoyed as it was our first live match.
Here's a snapshot of the ground before the start of play.