I am trying to get inputstream from class file of the other project.
I am using eclipse. The output folder is:
mycurrentproject/WebContent/WEB-INF/classes.
The export library folder is:
mycurrentproject/WebContent/WEB-INF/lib.
When I print "java.class.path", I got this:
D:\apache-tomcat-7.0.42\bin\bootstrap.jar;D:\apache-tomcat-7.0.42\bin\tomcat-juli.jar;
My environment variable of CLASS PATH of WINDOWS system is:
.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar;D:\work\workspace\myjar
My code in package action to get resource stream is:
classfilePath = "/cc/Person.class";
InputStream isInputStream = ModifyMethodTest.class.getResourceAsStream(classfilePath);
Package action is outputed in "mycurrentproject/WebContent/WEB-INF/classes". action.jar is exported in "mycurrentproject/WebContent/WEB-INF/lib".
When cc/Person.class in "mycurrentproject/WebContent/WEB-INF/classes", I got right result. When cc/Person.class in "mycurrentproject/WebContent/WEB-INF/lib" or in "D:\work\workspace\myjar". isInputStream got null. I want to get inputstream form a class file in the other project. The class file maybe in a folder or in a jar file in the target project folder. There should be many classes or jar files in that project. How to do that? For now, and for simple, I test my idea as above to put cc/Person.class in "D:\work\workspace\myjar". But It failed either. Any one have similar experience or advices? Thanks.
EDIT:
classfilePath ="file:D:/work/workspace/myjar/cc/Person.class";
URL[] urls = new URL[] { new URL(classfilePath) };
URLClassLoader ucl = new URLClassLoader(urls);
InputStream isInputStream = ucl.getResourceAsStream(classfilePath);
Here isInputStream still got null. The parameter of getResourceAsStream() is String name. What could be? Something like relative path? Any references?
EDIT2:
It works with code as follow:
String Path1 = "file:D:/";
String Path2 = "work/workspace/myjar/cc/Person.class";
URL[] urls = new URL[] { new URL(Path1) };
URLClassLoader ucl = new URLClassLoader(urls);
InputStream isInputStream = ucl.getResourceAsStream(Path2);
Use an URLClassLoader. Once you've established it, call:
getResourceAsStream("/work/workspace/myjar/cc/Person.class")
For the InputStream.
Related
I am trying to load a class from a jar that is sitting in a directory.
The structure of the class I am trying to grab is as follow:
myapp.jar
|__META-INF
|__com
|__myapp
|__config
|__PlumberConfig.class
This is how I tried to grab the class:
File file = new File("C:/_workspace/_jar/myapp.jar");
URL url = file.toURI().toURL();
URL[] urls = new URL[]{url};
URLClassLoader ucl = new URLClassLoader(urls, ClassLoader.getSystemClassLoader());
LOG.info("URLClassLoader: {}", ucl.getName()); // here always null
Class c = ucl.loadClass("com.myapp.config.PlumberConfig");
The result of new URLClassLoader() is always null hence I cannot go further from this point.
I double-checked everything (the path, name of the jar, and location of the class itself) but seems I am still missing something.
Your code is working but the method getName() is not defined on URLClassLoader. Try ucl.getURLs() instead. Than it should work as expected.
I kow there are dozens (if not hundreds) questions about Java's getResource/getResourceAsStream but i did not find any answers to my problem.
I load jars dynamically with: (String path is given)
File jar = new File(path);
URL url = new URL("file", "localhost", jar.getAbsolutePath());
URLClassLoader loader = new URLClassLoader(new URL[] { url });
c = loader.loadClass(name);
Then within the jar i try to load a resource in the jar. This resource clearly exists in the jar and the whole procedure works if I just run the whole thing with a class loader in Eclipse. In a jar it does not work.$
getClass().getResourceAsStream("resource.dat");
I tried every possible combination of /packageName/resource.dat, packageName/resource.dat, /resource.dat and resource.dat. They all throw a stream closed Exception.
The I tried debugging and ended up printing the URL of these files loaded via getClass().getResource(path)
This led to following URL and it does not look normal to me. Is it supposed to say "localhostC:..."?
jar:file://localhostC:\Users\******\export.jar!/packageName/resource.dat
Converting this URL also throws an Exception (URISyntaxException).
Is this URL really broken or am I just doing something wrong?
Try changing the line:
URL url = new URL("file", "localhost", jar.getAbsolutePath());
to
URL url = new URL("file", null, jar.getAbsolutePath());
The host parameter in the URL constructor is not applicable in this case.
First, the File class has a toURI() method, so the preferred way to get a URL pointing to a file is:
URL url = new File(path).toURI().toURL();
So using this, the class loader:
File jar = new File(path);
URLClassLoader loader = new URLClassLoader(new URL[] { jar.toURI().toURL() });
Next, when you want to load a resource for the jar, use a Class that is originating from the jar, so if you already loaded the Class c:
Class<?> c = loader.loadClass(classPathAndName);
URL resource = c.getResource("data.txt");
This will result in something like:
jar:file:/C:/test/testjar.jar!/testpkg/data.txt
Alternatively you can use the ClassLoader to get the resource like:
loader.getResoure(packageAndResourceName);
But note that this quoting from the javadoc:
This method will first search the parent class loader for the resource; if the parent is null the path of the class loader built-in to the virtual machine is searched. That failing, this method will invoke findResource(String) to find the resource.
I know there are already a lot similar questions here, but I couldn't get any smarter form them. I want to load a class inside a jar file, at this point this is no problem, but when I want to pass the path to my own ClassLoader it throws an exception it cannot find the class. Is it possible to load a class inside a jar using an absolute path? For instance,Class cls = loader.loadClass(/path/MyPlugin.jar/MyPlugin.class);
But when I do this:
File test = new File("path/plugins/MyPlugin.jar/MyPlugin.class");
System.out.println(test.exists());
It prints out false. I tried using MyPlugin.jar!/MyPlugin.class or MyPlugin.jar.jar!MyPlugin.class which i've seen sometimes on the web, even though i don't really know what it means...
When I do this it finds the class:
URLClassLoader loader = new URLClassLoader(new URL[] { "path/plugins/MyPlugin.jar" });
Class cl = loader.loadClass("MyPlugin");
But now, how can I receive the path? Something like URL url = cl.getResource("MyPlugin"); (which gives back a null)
You can obtain URLs to classpath resources using ClassLoader.getResources. To find a jar with specific class, you may use the following
URL url = classLoader.getResource("com/example/SomeClass.class");
JarURLConnection connection = (JarURLConnection) url.openConnection();
JarFile file = connection.getJarFile();
String jarPath = file.getName();
where classLoader is any classloader capable of finding the class you want to load. If the jar is a part of your application's classpath, you may use system classloader:
ClassLoader classLoader = ClassLoader.getSystemClassloader();
Otherwise, you need to know the jar file location beforehand, and create an instance of URLClassLoader, passing the jar in the constructor:
ClassLoader classLoader = new URLClassLoader(new URL[]{new URL("path/to/the/jar/file.jar")});
and then use it to load your class.
If you want to access a file in your jar file you have to put it in the same directory as the class files are.
For example if Main.class is in bin/my/pkg/Main.class you can store your MyPlugin.class in the same directory (bin/my/pkg/MyPlugin.class) and then, if you want to access that file use
URL url = Main.getResource("MyPlugin.class");
Which uses the location of Main.class in your project as root.
Hope it helps!
I am having some issues with Class Loading in Java. Inside my project I am trying to dynamically load a class from anywhere. However, I am currently failing at loading a hard-coded one and am still clueless after 6 hours of googling and stack-overflow checking.
I am suspecting that there is an issue with the package name of the class I am loading.
My goal is to load the Class LoadAClass.java in the project/resources/dynamicFolderNonInClassPath/loadThis directory. Since I am setting my URLClassLoader to the folder above, its package has been set to
package loadThis;
public class LoadAClass{
static{
System.out.println("I am loaded");
}
(...)
}
However I keep getting a class not found exception.
File file = new File("C:/Users/Robert/Documents/workspace/project/resources/dynamicFolderNonInClassPath/");
if (!file.exists()) System.out.println("typo!"); //debug print
URL url = file.toURI().toURL();
URLClassLoader loader = new URLClassLoader(new URL[]{url});
String classToBeLoaded = "loadThis.LoadAClass";
Class classy = loader.loadClass(classToBeLoaded);
System.out.println(classy.getCanonicalName()); //debug print
I have tried different combinations, like setting the URLClassLoader to the file directly or giving the full /resources/dynamicFolderNonInClassPath/loadThis as URL but how so far no success.
Someone in christmasy mood and seeing the problem? There seems to be some misunderstanding on my part regarding this functionality and I'd like to see it fixed.
you are missing a forward slash '/'
File file = new File("C:/Users/Robert/Documents/workspace/project/resources/dynamicFolderNonInClassPath");
if (!file.exists()) System.out.println("typo!"); //debug print
URL url = new URL("C:/Users/Robert/Documents/workspace/project/resources/dynamicFolderNonInClassPath/");
URLClassLoader loader = new URLClassLoader(new URL[]{url});
String classToBeLoaded = "loadThis.LoadAClass";
Class classy = loader.loadClass(classToBeLoaded);
System.out.println(classy.getCanonicalName()); //debug print
See the third line
A .java file isn't a class file. Have you compiled it? You would need a LoadAClass.class file in a "loadThis" directory with your class loader pointing at the directory that contains "loadThis".
Is there a way for java program to determine its location in the file system?
You can use CodeSource#getLocation() for this. The CodeSource is available by ProtectionDomain#getCodeSource(). The ProtectionDomain in turn is available by Class#getProtectionDomain().
URL location = getClass().getProtectionDomain().getCodeSource().getLocation();
File file = new File(location.getPath());
// ...
This returns the exact location of the Class in question.
Update: as per the comments, it's apparently already in the classpath. You can then just use ClassLoader#getResource() wherein you pass the root-package-relative path.
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
URL resource = classLoader.getResource("filename.ext");
File file = new File(resource.getPath());
// ...
You can even get it as an InputStream using ClassLoader#getResourceAsStream().
InputStream input = classLoader.getResourceAsStream("filename.ext");
// ...
That's also the normal way of using packaged resources. If it's located inside a package, then use for example com/example/filename.ext instead.
For me this worked, when I knew what was the exact name of the file:
File f = new File("OutFile.txt");
System.out.println("f.getAbsolutePath() = " + f.getAbsolutePath());
Or there is this solution too: http://docs.oracle.com/javase/tutorial/essential/io/find.html
if you want to get the "working directory" for the currently running program, then just use:
new File("");