I have planned to create an SDK in android, that means to share my class files and resource(layouts) to another application that requires them. If I export my application as JAR it does not include the resource files and R.class. I know currently Android does not support to packaging resource file via JAR but I searched the net and found one solution if compile our resource files with source code means we can access the resource in some other application.
So for that reason I did it in the following way:
copied all res folders content into my source folder
src
->com.mypackege
-> res--->here i put my res folder
finally my src folder look like
src
com.mypackage
>myfile.java
drawable-hdpi
drawable-ldpi
drawable-mdpi
drawable-xhdpi
com.mypackage.drawable
com.mypackage.layout
com.mypackage.menu
com.mypackage.values
and i build my project i got all class files including resource and
r.class in my bin
then i create jar manually by jar -cvf mysample.jar com/mypackage/*
the final jar contain all classes and resource of my project in side
mypackage.
then I add mysample.jar into another application say testapp, here I put the JAR in asset folder(because of layout )and add to build path. And also I configure the build path
In this application I call the myfile.class from mysample.jar which is needed to load the layout from that JAR.
The problem is here it doesn't see resource under the JAR file it only see the resource in current project res folder and though NULL pointer Exception
But it calls the R.java from JAR file. Ad also i tried to put xmlns:custom="http://schemas.android.com/apk/res-auto" in my manifest file it is also not working.
I hope I exactly come to close this issue, it may be a resource mapping problem.
do you have any idea to resolve this?
You can't store resources in jar. It's possible, but it's tricky, so for now Android provides just Android Library. Otherwise you can use compiled source code and resourses separately (by providing resources ID's to your library)
Related
[![enter image description here][1]][1]I am trying to load folder. This folder is placed inside JAR when the Project is build and this JAR file is located inside ZIP.
When I try to load as the resource, this is the value its returning.
ClassLoader classloader = Thread.currentThread().getContextClassLoader();
URL resource = classloader.getResource("templates");
zip:-
zip:/u01/app/iotdomain/servers/d1/tmp/_WL_user/mnt/artifacts/iot/server/
ServerCon/p7u/lib/Verticals.jar!/templates
Tried many different ways but couldn't find the solution.
As you stated in your question, the resource that you need to get access to is located
inside JAR when the project is build
and the jar file is packed inside a zip archive:
this JAR file is located inside ZIP
That would mean that this image is a representation of your project structure with your resource in its resource folder
and this whole project is exported as a jar file and said jar file is then again packed in a zip.
If that is the case, you can access your file as stated here.
If I did not get your point please provide a picture of your project hierarchy or clarify where all the relevant files are located.
I have a Spring app that I am deploying as a .jar.
The app has to write to a folder located in /src (precisely /src/main/resources/patches). I have this path directly in the code.
In application.properties: PATCH_DIR = src/main/resources/patches
The app has to also read a json file from src/main/resources/myJson.json, the path also being directly written in the code.
Prior to deploying, while running from the IDE everything goes well, the app sees the file and the folder and reads and writes correctly.
After building the .jar the paths change, the file is located in myJar.jar/BOOT-if/classes/myJson.json and the folder is respectively in myJar.jar/BOOT-if/classes/patches.
How can I specify these paths in the code in a way that even after building the jar they stay relevant to my application?
Edit: I can specify the path of the file as: PatchApplication.class.getClassLoader().getResource("myJson.json").getPath();
This should solve the problem, as the path is relative to the class and not to the root of the project, but it does not improve anything.
You should specify a path in your file system,instead of the path inside a .jar.When you run your app ,it would access the given path.
generally all the classes goes to classes folder in jar.
all the classes ending after src/main/java goes to /classes/ folder
and similarly all the resources file
Eg. your source folder have src/main/java/com/mypack/ABC.java than you will find this in jar as /classes/com/mypack/ABC.class .
Try using /classes/patches and /classes/myJson.json.
This should work
I am trying to export my app into jar using intelij Idea artifacts. I export everything except for resources (14,5GB is in my opinion too much for .jar file) so I have put /res folder inside same folder as jar.
Right now my structure looks like this:
/SAR.jar
/res/colors/
/res/icons/
/res/map/
However I cant access this resources. I am using the following code to get path:
dir = new File(getClass().getProtectionDomain().getCodeSource().getLocation().toURI().getPath() + "/res/icons/");
It works when running from IDE and it prints correct location. But when I build an artifact and run it through cmd I get the null pointer and it prints this path: D:/JavaProject/SAR/out/artifacts/SAR_jar/SAR.jar/res/icons. But my resources are not inside jar file they are only in same directory.
Any ideas? I have done only android projects in path and I simply cant get this resources system with jars to work.
Thanks in forward
You are trying to access the ressources with a path dependent of your source code location, which is obviously not the case since you separated the code (or bytecode in the case of the jar) and the ressources. You must access them with a path relative to the jar or an absolute path.
I think you just need the following path (if the jar was ran from the directory containing the jar) :
new File("res/icons/icon.png")
I have a maven project with typical project structure. At the base of the project, I have a directory names res that has some resources (> 500 MB).
I am trying to use
this.class().getClassLoader().getResourceAsStream("res/xxx")
this code fragment to read from that folder, but it returns a null resource stream.
I have a few workarounds below, but none of these are acceptable due to reasons explained below.
I can move the folder to {base}/target/classes, and it will be read, but it will also get cleaned when I do a mvn clean. Hence, this approach doesn't work. For some reason, specifying the path as ../../res/xxx also doesn't work.
I can move the folder to {base}/src/resources, but then it will get copied to target/classes and the jar. Hence this is also not acceptable.
Though I am open to trying some other java APIs, I may have to use the class loader mechanism only as there is some external library component that is also trying to access the res folder using the similar approach.
Is there some way I can read the res folder from projects base directory? Is there some setting in pom.xml file that can help me with that?
Use this.class().getClassLoader().getResourceAsStream("/res/xxx") and then you will be reading from the root of the classpath irrespective of the actual file/folder location in windows or Linux. This is actually one of the safest ways to read files especially when you do not know how your application will eventually be deployed.
It means though that your classpath must include the parent of res and that res/ must be copied over when you deploy your app
Otherwise, if you want to use relative paths, try this snippet (taken from this SO answer):
String filePath = new File("").getAbsolutePath();
filePath.concat("path to the property file");
If you use this.class().getClassLoader().getResourceAsStream("/res/xxx"), it is going to try to load resources from the classpath. If that's not want you want to do, you're going to need to specify an absolute path.
Resource on Classpath
If you don't want the resource built into your JAR, I'd suggest having a different maven project with the file in it, under the src/main/resources directory. This will create a jar file with the file in it, which will be ~500MB.
After this, you can include a dependency on this project in your project containing your application code. This will then be able to reference it from the jar file using getResourceAsStream(...).
If you don't want this large jar file to ship with your application, make sure you mark the dependency with <scope>provided</scope>.
File from Absolute Path
You will need to take the file location as a parameter in your main method, and then use new File("C:\\path\\to\\your\\file.txt") and then use a FileReader to read it in.
I am working on a Java project that I want to deliver to my client as a .jar file. However, I want to allow the client to be able to change the parameters of the program without having to recompile or recreate the .jar. Basically, I want to be able to load .properties files from classes inside the .jar but locate those .properties files outside of the .jar and even outside the working directory.
I have been testing my attempts inside Eclipse, which might be causing some of the problem but I don't see how at the moment. My setup is a follows. I have one project that contains a few classes that I build a .jar file from. I have a .properties file that is used to create a ResourceBundle whenever a class for the .jar is created. I specify that an additional directory, "conf/", be included in the .jar classpath within the .jar manifest.
Once the .jar file is built, it is copied to the lib/ directory of another project which I am using for testing. This test project includes the .jar file as a library ("Add External Jars..") in the Java Build Path. The .properties file is located the conf/ directory which is at the same level as lib/, src/, and bin/ but I am unable to accces it there. The only way I have been able to get it to work is to locate conf/ under src/ (and bin/) but I would like to be able to use it up one level. Is this possible?
Here's the entry in the .jar manifest file...
Class-Path: ../conf/
Here's the ResourceBundle call that I tried (didn't work)...
rb = ResourceBundle.getBundle("..conf.BaseProject");
Here's the directory structure that works now (names have been changed to protect the innocent)...
/Project
/Project/bin
/Project/bin/conf
/Project/bin/conf/BaseProject.properties
/Project/bin/TestClass.class
/Project/lib
/Project/lib/BaseProject.jar
Here's the directory layout I want (again, file names not important)...
/Project
/Project/bin
/Project/bin/TestClass.class
/Project/conf
/Project/conf/BaseProject.properties
/Project/lib
/Project/lib/BaseProject.jar
You can get it using the Classloader.
I like Spring's ClassPathResource