I am writing a java program that takes my generated .class files and Jars them then loads them into memory using a class loader.
I currently have a working jarring system with the code:
public static int BUFFER_SIZE = 10240;
protected static void createJarArchive(File archiveFile, File[] tobeJared) {
try {
byte buffer[] = new byte[BUFFER_SIZE];
// Open archive file
FileOutputStream stream = new FileOutputStream(archiveFile);
JarOutputStream out = new JarOutputStream(stream, new Manifest());
for (int i = 0; i < tobeJared.length; i++) {
if (tobeJared[i] == null || !tobeJared[i].exists()
|| tobeJared[i].isDirectory())
continue; // Just in case...
System.out.println("Adding " + tobeJared[i].getName());
// Add archive entry
JarEntry jarAdd = new JarEntry(getPackageNameModified +tobeJared[i].getName());
jarAdd.setTime(tobeJared[i].lastModified());
out.putNextEntry(jarAdd);
// Write file to archive
FileInputStream in = new FileInputStream(tobeJared[i]);
while (true) {
int nRead = in.read(buffer, 0, buffer.length);
if (nRead <= 0)
break;
out.write(buffer, 0, nRead);
}
in.close();
}
out.close();
stream.close();
System.out.println("Adding completed OK");
} catch (Exception ex) {
ex.printStackTrace();
System.out.println("Error: " + ex.getMessage());
}
}
Reference to something in code:
getPackageNameModified = com\Test
However, when I go to load the jar into memory I get a error of:
Could not load jar C:\Users\Dalton\AppData\Local\Temp\Test.jar into JVM. (Could not find class com.Test.ObjectFactory.)
I am using a squoop class loader to do this.
AKA:
ClassLoaderStack.addJarFile(jarFileAbsolute, absoluteClass);
Using the following command line the class loader code works properly, but I want to avoid command line in a java program:
jar cf C:\Users\Dalton\AppData\Local\Temp\Test.jar -C C:\Users\Dalton\AppData\Local\Temp\Test\com.Test com\Test
The following fixed my issue:
try
{
byte buffer[] = new byte[BUFFER_SIZE];
// Open archive file
FileOutputStream stream = new FileOutputStream(archiveFile);
JarOutputStream out = new JarOutputStream(stream, new Manifest());
for (int i = 0; i < tobeJared.length; i++)
{
if (tobeJared[i].toString().endsWith(CLASS))
{
// the .replace \\ with / is a java JDK bug that requires all
// paths to use / and end in / for a jar to properly be made
LOG.info("Adding "
+ getPackageNameModified().replace(
DOUBLE_BACKSLASH, FORWARD_SLASH) + FORWARD_SLASH + tobeJared[i].getName()
+ " to the temporary JAR.");
// Add archive entry
JarEntry jarAdd = new JarEntry(
getPackageNameModified().replace(DOUBLE_BACKSLASH,
FORWARD_SLASH) + FORWARD_SLASH + tobeJared[i].getName());
jarAdd.setTime(tobeJared[i].lastModified());
out.putNextEntry(jarAdd);
// Write file to archive
FileInputStream in = new FileInputStream(tobeJared[i]);
while (true)
{
int nRead = in.read(buffer, 0, buffer.length);
if (nRead <= 0) break;
out.write(buffer, 0, nRead);
}
in.close();
}
}
out.close();
stream.close();
LOG.info("Adding complete --> Success");
}
catch (Exception ex)
{
ex.printStackTrace();
LOG.error("Error: " + ex.getMessage());
}
Issue is in java the \ is a bug. All directory splits use a / instead, and end in /. I do not know why this is the issue, but because of it the generated JAR can class load.