org.iids.aos.util
Class Class2Jar

java.lang.Object
  extended by org.iids.aos.util.Class2Jar

public class Class2Jar
extends java.lang.Object

Utility class to convert a (set of) class files (from the runtime environment) to a JAR file. This utlity also creates a manifest that is contained in the resulting JAR file.

This class currently only works if the class data is present on the local file system. It queries the class loader for the calling thread to find the source of the bytecode to add to the resulting jar. This works if the class is directly on the file system or inside a jar. It is also possible to add the contents of entire packages in one go to the resulting jar file. The resulting jar file is always executable if there is at least one class in the archive.

This class is convenient for those applications that require transporting a (set of) classes as a JAR that are available to the local class loader, without transporting the entire JAR file (which may contain more classes than are needed). This is also convenient if the location of the JAR file is not known in advance to the application. Programs that require the transport of a JAR file (for example, when creating an agent) can just call addClass or addPackage and ship the JAR file that results from getJar.

TODO Remote JAR files cannot be processed (is this even possible?).

Author:
Reinier Timmer (rjtimmer@cs.vu.nl)

Constructor Summary
Class2Jar()
          Creates a new Class2Jar context.
 
Method Summary
 Class2Jar add(java.lang.Class... classes)
          Add a (set of) Class(es) to the JAR file.
 void addClassPath(java.lang.String... classPathEntries)
          Add entries to the Class-Path field of the manifest.
 void addPackage(java.lang.Package p, boolean recursive)
           
 void addPackage(java.lang.String pkgName, boolean recursive)
          Add all classes contained in a package to the resulting JAR.
 void addResource(java.lang.String path, byte[] contents)
          Put a resource in the jar file.
static java.lang.String getBaseName(java.lang.String name)
           
 byte[] getClassData(java.lang.Class cls)
          Read raw class data from the classpath.
 java.lang.Iterable<java.lang.Class> getClasses()
           
static java.io.File getContainingJar(java.lang.Class cls)
          Determine which JAR file a class was loaded from.
 byte[] getJar()
          Generate a JAR file from the classes/main class.
 java.lang.Class getMainClass()
           
static java.lang.String getPathName(java.lang.Package p)
          Get directory name for a given package
static java.lang.String getPathName(java.lang.String packageName)
           
static byte[] getResource(java.net.URI zip, java.lang.String entry)
           
static java.lang.String getZipFileEntryName(java.lang.Class c)
           
static java.lang.String getZipFileEntryName(java.lang.Package p)
           
static boolean isZipDirectoryEntryName(java.lang.String name)
           
static java.util.List<java.lang.Class<?>> listClasses(java.lang.Package pkg, boolean recursive)
          List all classes that belong to a package.
static java.util.List<java.lang.Class<?>> listClasses(java.lang.String pkgName, boolean recursive)
          List all classes that belong to a package.
static void main(java.lang.String[] args)
           
static byte[] readFile(java.net.URI file)
          Read a file completely as a byte[].
 void setMainClass(java.lang.Class c)
          Set the default class for this JAR archive.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

Class2Jar

public Class2Jar()
Creates a new Class2Jar context. To generate a Jar file, first add Classes and/or Packages to the Class2Jar context. Once all desired classes are added, a Jar archive containing only these classes can be obtained by calling the method getJar.

Method Detail

getClasses

public java.lang.Iterable<java.lang.Class> getClasses()

getMainClass

public java.lang.Class getMainClass()

add

public Class2Jar add(java.lang.Class... classes)
Add a (set of) Class(es) to the JAR file. The actual data for these classes is not copied until getJar() is called.

If no default class was set before calling this method, then the first class in the classes list will be set as the main class. This method also processes any (private) internal classes declared by the classes in the list.

Parameters:
classes - A list of classes that will be added to the final JAR file.
Returns:
The current Class2Jar instance

addPackage

public void addPackage(java.lang.Package p,
                       boolean recursive)

addPackage

public void addPackage(java.lang.String pkgName,
                       boolean recursive)
Add all classes contained in a package to the resulting JAR. This only applies to the classes that can be found by the class loader of the calling class.

For now, this only works if the classes are located in a JAR file that can be loaded by the local class loader. Remote JAR files (don't know how this works) or classes not in a JAR are not considered.

Parameters:
pkgName - The name of the package to scan for contained classes.
recursive - If true then the contents of subdirectories in the package tree will also be scanned for classes.

addClassPath

public void addClassPath(java.lang.String... classPathEntries)
Add entries to the Class-Path field of the manifest. This does not change the contents of the jar file, but merely updates the field in the manifest for the Jar file.

This is convenient for jar files (ie. agents) that rely on external libraries. These need not be shipped along with the agent.

Parameters:
classPathEntries - String entries for the class path.

listClasses

public static java.util.List<java.lang.Class<?>> listClasses(java.lang.Package pkg,
                                                             boolean recursive)
List all classes that belong to a package.

Parameters:
pkg - The package to search in.
recursive - Recurse into sub-packages
Returns:
A List of all classes in the package.

listClasses

public static java.util.List<java.lang.Class<?>> listClasses(java.lang.String pkgName,
                                                             boolean recursive)
List all classes that belong to a package.

Parameters:
pkgName - The name of the package (e.g. org.iids.aos)
recursive - Recurse into sub-packages
Returns:
A List of all classes in the package.

setMainClass

public void setMainClass(java.lang.Class c)
Set the default class for this JAR archive. This class is set in the Main-Class field of the JAR manifest. The class itself will also be put in the JAR file (if not already done so).

Parameters:
c - The Class to set as main class of the JAR file.

addResource

public void addResource(java.lang.String path,
                        byte[] contents)
Put a resource in the jar file. The bytes are stored in a specified path (paths separated by forward slashes). In case of relative paths the file is stored in the root.

Parameters:
path - Path name to store the contents in.
contents - Raw byte stream with the file contents.

getJar

public byte[] getJar()
              throws java.lang.ClassNotFoundException
Generate a JAR file from the classes/main class. This includes generating a manifest file, and copying the bytecode from the classes to the JAR file.

Returns:
A byte[] containing the raw JAR file. This can directly be written to a file, or used to create an agent (code segment).
Throws:
java.lang.ClassNotFoundException - If one or more of the classes entered through addClass or addPackage(java.lang.Package, boolean) cannot be found in the class path.

getClassData

public byte[] getClassData(java.lang.Class cls)
                    throws java.lang.ClassNotFoundException
Read raw class data from the classpath. The data is either loaded from a JAR file, or directly from a class file.

Parameters:
cls - The class to read the data from.
Returns:
The raw class data stored in a byte[]
Throws:
java.lang.ClassNotFoundException - Some error resolving the class.

getContainingJar

public static java.io.File getContainingJar(java.lang.Class cls)
Determine which JAR file a class was loaded from.

Parameters:
cls - The class to inspect.
Returns:
A File pointing to where the file is loaded from, or null if the Class was not loaded from a JAR file.

readFile

public static byte[] readFile(java.net.URI file)
Read a file completely as a byte[].

Note: this may take up a lot of memory for large files. It is better to work with input/output streams or writers for copying file contents.

Parameters:
file - Location of the file to read.
Returns:
The file contents in a byte[]

getResource

public static byte[] getResource(java.net.URI zip,
                                 java.lang.String entry)

getBaseName

public static java.lang.String getBaseName(java.lang.String name)

isZipDirectoryEntryName

public static boolean isZipDirectoryEntryName(java.lang.String name)

getZipFileEntryName

public static java.lang.String getZipFileEntryName(java.lang.Class c)

getZipFileEntryName

public static java.lang.String getZipFileEntryName(java.lang.Package p)

getPathName

public static java.lang.String getPathName(java.lang.Package p)
Get directory name for a given package

Parameters:
p -
Returns:
pathname

getPathName

public static java.lang.String getPathName(java.lang.String packageName)

main

public static void main(java.lang.String[] args)


Copyright © 2003, 2004 IIDS Group. All Rights Reserved.