Thursday, October 16, 2008

Installing Apache portable runtime (APR) for tomcat 6.0.x

Tomcat can now use Apache Portable Runtime and using APR results in performance boost.
Below we detail the steps to get tomcat native library installed on a linux system
(I am using Red hat but steps should be similar for other distros)

Download and install APR



wget http://apache.norhex.com/apr/apr-1.3.3.tar.gz
mkdir x
mv apr-1.3.3.tar.gz x/
408 tar -zxvf apr-1.3.3.tar.gz
409 cd apr-1.3.3
416 gcc -v
417 ./configure --prefix=/opt/apr
418 make
419 make install



Download and compile openssl tarball corresponding to your system
(Latest version maybe incompatible with your system)




424 openssl version -a
426 wget http://www.openssl.org/source/openssl-0.9.8b.tar.gz
427 tar -zxvf openssl-0.9.8b.tar.gz
429 cd openssl-0.9.8b
431 ./Configure
433 ./config --prefix=/opt/apr --openssldir=/opt/openssl shared
434 make
435 make test
436 make install


Download and install sun JDK .

You have to put /usr/java/latest/bin in your path to pick SUN JDK ahead of GCJ.




466 uname -a
467 java -version
468 links http://java.sun.com/javase/downloads/index.jsp
chmod +x jdk-6u10-linux-i586-rpm.bin
411 ./jdk-6u10-linux-i586-rpm.bin
418 /usr/java/latest/bin/java -version
419 echo $PATH
423 vi .bash_profile
424 . .bash_profile
425 echo $PATH
426 java -version




Download and install tomcat native source



443 wget http://tomcat.heanet.ie/native/1.1.10/source/tomcat-native-1.1.10-src.tar.gz
444 tar -zxvf tomcat-native-1.1.9-src.tar.gz
445 cd tomcat-native-1.1.10-src/jni/native
464 ./configure --help
440 ./configure --prefix=/opt/apr/ --with-ssl=/opt/apr --with-apr=/opt/apr
--with-java-home=/usr/java/latest --with-java-platform=2

460 make
467 make install
468 ls /opt/apr/lib/
469 ldd /opt/apr/lib/libtcnative-1.so.0


if configure complains about not finding openSSL then set LD_LIBRARY_PATH to include /opt/apr/lib.




454 echo $LD_LIBRARY_PATH
455 LD_LIBRARY_PATH=/opt/apr/lib
456 export LD_LIBRARY_PATH




Put tomcat native library in LD_LIBRARY_PATH before starting tomcat. Start tomcat and check catalina log file to verify that tomcat is using APR.



# setup native library in path
LD_LIBRARY_PATH=/opt/apr/lib:$LD_LIBRARY_PATH
export LD_LIBRARY_PATH
/usr/local/apache-tomcat-6.0.16/bin/startup.sh


Monday, July 21, 2008

Making jar files dependency graph using jarjar and dot

Our project has grown quite a bit over the past couple of years and with it the library folder containing third party jars . So much so that we are not sure now as to what is used and what is not. So we decided to do a bit of cleanup and remove the unused jars. However before we can do that we need to know which ones are used by code and which ones are not.

I have not been able to locate a tool that can print out run time dependencies of java code on a jar file. Anyway I am not sure if that can be done at all with static analysis. Leaving aside run time dependencies there are some tools that can print out the static dependencies between two jar files. After some googling and general goofing I settled on jarjar (http://code.google.com/p/jarjar/)

jarjar can print the dependencies between any two jar files (see http://sixlegs.com/blog/java/depfind.html). jarjar can print dependencies between multiple jar files also. Just separate the jar file names with a colon (UNIX) or semi colon (MS-WIN32) What I wanted was the multiple file version of command , A panacea to print dependencies between all my jar files in lib folder.

I made a batch file with all the jar file names (Using a perl script to print the required batch file) along the lines of
/>java -jar jarjar-1.0rc7.jar find jar activation-1.1.jar;ant-1.6.5.jar;antlr-2.7.2.jar.............. 70 more files.

I used the following script to generate my batch file

$argc = @ARGV;
if($argc != 1 ) {
print " USAGE : $perl read-dir.pl \n ";
exit(0);
}


$mydir = $ARGV[0] ;

opendir(dhandle, $mydir) || die("Cannot open directory");
@thefiles= readdir(dhandle);
closedir(dhandle);

print " java -jar jarjar-1.0rc7.jar --find --level=jar " ;

foreach $f (@thefiles) {
unless ( ($f eq ".") || ($f eq "..") || ($f eq ".svn" )) {
print "$f:";
}
}




The batch file runs for a while and then dies with an ArrayOutOfBoundException. Now I did not want to tackle any problems in jarjar so I took a workaround. Since jarjar can print dependencies between any two jars , I decided to use that fact in my solution. I just wrote a perl script that would store all the jar files in a folder and compare a pair of them at a time using jarjar. If we find any dependency we print it on console. (script attached below) The output of this script can be saved as a "dot" file.

The script ran for quite some time but in the end it produced dependencies of all jar files in the folder in dot-ready format. dot is a nifty program to print graphs that comes bundled with graphviz. (Graphviz website) if you print the dependencies in a format that dot can understand then you can use dot on this output to produce a graph. That was the intention. If you install graphviz then dot should already be in your system path.

Just run dot over the outfile file like, ( This link from oreilly linux dev center may be useful )

D:/project/lib/> dot -Tpng -o graph.png .dot


And now you have the dependencies graph. If you are not satisfied with quality then you can try OmniGraffle see link ( http://paco.to/blog/000040.html). However for Omnigraffle make sure

  • You save the output of perl script as a dot file (extension dot like jars-data.dot)
  • OmniGraffle will run on a Mac only


And here is the perl script to do dependency analysis



$argc = @ARGV;
if($argc != 1 ) {
print " USAGE : $perl jarjar.pl <dirname> \n ";
exit(0);
}


$mydir = $ARGV[0] ;

opendir(dhandle, $mydir) || die("Cannot open directory");
@files= readdir(dhandle);
closedir(dhandle);

# make extra copy of files
@alljars = @files ;

# program may end abruptly for all possible combnations
# To control the jar combinations we can look for files
# starting with following alphabets only
#

%allowed = qw/o p q r s t u v w x y z/;


foreach $file (@files) {
$starts_with = substr($file,0,1);
# process $file that starts with allowed letter and ends with jar
if ( $file=~/jar$/ && exists($allowed{$starts_with})) {
# go over all jar files
foreach $jar(@alljars) {
if ( $jar=~/jar$/ ) {
# compare this jar against the file
$command = "java -jar jarjar-1.0rc7.jar find jar $file $jar \n ";
#print $command ;
#open command pipe
open(CMD, "$command|");
$output = <CMD>;
close(CMD);
# print output in graphviz dot format
if(length($output) > 0 ) {
print " \"$file\" -> \"$jar\" \n " ;
}


}
}
}


}

exit(0);




© Life of a third world developer
Maira Gall