I am running a project using $ activator "run 8081". In the application, I try to read an xml file using the following command:
resource = ClassLoader.getSystemClassLoader().getResource(filePath)
The problem is that the resource is null. After debuging, I noticed that the running ClassLoader.getSystemClassLoader().getURLs() returns a single jar file. Which means that the above code is trying to load filePath from inside this jar file.
Any ideas on what I can do to fix this problem and load the filePath? Note that I have to keep the ClassLoader.getSystemClassLoader().getResource(filePath) as is, but I can change the value of filePath and environment variables, etc.
EDIT:
How do I set the classpath for activator when I run it in dev mode: $ activator "run 8081"?
Answering this can help answer my original question.
Related
I have a spring boot web app but I want to load the application.properties file in another path because it has private information about database connection string.
Here are things what I did:
Remove the application.properties file in the default path like this:
src
main
resources
application.properties
I tried a kind of command line (I use gradle not maven):
> gradle clean assemble
> java -jar -Dspring.config.location=<Insert the path here> build/libs/<jar-file>
As usual. The code would run with the configuration of application.properties file as my desire. But many changes later seems doesn't save and still run old code before it has changed. How to solve it?
You can try find the answer here.
Try to use other profile configure file and override what you need within.
Or if there are just a few things to change, you can override them without properties file. For example:
./gradlew run --args='--server.port=8080'
or
java -jar -Dserver.port=8080 app.jar
With this setup (from Eclipse using Windows10)
I was able to correctly start my SpringBoot application. This one worked too (same directory pattern):
Now I'm packaging my project as JAR and I want to use an external properties file. I had an teste32.yml file beside my JAR at the same directory (also tried to use it inside /config directory, as show here, but it didn't work either)
I want to dynamically use a properties file beside my JAR file everytime. Doesn't matter at which directory they are, I wanted to dynamically point to a properties file always at the same directory as the JAR is. I want to say to my client: "take this JAR and this file, put them wherever you want and run this command X and everything will be alright". I'm trying to discover command X but before I add some dynamic path, I'm trying with absolutes paths. I'm using this:
java -jar myJar.jar -Dspring.config.name=teste32 -Dspring.config.location=C:\workspace\myProject\target\
I manually copied teste32 inside target\ to test this. But this didn't work. This didn't work either (only spring.config.location variants):
-Dspring.config.location=file:C:\workspace\myProject\target\
-Dspring.config.location=classpath:/
-Dspring.config.location=file:C:/workspace/myProject/target/
I also tried with no spring.config.location, only name
So my questions are:
What does classpath: and file: mean? Until now I got the 2 correct setups by pure luck and I would like to understand when to use them.
When I have my project package as a JAR, what classpath becomes?
Finally, which combination is necessary to dynamically use a properties always at the same directory as the JAR?
UPDATE
Using --debug at the correct example got me this line at the very begging (Spring banner was still visible):
2018-09-25 15:45:14.480 DEBUG 11360 --- [ main] o.s.b.c.c.ConfigFileApplicationListener : Loaded config file 'file:src/main/resources/xirulei/teste32.yml' (file:src/main/resources/xirulei/teste32.yml)
But after moving myJar.jar and teste32.yml to a specific directory and running java -jar myJar.jar -Dspring.config.name=teste32 --debug (without spring.config.location, since teste32 is at the same directory as JAR), I simply didn't get any ConfigFileApplicationListener debug line.
a) java -jar myJar.jar -Dspring.config.name=teste32 -Dspring.config.location=C:\workspace\myProject\target
Did you check content of target dir? I'm pretty sure your cfg file is placed to target\classes\xirulei and it is why Spring cannot find it in target
b) When you place teste32.yml in the same directory as jar file then Spring must be able to find it (given this directory is working directory) without -Dspring.config.location (but you still need to provide -Dspring.config.name=teste32)
c) When you use -jar and do not provide additional class paths then classpath: points to the root of packages inside jar. Spring cannot find your file at classpath:/ because your file is at classpath:/xirulei/
Well, after all it was a simple mistake. As documentation says and as already pointed here, it should be
java -jar myproject.jar --spring.config.name=myproject
and not
java - jar myproject.jar -Dspring.config.name=myproject
As stated on question, only when using Eclipse -D(JVM argument) is necessary. When using bash/cmd, just --(program argument) is the correct option:
Both class.getResource(FILE_NAME) and class.getClass().getClassLoader().getResource(FILE_NAME) run perfectly inside my eclipse but the same code getting failed to locate the file which is inside the jar file, when run as an executable jar in windows machine.
I have gone through all related links available for this problem (well, not exactly the same issue but 90% in sync), asked for solution but no reply came from any of those posts, so I'm posting my issue as a separate question hoping for help on this.
In total, 4 cases I have ran to resolve but none worked so far and I'm out of ideas now.
class.getClass().getClassLoader().getResource("/resources/readme.txt");
class.getResource("/resources/readme.txt");
class.getClass().getClassLoader().getResource("resources/readme.txt");
class.getResource("resources/readme.txt");
Ouf of all the above 4 cases, only 2 cases ran successfully in eclipse which are as mentioned below.
class.getResource("/resources/readme.txt");
class.getClass().getClassLoader().getResource("resources/readme.txt");
The other 2 cases just throwing me Exception in thread "main" java.lang.NullPointerException
Coming to the executable jar, all 4 cases are throwing me the Exception in thread "main" java.lang.NullPointerException.
So I have created a folder named resources where my jar is residing and placed my files inside this folder and ran the jar. Now the jar is running without any issues referring to the files inside the resources folder I created. So wherever I run this jar (windows, linux etc.,) I need to create a resources folder and place my files under the folder. Now the question is, can it be possible to make my jar refer the resources folder which is inside the jar itself?
Any help on this is much appreciated!
To get your txt file:
File yourFileIsHere = new File("resources/readme.txt");
Where put your file?
In the same location of your jar, example:
myapp/yourjar.jar
myapp/resources/readme.txt
If you want read file inside of your "src" folder:
InputStream yourInputStream = new YourClass().getClass().getClassLoader().getResourceAsStream("readme.txt");
If you are using Spring:
org.springframework.util.ResourceUtils.getFile("classpath:readme.txt")
Otherwise:
import com.google.common.io.Resources
byte[] byteSource = Resources.asByteSource(Resources.getResource("readme.txt")).read()
method class.getClass().getClassLoader().getResource() may take 3 prefixes: url:, classpath: and file: each prefix tells what is your base of search. If you want to search inside your jar use classpath: prefix. That tells your classloader to search everywhere within your classpath. Here is one example how to deal with it with Spring tools. Look also at ResourceLoader class in Spring
I uploaded a Spring application to Heroku but the application crashed with the following error:
java.io.FileNotFoundException: class path resource [com/myname/myapp/config/dao-context.xml
The file is definitely there, and it is in GIT, and the app runs successfully locally.
Any ideas what is happening here?
I suspect that when you are running locally, it is picking up the file on the classpath as a regular file on the filesystem (i.e. not inside of a JAR).
On Heroku, it is probably inside of a JAR file, which means it is not a regular file, and must be read as an input stream, which might look like this:
ClassLoader cl = this.getClass().getClassLoader();
InputStream inputStream = cl.getResourceAsStream("com/myname/myapp/config/dao-context.xml");
You can probably reproduce the problem locally by running the same command that's in your Procfile.
If this is not the case, then make sure the file exists on Heroku by running this command:
$ heroku run ls com/myname/myapp/config/dao-context.xml
For future visitors to this question, I overcame the problem by converting my DAO XML config file to the Java Config method, therefore Spring no longer required that XML file. This didn't directly solve the issue of being unable to find the XML file, but the added benefit is that I am now using the more modern and less verbose Java Config method.
I wrote a program that works on my laptop perfectly, but I really want it to work on a server that I have. Using NetBeans, I've clean and built the project. I copied the contents of the folder dist on my server but I cannot seem to get to work by using command
java -jar nameOfFile.jar
I get the error
java.lang.NoClassDefFoundError: org/....
I have been doing some reading and from what I gather is that I need to pretty much specify where the libraries that I've used are located. Well they are located in a subfolder called lib.
Question:
So what would I need to do in order to be able to run my jar?
CLASSPATH is an environment variable that helps us to educate the Java Virtual Machine from where it will start searching for .class files.
We should store the root of the package hierarchies in the CLASSPATH environment variables.
In case of adding or using jar libraries in our project, we should put the location of the jar file in the CLASSPATH environment variable.
Example: If we are using jdbc mysql jar file in our java project, We have to update the location of the mysql jar file in the CLASSPATH environment variable. if our mysql.jar is in c:\driver\mysql.jar then
We can set the classpath through DOS in Windows
set CLASSPATH=%CLASSPATH%;c:\driver\mysql.jar
In Linux we can do
export CLASSPATH=$CLASSPATH:[path of the jar]
Hope it helps!
Try that:
java -classpath "$CLASSPATH:nameOfFile.jar:lib/*" path.to.your.MainClass
What this does is setting the classpath to the value of $CLASSPATH, plus nameOfFile.jar, plus all the .jar files in lib/.
Classpath
A compiler(e.g. javac) creates from .java - .class files and JVM uses these .class files.
classpath - local codebase[About] - points on the root of source. classpath + import_path = full path
For example for MacOS
//full path
/Users/Application.jar/my/package/MainClass
//classpath
/Users/Application.jar
//import_path
my.package.MainClass
Android classpath
ANDROID_HOME/platforms/android-<version>/android.jar
//e.g
/Users/alex/Library/Android/sdk/platforms/android-23/android.jar
When you use a META-INF/MANIFEST.MF file to specify the Main-Class dependencies must be specified in the manifest too.
The -jar switch ignores all other classpath information - see the tools docs for more.
You need to set class path using
The below works in bash .
This is temporary
set CLASSPATH=$CLASSPATH=[put the path here for lib]
If you want it permanent then you can add above lines in ~/.bashrc file
export CLASSPATH=$CLASSPATH:[put the path here for lib]:.
You have 2 questions, one is the "title question" and another is the "foot note question" after elaborating your problem.
Read this documentation bellow to get a better understanding of CLASSPATH.
https://docs.oracle.com/javase/tutorial/essential/environment/index.html
https://docs.oracle.com/javase/8/docs/technotes/tools/windows/classpath.html
This is fast and straight forward for what you need.
For your first question, this will do:
The documentation recommends us to set a classpath for every application we are running at the moment using (use in the command-line):
java -classpath C:\yourDirectoryPath myApp
For your second question, look this exercise in the java documentation. It seems to be the same problem:
https://docs.oracle.com/javase/tutorial/essential/environment/QandE/answers.html
Answers to Questions and Exercises: The Platform Environment
Question 1.A programmer installs a new library contained in a .jar file. In order to access the library from his code, he sets the CLASSPATH environment variable to point to the new .jar file. Now he finds that he gets an error message when he tries to launch simple applications:
java Hello
Exception in thread "main" java.lang.NoClassDefFoundError: Hello
In this case, the Hello class is compiled into a .class file in the current directory — yet the java command can't seem to find it. What's going wrong?
Answer 1. A class is only found if it appears in the class path. By default, the class path consists of the current directory. If the CLASSPATH environment variable is set, and doesn't include the current directory, the launcher can no longer find classes in the current directory. The solution is to change the CLASSPATH variable to include the current directory. For example, if the CLASSPATH value is c:\java\newLibrary.jar (Windows) or /home/me/newLibrary.jar (UNIX or Linux) it needs to be changed to .;c:\java\newLibrary.jar or .:/home/me/newLibrary.jar."