Get absolute path of resource file inside a jar - java

I want to access a file inside a resource folder of the current jar running.
The file is inside of My_app.jar where is located to /apps/dashboard/
I tried to access it like this
String customScriptPath = "script/template.sh";
public String getTemplatePath() {
Resource temp= new ClassPathResource(this.customScriptPath, this.getClass().getClassLoader());
try {
File templateFile = temp.getFile();
logger.info("Script template path = "+templateFile.getAbsolutePath());
return templateFile.getAbsolutePath();
} catch (IOException e) {
logger.error(e.getMessage());
e.printStackTrace();
}
return null;
}
and I got this error
class path resource [script/template.sh] cannot be resolved to absolute file path because it does not reside in the file system: jar:file:/apps/dashboard/My_app.jar!/BOOT-INF/classes!/script/template.sh

You can't use File to access the template.sh. File is used to reference files in the file system. In your case, you are trying to reference something inside a jar file.
If you want to read content of template.sh, take a stream using Resource.getInputStream(). If you want to log location of the file, use Resource.getURL().

Related

java get url of html file that is in project package

In my project, I have created a package that am calling htmlRepository. In this package, I have created an Html file called mapping.html. I would like to access this file, convert it to a url so I can use the setPage method to diplay it in a JEditorPan.How can I access this file in order to get its url.
I have used the code below to do this if the file resides outside the project package i.e on some folder on my computer.
NodeName = Node;
try {
NodeURL = new File(filename).toURI().toURL();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
However, this means that when I create the jar then I will have to have another folder with the HTML.So I created the Html package so I can carry the Html files in the jar and access them from there. How can I go about this. Thank you in advance.
You should load it as a resource file using the context class loader as so:
URL url = Thread.currentThread().getContextClassLoader().getResource(fileName);
and by filename you should include the full nested directories before your file starting from the resources dir

Access local file in cloud environment

I'm trying to access GeoLiteCity File, it's working on my local machine but unable to get path on the cloud (Azure).
file saved exactly hierarchy like:
/src/main/resources/database/GeoLiteCity.dat
My Code:
void getFile() {
if (this.file == null) {
try {
URL url = this.getClass().getClassLoader().getResource("database/GeoLiteCity.dat");
this.file = new File(url.toURI());
System.out.println(file.getPath().toString());
} catch (Exception ex) {
System.out.println(file.getPath().toString(),ex);
}
}
}
Assumption that the code is a part of Java WebApp running on Tomcat. Per my experience, if you want to get the resource via the method this.getClass().getClassLoader().getResource("<the data file path relative to the root classes path>"), so please make sure the data file GeoLiteCity.dat under the path webapps/<your-webapp-name>/WEB-INF/classes/database/.
If your webapp was deployed on Azure WebApp, I think you can try to use the absolute path of data file on Azure WebApp, such as D:/home/site/wwwroot/webapps/<your-webapp-name>/<the data file path>, and only use new File("<the absolute path of data file>").

Loading resources from another maven module with mvn exec:java doesn't work

I have a maven project with this structure:
parent
-----module1
--------src
------------main
-----------------java
----------------------Loader.java
-----------------resources
-------------------------file1.txt
-----module2
--------src
------------main
-----------------java
-------------------------CallLoader.java
So Loader.java, loads files1.txt. I call this class from CallLoader.java from module2. This is the code I used
In Loader.java,
private static File getResourceFile(String fileName){
try {
URL resource = GraphUtil.class.getClassLoader().getResource(fileName);
return new File(resource.getPath());
} catch (Throwable e) {
throw new RuntimeException("Couldn't load resource: "+fileName, e);
}
}
where fileName="file1.txt".
I get an error because the file absolute path looks like this:
file:/home/moha/.m2/repository/my/package/name/%7Bproject.version%7D/base-%7Bproject.version%7D.jar!/file1.txt
What exactly am I doing wrong?
Get the content of your file as a stream instead in order to be able to read your resource from a jar file which is the root cause of your issue. In other words use getResourceAsStream instead of getResource.
You can also return the URL instead of File then call openStream() later to read it if needed.
NB1: the URL will be of type jar:file/... which cannot be managed by the class File
NB2: To convert a URL into a File, the correct code is new File(resource.toURI())

getResource() unable to read contents of a directory inside jar

I just came around this issue that the main class inside jar is unable to read the contents of a folder.
The class contains
String path = "flowers/FL8-4_zpsd8919dcc.jpg";
try {
File file = new File(TestResources.class.getClassLoader()
.getResource(path).getPath());
System.out.println(file.exists());
} catch (Exception e) {
e.printStackTrace();
}
Here sysout returns false.
But when I try something like this it works
String path = "flowers/FL8-4_zpsd8919dcc.jpg";
FileOutputStream out = null;
InputStream is = null;
try {
is = TestResources.class.getClassLoader().getResourceAsStream(path);
byte bytes[] = new byte[is.available()];
is.read(bytes);
out = new FileOutputStream("abc.jpg");
out.write(bytes);
out.close();
} catch (IOException e) {
e.printStackTrace();
}
getResourceAsStream() is able to read the path of the folder inside jar but getResource() is unable to read it,
why is it so and what is the difference between the reading mechanism of these two methods for contents inside jar.
The contents of the simple jar
Both getResource() and getResourceAsStream() are able to find resources in jar, they use the same mechanism to locate resources.
But when you construct a File from an URL which denotes an entry inside a jar, File.exists() will return false. File cannot be used to check if files inside a jar/zip exists.
You can only use File.exists which are on the local file system (or attached to the local file system).
You need to use an absolute path to get the behavior you're expecting, e.g. /flowers/FL8-4_zpsd8919dcc.jpg, as sp00m suggested.

Get file in the resources folder in Java

I want to read the file in my resource folder in my Java project. I used the following code for that
MyClass.class.getResource("/myFile.xsd").getPath();
And I wanted to check the path of the file. But it gives the following path
file:/home/malintha/.m2/repository/org/wso2/carbon/automation/org.wso2.carbon.automation.engine/4.2.0-SNAPSHOT/org.wso2.carbon.automation.engine-4.2.0-SNAPSHOT.jar!/myFile.xsd
I get the file path in the maven repository dependency and it is not getting the file. How can I do this?
You need to give the path of your res folder.
MyClass.class.getResource("/res/path/to/the/file/myFile.xsd").getPath();
Is your resource directory in the classpath?
You are not including resource directory in your path:
MyClass.class.getResource("/${YOUR_RES_DIR_HERE}/myFile.xsd").getPath();
A reliable way to construct a File instance from the resource folder is it to copy the resource as a stream into a temporary File (temp file will be deleted when the JVM exits):
public static File getResourceAsFile(String resourcePath) {
try {
InputStream in = ClassLoader.getSystemClassLoader().getResourceAsStream(resourcePath);
if (in == null) {
return null;
}
File tempFile = File.createTempFile(String.valueOf(in.hashCode()), ".tmp");
tempFile.deleteOnExit();
try (FileOutputStream out = new FileOutputStream(tempFile)) {
//copy stream
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = in.read(buffer)) != -1) {
out.write(buffer, 0, bytesRead);
}
}
return tempFile;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
It is not possible to access resources of other maven modules. So you need to provide your resource myFile.xsd in your src/main/resources or src/test/resources folder.
The path is correct, though not on the file system, but inside the jar. That is, because the jar was running. A resource never is guaranteed to be a File.
However if you do not want to use resources, you can use a zip file system. However Files.copy would suffice to copy the file outside the jar. Modifying the file inside the jar is a bad idea. Better use the resource as "template" to make an initial copy in the user's home (sub-)directory (System.getProperty("user.home")).
In maven project, lets assume that, we have the file whose name is "config.cnf" and it's location is below.
/src
/main
/resources
/conf
config.cnf
In IDE (Eclipse), I access this file by using ClassLoader.getResource(..) method, but if I ran this application by using jar, I always across "File not found" exception. Finally, I wrote a method which accessing the file by looking at where app works.
public static File getResourceFile(String relativePath)
{
File file = null;
URL location = <Class>.class.getProtectionDomain().getCodeSource().getLocation();
String codeLoaction = location.toString();
try{
if (codeLocation.endsWith(".jar"){
//Call from jar
Path path = Paths.get(location.toURI()).resolve("../classes/" + relativePath).normalize();
file = path.toFile();
}else{
//Call from IDE
file = new File(<Class>.class.getClassLoader().getResource(relativePath).getPath());
}
}catch(URISyntaxException ex){
ex.printStackTrace();
}
return file;
}
If you call this method by sending "conf/config.conf" param, you access this file from both jar and IDE.

Categories