Reading a jar file from resource location - java

In my application I have to read a jar file available in the disk location and segregate .classes file from the jar.
Code is
JarFile jarFile = new JarFile("./resources/CD.jar");
for(Enumeration<JarEntry> em = jarFile.entries(); em.hasMoreElements();) {
String s= em.nextElement().toString();
ZipEntry entry = jarFile.getEntry(s);
String fileName = s.substring(s.lastIndexOf("/")+1, s.length());
if(fileName.endsWith(".class")){
System.out.println(fileName);
}
But I am getting an error
java.io.FileNotFoundException: .\resources\CD.jar (The system cannot find the path specified).

I found a solution to my problem:
Add the 'resource' location to the classpath
Allow external service API to place cd.jar in resources location
Using a child class loader add the cd.jar to the classpath
code snippet is given below:
URLClassLoader childLoader = new URLClassLoader(new URL[] { getURLOfTestclass() }, this.getClass().getClassLoader());
URL url = getClass().getClassLoader().getResource("CD.jar");
return url;

Did you try adding the CD.jar file in your classpath? I would try doing that once.

Change ".\resources\CD.jar" to a fully qualified URI. Eg:C:\Users\Whoever\Documents\resources\CD.jar.

Related

How to get a String value of resources folder (Java)

I'm a beginner in programming and I have a class that requires a path to some folder in its constructor. For example:
SomeClass class = new SomeClass(c:/folder);
I need to get a String value of resources folder (only path to folder without specific file names). A method in that class will add a filename to path from constructor and do some operations with a specific file.
I'm trying to do this (bad code!), but just have npe:
ClassLoader classLoader = getClass().getClassLoader();
File file = new File(classLoader.getResource("src/main/resources").getFile());
String path = file.getAbsolutePath();
So, the question is: how to get String value of resources folder?
What solved my problem:
File file = new File("src/main/resources");
String path = file.getAbsolutePath();
So, I got String path to resources folder.

Absolute Path from File in Package

Let's say I have a package: com.example.resources and inside it I have picture.jpg and text.txt - How can I use only the package path to identify the absolute filepath of picture.jpg and text.txt?
Is this correct?
File file1 = new File("/com/example/resources/picture.jpg");
file1.getAbsolutePath();
File file2 = new File("/com/example/resources/text.txt");
file2.getAbsolutePath();
"I'm trying to reference those files within the application so that when I deploy the application to different systems I won't have to reconfigure the location of each resource "
You don't want to use a File, which will load from the file system of the local machine, you want to load through the class path, as that's how embedded resources should be read. Use getClass().getResourceAsStream(..) for the text file and getClass().getReource(..) for the image
Your current path you're referencing looks like it should work, given the package name you've provided.
Take a look at this answer and this answer as some references.
I've figured out how to do it. Here is the code that I used:
public String packagePathToAbsolutePath(String packageName, String filename) {
String absolutePath = "File not found";
URL root = Thread.currentThread().getContextClassLoader().getResource(packageName.replace(".", "/"));
File[] files = new File(root.getFile()).listFiles();
for (File file : files) {
if (file.getName().equals(filename)) {
absolutePath = file.getName();
return absolutePath;
}
}
return absolutePath;
}
This method was really useful because it allowed me to configure the resource paths within the application so that when I ran the application on different systems I didn't have to reconfigure any paths.

Load class within Jar file and get it's path

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!

have a file in the classloader's root path, how to create it

File f = new File(path)
How to give the path parameter in this case?
You mean something like this?
URL resource = Thread.currentThread().getContextClassLoader().getResource("config.properties");
File f = new File(resource.toURI());
In principle, you need to know from where the classloader loads its resources. This is classloader-dependent, and most types of classloader don't use files at all. If you have an URLClassLoader (which fortunately is quite often), you can ask it about its URLs, and look if there is one file: URL. Then use this URL as a base.
If your Classloader has no file: URL, obviously you have no chance.
But I think most probably you are not doing the right thing - what do you really want to do?
You could use a better option and go for java.net.URLClassLoader.
This class loader is used to load classes and resources from a search path of URLs referring to both JAR files and directories.
A URLClassLoader can be used to load classes in any directory.
Check out this example
// Create a File object on the root of the directory containing the class file
File file = new File("c:\\myclasses\\");
try {
// Convert File to a URL
URL url = file.toURL(); // file:/c:/myclasses/
URL[] urls = new URL[]{url};
// Create a new class loader with the directory
ClassLoader cl = new URLClassLoader(urls);
// Load in the class; MyClass.class should be located in
// the directory file:/c:/myclasses/com/mycompany
Class cls = cl.loadClass("com.mycompany.MyClass");
} catch (MalformedURLException e) {
} catch (ClassNotFoundException e) {
}
Also, have a look at File ClassLoader in Java

Getting file path in java

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("");

Categories

Resources