/*
* JBoss, Home of Professional Open Source
* Copyright 2005, JBoss Inc., and individual contributors as indicated
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
/*
* JBoss, Home of Professional Open Source
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package org.jboss.tools;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.TreeSet;
import java.util.Comparator;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.logging.Logger;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtConstructor;
import javassist.NotFoundException;
/**
A utility class that loads all jdk1.4.2 Throwable types from the rt.jar
and compares these constructor signatures to the jdk5 types to identity
where new constructors taking a Throwable argument have been added.
@author Scott.Stark@jboss.org
@version $Revision: 200 $
*/
public class FindExceptionCtorChanges
{
static Logger log = Logger.getLogger("FindExceptionCtorChanges");
static class CtorComparator implements Comparator<CtConstructor>
{
public int compare(CtConstructor o1, CtConstructor o2)
{
String sig1 = o1.getSignature();
String sig2 = o2.getSignature();
return sig1.compareTo(sig2);
}
}
/**
@param args [0] = jdk14/rt.jar, [1] = jdk15/rt.jar
*/
public static void main(String[] args)
throws Exception
{
if( args.length != 2 )
throw new IllegalArgumentException("Usage: FindExceptionCtorChanges path-to-jdk14/rt.jar path-to-jdk15/rt.jar");
String jdk14Jar = args[0];
JarFile jdk14JarFile = new JarFile(jdk14Jar);
ClassPool jdk14Pool = new ClassPool();
jdk14Pool.appendClassPath(jdk14Jar);
CtClass jdk14Throwable = jdk14Pool.get("java.lang.Throwable");
HashMap<String, CtClass> throwables14 = new HashMap<String, CtClass>();
scanJar(jdk14JarFile, jdk14Pool, jdk14Throwable, throwables14);
log.info("jdk14 throwable count: "+throwables14.size());
String jdk5Jar = args[1];
JarFile jdk5JarFile = new JarFile(jdk5Jar);
ClassPool jdk5Pool = new ClassPool();
jdk5Pool.appendClassPath(jdk5Jar);
CtClass jdk5Throwable = jdk5Pool.get("java.lang.Throwable");
HashMap<String, CtClass> throwables5 = new HashMap<String, CtClass>();
scanJar(jdk5JarFile, jdk5Pool, jdk5Throwable, throwables5);
log.info("jdk5 throwable count: "+throwables5.size());
// For each jdk14 excetion, find the exceptions with new ctor signatures
CtorComparator compare = new CtorComparator();
StringBuffer exceptionCtors = new StringBuffer();
for(CtClass jdk14EX : throwables14.values())
{
CtClass jdk5EX = throwables5.get(jdk14EX.getName());
if( jdk5EX == null )
continue;
CtConstructor[] ctors14 = jdk14EX.getConstructors();
CtConstructor[] ctors5 = jdk5EX.getConstructors();
if( ctors14.length != ctors5.length )
{
// Find the new set of ctor signatures
TreeSet<CtConstructor> jdk5Set = new TreeSet<CtConstructor>(compare);
jdk5Set.addAll(Arrays.asList(ctors5));
List jdk14Set = Arrays.asList(ctors14);
if( jdk14EX.getName().equals("java.lang.IllegalArgumentException") )
{
log.info("jdk14(IllegalArgumentException): "+jdk14Set);
log.info("jdk5(IllegalArgumentException): "+jdk5Set);
}
jdk5Set.removeAll(jdk14Set);
for(CtConstructor ctor : jdk5Set)
{
exceptionCtors.append("exceptionCtors.add(\"");
exceptionCtors.append(ctor.getDeclaringClass().getName());
exceptionCtors.append(ctor.getSignature());
exceptionCtors.append("\"),\n");
}
}
}
log.info(exceptionCtors.toString());
}
private static void scanJar(JarFile jar, ClassPool pool,
CtClass langThrowable, HashMap<String, CtClass> throwables)
{
Enumeration<JarEntry> entries = jar.entries();
while( entries.hasMoreElements() )
{
JarEntry entry = entries.nextElement();
String name = entry.getName();
if( name.endsWith(".class") )
{
name = name.replace('/', '.');
name = name.substring(0, name.length() - 6);
try
{
CtClass clazz = pool.get(name);
if( clazz.subtypeOf(langThrowable) == true )
{
throwables.put(name, clazz);
}
}
catch(NotFoundException e)
{
// Ignore exceptions needing other jars for now
log.warning(e.getMessage());
}
}
}
}
}