How to load the class with full absolute path - java

This code works only for the class in the same package. I need to load the file from absolute path like c:/home/lpl/asm/hello.class
Any one please help me do this
InputStream in=ASMHelloWorld.class.getResourceAsStream("/aasm/ClassModificationDemo.class");
ClassReader classReader=new ClassReader(in);

To load a file from an absolute path:
String path = "c:/home/lpl/asm/hello.class";
InputStream in = new FileInputStream(path);
ClassReader classReader = new ClassReader(in);
Obviously hardcoding the path like this, would seriously restrict portability, so the path should be obtained from a command line parameter, user input, a properties file etc.

Why would you want this? If you do something like that you disable the ability to use the program on a different computer, unless you recreate that folder structure.
Seems like a duplicate question to me, just with a different file: Use Absolute path for ClassLoader getResourceAsStream()

Related

How to Play .wav file when your execute a jar file in java. [duplicate]

In my application I load resources in this manner:
WinProcessor.class.getResource("repository").toString();
and this gives me:
file:/root/app/repository (and I replace "file:" with empty string)
This works fine when I run my application from the IDE, but when I run the jar of my application:
java -jar app.jar
The path becomes:
jar:/root/app.jar!/repository
is there any way to solve this problem?
I'll use the "repository" dir name in order to create this:
ConfigurationContext ctx = (ConfigurationContext) ConfigurationContextFactory.createConfigurationContextFromFileSystem(repositoryString, null);
In the same manner, I'll get one file name (instead of a dir) and I'll use it this way:
System.setProperty("javax.net.ssl.trustStore", fileNameString)
It sounds like you're then trying to load the resource using a FileInputStream or something like that. Don't do that: instead of calling getResource, call getResourceAsStream and read the data from that.
(You could load the resources from the URL instead, but calling getResourceAsStream is a bit more convenient.)
EDIT: Having seen your updated answer, it seems other bits of code rely on the data being in a physical single file in the file system. The answer is therefore not to bundle it in a jar file in the first place. You could check whether it's in a separate file, and if not extract it to a temporary file, but that's pretty hacky IMO.
When running code using java -jar app.jar, java uses ONLY the class path defined in the manifest of the JAR file (i.e. Class-Path attribute). If the class is in app.jar, or the class is in the class path set in the Class-Path attribute of the JAR's manifest, you can load that class using the following code snippet, where the className is the fully-qualified class name.
final String classAsPath = className.replace('.', '/') + ".class";
final InputStream input = ClassLoader.getSystemResourceAsStream( path/to/class );
Now if the class is not part of the JAR, and it isn't in the manifest's Class-Path, then the class loader won't find it. Instead, you can use the URLClassLoader, with some care to deal with differences between windows and Unix/Linux/MacOSX.
// the class to load
final String classAsPath = className.replace('.', '/') + ".class";
// the URL to the `app.jar` file (Windows and Unix/Linux/MacOSX below)
final URL url = new URL( "file", null, "///C:/Users/diffusive/app.jar" );
//final URL url = new URL( "file", null, "/Users/diffusive/app.jar" );
// create the class loader with the JAR file
final URLClassLoader urlClassLoader = new URLClassLoader( new URL[] { url } );
// grab the resource, through, this time from the `URLClassLoader` object
// rather than from the `ClassLoader` class
final InputStream input = urlClassLoader.getResourceAsStream( classAsPath );
In both examples you'll need to deal with the exceptions, and the fact that the input stream is null if the resource can't be found. Also, if you need to get the InputStream into a byte[], you can use Apache's commons IOUtils.toByteArray(...). And, if you then want a Class, you can use the class loader's defineClass(...) method, which accepts the byte[].
You can find this code in a ClassLoaderUtils class in the Diffusive source code, which you can find on SourceForge at github.com/robphilipp/diffusive
And a method to create URL for Windows and Unix/Linux/MacOSX from relative and absolute paths in RestfulDiffuserManagerResource.createJarClassPath(...)
Construct a URL, you can then load a resource (even in a jar file) using the openStream method.

Can't find specified path when using .. in the middle?

I'm trying to write in a file with a path like this:
D:\abcd\efgh\..\ijkl\file.txt
So I have an File object with such a path, but in the line
FileOutputStream fos = new FileOutputStream(f);
I get this:
java.io.FileNotFoundException: ..\ijkl\file.txt (The system cannot find the path specified)
Does anybody know what's wrong here? Is there a possibility to resolve the path in an absolute path?
Initialisation of the File object:
File f = new File(strImagePath);
strImagePath is built out of different Strings and looks exactly like the path shown above.
Thanks!
According to your code java try to access the folder D:\abcd\ijkl\file.txt as you have place ..\ijkl\file.txt but in your system doesnot have any file on that path. Thus you are getting the error.
Edit: can you please, try using D:\\abcd\\efgh\\../efgh\\ijkl\\file.txt

How to get absolute path to file in /resources folder of your project

Assume standard maven setup.
Say in your resources folder you have a file abc.
In Java, how can I get absolute path to the file please?
The proper way that actually works:
URL resource = YourClass.class.getResource("abc");
Paths.get(resource.toURI()).toFile();
It doesn't matter now where the file in the classpath physically is, it will be found as long as the resource is actually a file and not a JAR entry.
(The seemingly obvious new File(resource.getPath()) doesn't work for all paths! The path is still URL-encoded!)
You can use ClassLoader.getResource method to get the correct resource.
URL res = getClass().getClassLoader().getResource("abc.txt");
File file = Paths.get(res.toURI()).toFile();
String absolutePath = file.getAbsolutePath();
OR
Although this may not work all the time, a simpler solution -
You can create a File object and use getAbsolutePath method:
File file = new File("resources/abc.txt");
String absolutePath = file.getAbsolutePath();
You need to specifie path started from /
URL resource = YourClass.class.getResource("/abc");
Paths.get(resource.toURI()).toFile();
Create the classLoader instance of the class you need, then you can access the files or resources easily.
now you access path using getPath() method of that class.
ClassLoader classLoader = getClass().getClassLoader();
String path = classLoader.getResource("chromedriver.exe").getPath();
System.out.println(path);
There are two problems on our way to the absolute path:
The placement found will be not where the source files lie, but
where the class is saved. And the resource folder almost surely will lie somewhere in
the source folder of the project.
The same functions for retrieving the resource work differently if the class runs in a plugin or in a package directly in the workspace.
The following code will give us all useful paths:
URL localPackage = this.getClass().getResource("");
URL urlLoader = YourClassName.class.getProtectionDomain().getCodeSource().getLocation();
String localDir = localPackage.getPath();
String loaderDir = urlLoader.getPath();
System.out.printf("loaderDir = %s\n localDir = %s\n", loaderDir, localDir);
Here both functions that can be used for localization of the resource folder are researched. As for class, it can be got in either way, statically or dynamically.
If the project is not in the plugin, the code if run in JUnit, will print:
loaderDir = /C:.../ws/source.dir/target/test-classes/
localDir = /C:.../ws/source.dir/target/test-classes/package/
So, to get to src/rest/resources we should go up and down the file tree. Both methods can be used. Notice, we can't use getResource(resourceFolderName), for that folder is not in the target folder. Nobody puts resources in the created folders, I hope.
If the class is in the package that is in the plugin, the output of the same test will be:
loaderDir = /C:.../ws/plugin/bin/
localDir = /C:.../ws/plugin/bin/package/
So, again we should go up and down the folder tree.
The most interesting is the case when the package is launched in the plugin. As JUnit plugin test, for our example. The output is:
loaderDir = /C:.../ws/plugin/
localDir = /package/
Here we can get the absolute path only combining the results of both functions. And it is not enough. Between them we should put the local path of the place where the classes packages are, relatively to the plugin folder. Probably, you will have to insert something as src or src/test/resource here.
You can insert the code into yours and see the paths that you have.
To return a file or filepath
URL resource = YourClass.class.getResource("abc");
File file = Paths.get(resource.toURI()).toFile(); // return a file
String filepath = Paths.get(resource.toURI()).toFile().getAbsolutePath(); // return file path

InputStream from jar-File returns always null

i know this question has been asked several times, but i think my problem differs a bit from the others:
String resourcePath = "/Path/To/Resource.jar";
File newFile = new File(resourcePath);
InputStream in1 = this.getClass().getResourceAsStream(resourcePath);
InputStream in2 = this.getClass().getClassLoader().getResourceAsStream(resourcePath);
The File-Object newFile is completely fine (the .jar file has been found and you can get its meta-data like newFile.length() etc)
On the other hand the InputStream always return null.
I know the javadoc says that the getResourceAsStream() is null if there is no resource found with this name, but the File is there! (obviously, because it's in the File-Object)
Anyone know why this happens and how i can fix it so that i can get the .jar File in the InputStream?
The getResourceAsStream() method doesn't load a file from the file system; it loads a resource from the classpath. You can use it to load, for example, a property file that's packaged inside your JAR. You cannot use it to load a file from the file system.
So, if your file resides on the file system, rather than in your JAR file, better use the FileInputStream class.

Reading from src/main/resources gives NullPointerException

In my Maven project, I have a xls file in src/main/resources.
When I read it like this:
InputStream in = new
FileInputStream("src/main/resources/WBU_template.xls");
everything is ok.
However I want to read it as InputStream with getResourceAsStream. When I do this, with or without the slash I always get a NPE.
private static final String TEMPLATEFILE = "/WBU_template.xls";
InputStream in = this.getClass.getResourceAsStream(TEMPLATEFILE);
No matter if the slash is there or not, or if I make use of the getClassLoader() method, I still get a NullPointer.
I also have tried this :
URL u = this.getClass().getResource(TEMPLATEFILE);
System.out.println(u.getPath());
the console says.../target/classes/WBU_template.xls
and then get my NullPointer.
What am I doing wrong ?
FileInputStream will load a the file path you pass to the constructor as relative from the working directory of the Java process.
getResourceAsStream() will load a file path relative from your application's classpath.
When you use .getClass().getResource(fileName) it considers the location of the fileName is the same location of the of the calling class.
When you use .getClass().getClassLoader().getResource(fileName)
it considers the location of the fileName is the root - in other words bin folder.
The file should be located in src/main/resources when loading using Class loader
In short, you have to use .getClass().getClassLoader().getResource(fileName) to load the file in your case.
I usually load files from WEB-INF like this
session.getServletContext().getResourceAsStream("/WEB-INF/WBU_template.xls")

Categories