<build>
<sourceDirectory>src/main/</sourceDirectory>
<testSourceDirectory>src/test/</testSourceDirectory>
+ <testResources>
+ <testResource>
+ <directory>src/test/resources</directory>
+ </testResource>
+ </testResources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<includes>
<include>javassist/JvstTest.java</include>
</includes>
- <forkMode>once</forkMode>
+ <additionalClasspathElements>
+ <additionalClasspathElement>resources</additionalClasspathElement>
+ </additionalClasspathElements>
+ <forkMode>once</forkMode>
<workingDirectory>runtest</workingDirectory>
</configuration>
</plugin>
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
return null;
}
- public void close() {}
-
public String toString() {
return directory;
}
return null; // not found
}
-
- public void close() {
- if (jars != null)
- for (int i = 0; i < jars.length; i++)
- jars[i].close();
- }
}
final class JarClassPath implements ClassPath {
- JarFile jarfile;
+ List<String> jarfileEntries;
String jarfileURL;
JarClassPath(String pathname) throws NotFoundException {
+ JarFile jarfile = null;
try {
jarfile = new JarFile(pathname);
+ jarfileEntries = new ArrayList<String>();
+ for (JarEntry je:Collections.list(jarfile.entries()))
+ if (je.getName().endsWith(".class"))
+ jarfileEntries.add(je.getName());
jarfileURL = new File(pathname).getCanonicalFile()
- .toURI().toURL().toString();
+ .toURI().toURL().toString();
return;
+ } catch (IOException e) {}
+ finally {
+ if (null != jarfile)
+ try {
+ jarfile.close();
+ } catch (IOException e) {}
}
- catch (IOException e) {}
throw new NotFoundException(pathname);
}
+ @Override
public InputStream openClassfile(String classname)
- throws NotFoundException
+ throws NotFoundException
{
- try {
- String jarname = classname.replace('.', '/') + ".class";
- JarEntry je = jarfile.getJarEntry(jarname);
- if (je != null)
- return jarfile.getInputStream(je);
- else
- return null; // not found
- }
- catch (IOException e) {}
- throw new NotFoundException("broken jar file?: "
- + jarfile.getName());
+ URL jarURL = find(classname);
+ if (null != jarURL)
+ try {
+ return jarURL.openConnection().getInputStream();
+ }
+ catch (IOException e) {
+ throw new NotFoundException("broken jar file?: "
+ + classname);
+ }
+ return null;
}
+ @Override
public URL find(String classname) {
String jarname = classname.replace('.', '/') + ".class";
- JarEntry je = jarfile.getJarEntry(jarname);
- if (je != null)
+ if (jarfileEntries.contains(jarname))
try {
- return new URL("jar:" + jarfileURL + "!/" + jarname);
+ return new URL(String.format("jar:%s!/%s", jarfileURL, jarname));
}
catch (MalformedURLException e) {}
-
return null; // not found
}
- public void close() {
- try {
- jarfile.close();
- jarfile = null;
- }
- catch (IOException e) {}
- }
-
+ @Override
public String toString() {
- return jarfile == null ? "<null>" : jarfile.toString();
+ return jarfileURL == null ? "<null>" : jarfileURL.toString();
}
}
else
list = list.next;
}
-
- cp.close();
}
public ClassPath appendSystemPath() {
package javassist;
import junit.framework.*;
+import java.io.File;
import java.io.FileInputStream;
import java.lang.reflect.Method;
import javassist.bytecode.*;
assertTrue("[class path: ]".equals(pool.toString()));
}
+ public void testReleaseJarClassPathFileHandle() throws Exception {
+ String jarFileName = "./empty.jar";
+ ClassLoader classLoader = getClass().getClassLoader();
+ File jarFile = new File(classLoader.getResource(jarFileName).getFile());
+ assertTrue(jarFile.exists());
+
+ // Prepare class pool and force it to open the Jar file
+ ClassPool pool = ClassPool.getDefault();
+ ClassPath cp = pool.appendClassPath(jarFile.getAbsolutePath());
+ assertNull(cp.openClassfile("nothere.Dummy"));
+
+ // Assert that it is possible to delete the jar file.
+ // On Windows deleting an open file will fail, while on on Mac/Linux this is always possible.
+ // This check will thus only fail on Windos if the file is still open.
+ assertTrue(jarFile.delete());
+ }
+
+ public void testJarClassPath() throws Exception {
+ // TODO: Verify that classes can be loaded from a JarClassPath
+ }
+
public void testSubtype() throws Exception {
CtClass cc = sloader.get("test1.Subtype");
assertTrue(cc.subtypeOf(cc));