The .cfg file created by JPackage contains some useful metadata such as the app.version. Here's a snippet...
app.name=MyApp
app.version=1.0
app.runtime=$APPDIR\runtime
app.identifier=com.company.package
app.classpath=
app.mainmodule=application/com.company.package.Main
[JavaOptions]
[ArgOptions]
Is there a simple way to query this file through Java without manually loading the file from the file system and parsing it?
For context, we would have liked to retrieve the version from the manifest within the JAR, but unfortunately this doesn't seem to be available when the application is built using modules.
Cheers.
Some of those fields can be read from the system properties inside the app - assuming you use jpackage --app-version flag:
System.getProperty("jpackage.app-path");
System.getProperty("jpackage.app-version");
System.getProperty("java.home");
System.getProperty("java.class.path");
If there are other fields that are important to you it is also possible to specify other settings to apply to launchers using --java-options "-Dyour.field=XYZ"
Related
I have a micronaut project where I want to have an unnversioned configuration file for private data (like database connections and so on)
This information have to be loaded through #Property annotation, but since there will be more than one .yml (there will also be at least an application.yml) y want to be able to provide file's path to #Properties to be able to differentiate where to look for property.
Since it's my first micronaut project I'm a bit lost with this stuff but taking springboot as an example, what I want to do is something like:
#PropertySource("classpath:configprops.properties")
But after reading micronaut documentation(https://docs.micronaut.io/latest/guide/index.html#configurationProperties) I found myself unable to do this (except from something like just reading the plain file which I guess would not be micronaut compliant)
I do it by passing jvm arguments.
For example, If I am running it on my local machine using gradle:run, I add following to build.grade
run.jvmArgs('-Dmicronaut.environments=dev', "-Dmicronaut.config.files=${System.getProperty("user.home")}/auth-config.groovy")
For my jar deployment, I have made a deploy.sh file as follows :
#!/bin/bash
fuser -k 8181/tcp
nohup java -Xmx512m -Dmicronaut.environments=staging -Dmicronaut.config.files=<path-to-config>/config.groovy -jar application-0.1-all.jar > application.log 2>&1 &
Also note that I am passing different environment names, this helps you to include development environment config directly in code if you want.
Like
application-[environment_name].groovy
application-[environment_name].yml
application-[environment_name].properties
This will help new contributors on your project to speedup the process project setup, I generally also include note in my application-dev.groovy file
DEVELOPER NOTE:
***** DO NOT COMMIT ANY CHANGE IN THIS FILE IF YOU MAKE ANY
*******************************************************
***** CREATE <config.groovy> file in your <HOME> folder and copy paste content of this file
***** Override properties as required
*******************************************************
We would like to keep the .properties file out of the jar so that we can change the properties used in a module and we do not have to re-install the module.
Before Java 8, we used to run a script and include the .properties file in the way below and it worked. But since when we updated to Java 8 , this way of including .properties file in classpath is not working, means java program fails not finding the .properties file.
My script to run the java project:
/usr/java/latest/bin/java -d64 -Xms1G -Xmx16G -XX:MaxPermSize=128m -XX:-UseGCOverheadLimit -cp "/online/sand/lib/client-api-1.0.0.jar:/online/sand/oap_pub/lib/*:/online/sand/oap/oap_dw/run/client_api/application.properties" team.online.client.api.MasterProcessor | tee -a client_api.log
We are using Sping context to pick up the properties file this way:
<util:properties id="app_props"
location="classpath*:/application.properties" />
Then a property in that appilcation.properties files is being used ( in many different files) this way:
#Value( "#{app_props[\"SERVICE_PATH_GET_METADATA\"]?:''}" )
private String metadataServicePath;
Looking for a way to keep the.properties file out of the jar and in classpath so that Spring context finds that file.
Is their any other way than using ? We need to keep the properties file excluded from jar
class.getClassLoader( ).getResourceAsStream( "application.properties" );
Thanks in advance.
Use this if you are using xml based config
<context:property-placeholder location="classpath:application.properties"/>
Then it will load the properties from anywhere as long as it is in class path not in the jar. You have to include it in class path as $CLASSPATH:application.properties
For annotation based, #PropertySource("classpath:application.properties")
There is a sample here
Java: read properties file using spring annotations
I found a workaround making changes in the script to run the program by using "::" instead of ":" .
Got the idea :
==> java and javac are handling the classpath settings in a different way,
javac is searching for classes in / if the classpath contains double Classpath delimiters ("::" under Unix, ";;" under Windows).
From this link which seemed convincing to me and that works. Please take a look here:
https://bugs.openjdk.java.net/browse/JDK-4809833
I have a Spring Java 1.8 project exported in a .jar. When I want to run this Java .jar application, I'd like to give a file into the argument which .xml config file should the program use in the relative folder. I tried so many ways, but none of them works.
For example:
sampleJavaPorgram.jar config1.xml
(config1.xml and sampleJavaProgram.jar is in the same directory)
shoud load config1.xml like that:
ApplicationContext context = new ClassPathXmlApplicationContext("config1.xml");
Maybe use Command-Line Argument, to get name of this XML file and then pass it to AppContext.
Or you might use System properties
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."
I'm using launch4j to wrap an executable jar file in my Windows application, but I need to pass references to some of its libraries in through the JVM arguments. The libraries in question reside in the application install directory, and are always located in the same place, relative to the executable.
I'd like to tell launch4j to use executable-relative paths in the JVM options. I know this information is available at the Windows batch script level, but how do you configure launch4j to fetch it?
Edit for clarification: I'm looking specifically for how to make the paths relative to the binary itself, not how to make them relative to the current working directory. The two aren't necessarily the same.
You might add to your launch4j configuration
...
<jre>
...
<opt>-Djna.library.path="%EXEDIR%\\path\\to\\lib"</opt>
<opt>-Djava.library.path="%EXEDIR%\\path\\to\\lib"</opt>
...
</jre>
...
If you need more then a you might seperate several paths by a semikolon as usual.
< opt> Optional, accepts everything you would normally pass to
java/javaw launcher: assertion options, system properties and X
options. Here you can map environment and special variables EXEDIR
(exe's runtime directory), EXEFILE (exe's runtime full file path) to
system properties. All variable references must be surrounded with
percentage signs and quoted.
Source: http://launch4j.sourceforge.net/docs.html
Set -Djna.library.path=<relative path of native libraries> (if using JNA) and -Djava.library.path=<relative path of native libraries>.
Alternatively, this can be done in Java code as: System.setProperty("jna.library.path","<relative path of native libraries>") and System.setProperty("java.library.path","<relative path of native libraries>"). You can append as many paths to refer to. In Windows, use ; to separate the paths.
This setup only has its effect on the JVM runtime of that Java application (not globally like LD_LIBRARY_PATH in Linux.)
Or, you can put this in Launch4J JVM options list under JRE tab. This is what I do in my projects.
One of the options in configuration is to allow a change directory chdir to the executables directory. This will set user.dir to same directory as exe, which you could use to find other application paths.
<chdir>
Optional. Change current directory to an arbitrary path relative to the executable. If you omit this property or leave it blank it will have no effect.
Setting it to . will change the current dir to the same directory as the executable. .. will change it to the parent directory, and so on.
<chdir>.</chdir>
<chdir>../somedir</chdir>
The code which find the actual path to executable will be dependent on OS (readlink, GetModuleFileName etc). Make sure you really test on target OSes..
If I understand your question correct, you have a launch4j executable and a native library within your installation directory:
/launch.exe
/bin/lib.dll
/lib/app.jar
Now you want to start you app.jar with the generated launcher (launch.exe). You app loads the lib.dll.
You can embed a file into your app.jar (marker.txt). Now you can use the ClassLoader
http://docs.oracle.com/javase/6/docs/api/java/lang/ClassLoader.html#getResource(java.lang.String)
getResource("marker.txt);
This will give you something like:
file://c://installdir/lib/app.jar!marker.txt
This String can be parsed. But in fact, I think there should be a better solution for this problem.
You can simply include the directory (e.g. ..\lib) where the libraries are located in the classpath tab in Launch4j. At least that worked for me.