The workings of my program:
Connect to server
Get String
Decrypt String
Send it back
I'm decrypting with a class i downloaded from the server. The class changes everytime and should be downloaded everytime i start my program
It HAS! to be in package named etc/etc/client/file.class
It works flawless when i'm testing it INSIDE eclipse cause the package folder is then accesible
But what do i do when i want to export is as runnable .jar ? Then i can't write in the package folder?
The line that's loading the class:
(The class extends Base64 which is already in the folder)
etc.sec.client.Base64 decode = (etc.sec.client.Base64)Class.forName("etc.sec.client." + handlerClass).newInstance();
// Handler class is the name of the class
The folder i'm downloading the class to before loading newInstance():
bin/etc/sec/client/"+filename+".class
Works perfect in eclipse but i do not know how to make it work when exporting to .jar
You will have to load the class using a new class loader.
public void go() throws Exception {
ClassLoader cl = new URLClassLoader(new URL[] { new URL("file:///home/ben/") }, this.getClass().getClassLoader());
Class decoderclass = cl.loadClass("etc.sec.client." + handlerClass);
etc.sec.client.Base64 decode = (etc.sec.client.Base64)decoderclass.newInstance();
System.out.println(decode.toString());
}
If download your class into:
/home/ben/etc/sec/client/
That should instantiate the class fine. Naturally you will have to use the interface available at compile time, etc.sec.client.Base64 must be an interface or your handler class must inherit from it.
Related
I have a web application my requirement is to read some files and process it and persist the file content in database when the application starts.
class MyUtil{
/**
*Read the files
*/
public static void readFiles(){
File file = new File(ClassLoader.getSystemClassLoader().getResource("MyFile").toURI()); //NullPointerException
// ClassLoader.getSystemClassLoader().getResource("MyFile") is giving null in servlet.init() method.
if (file.isDirectory()) {
//Read all the files and persist.
}
}
}
MyFile folder/dir is available in class path. When MyUtil.readFiles() is called in JUnit test case it works fine. But when It's called in servelet.init() method ClassLoader.getSystemClassLoader().getResource("MyFile") gives the null.
You can use getClass().getClassLoader().getResource(...) as an alternative to ClassLoader.getSystemClassLoader().getResource(...)
The alternative works because in webserver there are more than one class loader, and you can't be sure whichone loaded your class. I guess ClassLoader class loaded before anything with default java class loader, and then MyUtil class loaded with different class loader with the webserver hence it resulted in different classpath.
Usually we can use java reflection to get a class by simply doing Class.forName("fully qualified class name").
Now I have a class file (.class) located in client machine. For example, if the client machine is windows and the the class file myClass.class is located in c:\tmp\myClass.class. I have to "process" this class file in another machine in the server to know the class's methods etc.
Please do not ask why this is needed:-) Any suggestions on how to do it?
I think you should make use of Network class loader here. Check this out.
URLClassLoader loader = new URLClassLoader(new URL[] { new
URL("http://123.321.456.121:8080/test/") });
Class c = loader.loadClass ("Hello");
Object o = c.newInstance();
I would like to load a class from another JAR (imported as file during runtime) and handover an Object (this) to the Constructor of the class which should be loaded.
I tried doing that with the following code:
URLClassLoader cl2 = URLClassLoader.newInstance(new URL[] { new URL("jar:file:" + jarPath +"!/") });
Class c2 = cl2.loadClass("main.Class2BeLoaded");
Object loadedClass = c2.getConstructor(Object4Constructor.class).newInstance(this));
It seems so, that the Object which I handover to the constructor (this) can't be used from the code which runs in the JAR.
What is wrong? If I run this code in the same JAR everything works.
In my J2EE web project, I have a simple JSP (HomeScreen.jsp) and a servlet class (HomeScreenServlet.java) behind it. This class is calling non-static method (PDFAwt1) from another class (PDFAwt) which in turn calls many other methods from many different classes, as usually happens.
When I try to create an object of the PDFAwt to call PDFAwt1(), I get an exception:
java.lang.ClassNotFoundException: jxl.read.biff.BiffException
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1360)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1206)
...
Here is a little preview of PDFAwt1()
CreateExcelFile cef = new CreateExcelFile();
ImageConversion.setupPDFToPNG(ReferencePath);
ImageConversion.setupPDFToPNG(NewPath);
File folder = new File(ReferencePath + "/png");
File[] f = folder.listFiles();
File folder1 = new File(NewPath + "/png");
File[] f1 = folder1.listFiles();
...
CreateExcelFile()
import jxl.Workbook;
import jxl.format.Colour;
...
public class CreateExcelFile {
public CreateExcelFile() {
try {
if (!new File("LabelsTemplate.xls").exists()) {
WritableWorkbook workbook = Workbook.createWorkbook(new File("LabelsTemplate.xls"));
WritableSheet sheet = workbook.createSheet("Sheet1", 0);
...
}
}
}
Not able to find where the problem is exactly.. please help..
Missing jar in your class path, if you are using any IDE, download the respective jar and set it in your build path before running the application.
In case you are not using any IDE, add the respective jar's to the lib folder of your web application.
Your code is transitively dependent on some jars and you are missing those on your classpath. Maven is a good tool to avoid such transitive dependencies. If you are not using maven then you need to find the jars that you are using, required what all other jars. As a first step, try to find the jar which contains the follwing class:
jxl.read.biff.BiffException
public class BiffException extends JXLException
Exception thrown when reading a biff file
This exception has a number of messages that should provide some information about the cause:
excelFileNotFound
excelFileTooBig
expectedGlobals
passwordProtected
streamNotFound
unrecognizedBiffVersion
unrecognizedOLEFile
Print the message to see exact problem.
You can find missing jar here
As the name suggests ClassNotFoundException in Java is a subclass of java.lang.Exception and Comes when Java Virtual Machine tries to load a particular class and doesn't found the requested class in classpath.
Another important point about this Exception is that, It is a checked Exception and you need to provide explicitly Exception handling while using methods which can possibly throw ClassNotFoundException in java either by using try-catch block or by using throws clause.
Oracle docs
public class ClassNotFoundException
extends ReflectiveOperationException
Thrown when an application tries to load in a class through its string name using:
The forName method in class Class.
The findSystemClass method in class ClassLoader .
The loadClass method in class ClassLoader.
but no definition for the class with the specified name could be found.
When a web application is loaded in Tomcat it is loaded by a specific classloader, right?
I assume that all libraries (under WEB-INF\lib) used by this web application are all loaded by this same classloader?
In this case, is there a way to load a library under a different classloader without any issues?
The reason I want to do this is because Axis uses some configuration properties that are bound to the classloader and would like to do requests with different properties thereby use a different classloader.
Is this possible?
If you want to load classes programmatically at run time, you can use URLClassLoader, but it can be quite tricky to really get it right. You would do something like this:
URL[] urls = new URL[] {
/* URL to your axis jar */,
/* other URLs you need */
};
URLClassLoader classLoader = new URLClassLoader(urls, getClass().getClassLoader());
Class<...> axisClass = classLoader.findClass(/* fully qualified name */);
Then you should be able to create a new instance of this class and use it.
Edit: Here is a more concrete example, albeit not using Axis because it would be too difficult to set up. I have create a JAR file that contains the following class:
public class Hello {
public Hello(String config) {
}
public String getMessage() {
return "Hello World";
}
}
I have copied this jar file to the source folder of my test project, so I can find it using UrlClassloaderTest.class.getResource("hello.jar"). In a web app, you should probably put it into WebContent/WEB-INF (or something similar) and use the method javax.servlet.ServletContext.getRealPath("WEB-INF/hello.jar") to find it. I can then access the Hello class using the URLClassLoader and reflection:
public class UrlClassloaderTest {
public static void main(String[] args) throws Exception {
URL jarUrl = UrlClassloaderTest.class.getResource("hello.jar");
URLClassLoader cl = new URLClassLoader(new URL[] { jarUrl }, UrlClassloaderTest.class.getClassLoader());
Class helloClass = cl.loadClass("test.Hello");
Constructor constructor = helloClass.getConstructor(String.class);
Object helloObject = constructor.newInstance("some configuration");
Method messageMethod = helloClass.getMethod("getMessage");
String message = (String) messageMethod.invoke(helloObject);
System.out.println(message);
}
}
Note that I can not use Hello as a type here because it is not on the class path of the application, and so it is not known to the class loader of the class UrlClassLoaderTest!