Can anyone help me understand the classpath logic when deploying Java applications to remote hosts?
Netbeans will build, deploy and execute my Java application correctly on a remote Linux (Ubutntu 20.x) host.
Lets say that the executable JAR is deployed and executed in:
/home/user/project/dist
With any supporting library files copied to:
/home/user/project/dist/lib
This all makes sense to me.
However, I wish to read application and log4j2 configuration files. I would think that these should be placed in the same directory as the jar file. However they must be placed in the parent directory:
/home/user/project
Okay... BUT...
If I amend my code to write out a text file (to the executable directory) the resulting text file is written to:
/home/user/project/
<Edited 19Jun22>
I want my deployed application to read the log4j2.xml and configuration files from the same directory that my application writes to. What configuration settings must I change in Netbeans?
Alternatively is there a way to make Netbeans deploy to /home/user/project instead of /home/user/project/dist?
Related
I want to run a fat client delivered as a Java web start application without Java web start. I launched it via javaws and managed to get all the jar files mentioned in the JNLP file from the cache after they were downloaded.
I tried running the jar file that contains the main class according to the JNLP file, but I get the 'Could not find or load main class' error. Were I just trying to run a class I'd set the classpath accordingly, but since I'm running a jar file with java -jar, as far as I know the classpath settings will be ignored anyway. Now I'm not sure what to do, does anybody know how to tackle this?
I'll answer this myself now, turns out it is stupidly simple: Get all the jar files, unzip them to get the content, merge all the content (best done with rsync), create a new MANIFEST.MF file that contains the main class to be loaded and the merged hashes for all existing files from all MANIFEST.MF files, zip again to create a jar. That's it.
I am running a cron scheduler which going to run the query and export into excel file in resource folder. When I'm running the program in IDE it is working fine and file is getting created under resource, but when i deploy the code in Tomcat getting this error "java.io.FileNotFoundException: src\main\resources\Report\testQuery.xlsx (The system cannot find the path specified)"
Output from IDE :
Starting
Connected
Executing
Exported Successfully
Closed
Output from Tomcat :
Starting
Connected
Executing
java.io.FileNotFoundException: src\main\resources\Report\testQuery.xlsx (The system cannot find the path specified)
Folder src\main\resources\Report does not exist when you deploy the application to Tomcat. When the project is built, compiled classes and resources are packed into a WAR archive. On runtime, you can access resources from the /resources folder, but you cannot write there.
You need to find some other location for the generated files, ensuring that it will be available for your application when deployed to the application server.
If the files are temporary, you can use File.createTempFile, which is pretty safe to be used in any environment.
You can use your application's working directory, whatever it is. In your IDE it would be your project's root folder (that's why src\main\resources\Report\testQuery.xlsx works), on Tomcat it depends on the server configuration (CATALINA_BASE environment variable). You could create there a /Report subdirectory on the application startup.
How I can set a war in an embedded jetty in a way that it can load from a classpath. Following is my current code snippet
webAppContext.setWar("hello.war");
Context :-
I want to secure my code other than obfuscation.so, I used Jetty to create a runnable jar and subsequently i used winrun4j to create an exe wrapper. The exe works fine when war file is found at same level but not otherwise even though i've embedded the war in winrun4j exe.
Problem:-
Is there any way that i can set the war in a way that it can pick it up from classpath rather than some pre-defined path.
Hope i communicated the problem statement in a lucid way.
Thankyou.
I came around the same and I always extract the war to a temporary location and then use the absolute path;
webAppContext.setWar("/path/to/temp/tmp262622522.war");
In any case Jetty will extract the war to a temporary location too, when starting the web app.
I have created an executable java Swing .jar application. It works fine on Windows. The application hierarchy is :
application.jar
images(Folder) .......... Contains all images the application uses.
libraries(Folder) ....... Contains all external jar libraries the application uses.
bundles(Folder) ......... Contains all bundle files the application uses.
database(Folder) ........ Contains the database files the application uses.
All the above folders exist outside the jar file. Now i am trying to create a Mac executable file (.app) from "application.jar" to run it on Mac so i used the "Jar Bundler" as specified here but when i run the output application.app file nothing happens, nothing runs and i can't even debug it.
I think the main reason is that it can't see the external folders. So is it impossible to create a .app file if the application has external folders ?
And is there a way to debug the .app file to see what's going on ?
Nothing runs, and i can't even debug it.
Diagnostic output from the launch process may be obtained as follows:
$ export JAVA_LAUNCHER_VERBOSE
$ ./YourApplication.app/Contents/MacOS/JavaApplicationStub
There's a related example here.
Most likely the problem is your working directory.
When you run an executable JAR file by double-clicking it, the working directory is the parent directory of the JAR file.
By default, the working directory of an application bundle is its parent directory. If you package the external folders into the application bundle they will be located under $APP_PACKAGE/Contents/Resources.
So the assumption about the working directory that you make for an executable JAR file does not hold for an application bundle.
In order to set the working directory to the resources directory, add
<key>WorkingDirectory</key>
<string>$APP_PACKAGE/Contents/Resources</string>
to the Info.plist file of your bundle.
In case you know nothing about application bundles, please read this document.
This might help: AppBundler by Josh Marinacci
I am not sure about your exact directory hierarchy. But on a Mac with Xcode installed is an application called "Jar Bundler". It exist for exact that purpose you are asking for.
BTW, Mac application use the suffix .app, that is right. But they are not files. Thery are directories.
I use ant for creating .jar files in Eclipse. Works great.
I have a .jar file I am working on that expects the code to be in a .jar file (it looks for .properties files in the same directory as the .jar file) -- the standard Eclipse "Run" and "Debug" menus execute the main() method of a specified Java class... but they do it from the directory containing the compiled class files, not a jar file. Is there a way to change this behavior so Eclipse runs code from the appropriate .jar file instead?
(My workaround right now is to run the .jar file externally, with it suspended waiting for a debugger, per Dave Ray's answer to one of my other questions.)
You could use remote debugging by running your jar like this
java -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005 -jar yourJar.jar
And then connecting from your IDE to that port
Yes, you can create a custom "Run Configuration":
Ie, a "Java Application" one, with:
Classpath tab emptied from its default content (the .class directory) and with the jar added
Source tab with its default content (should reference the src directory of the project)
One such configuration can be run or debugged.
(Example of a custom configuration with jars as user entries)
I just found the following link, which describes the whole procedure in order to debug a Java jar remotely.
Debug Java applications remotely with Eclipse
The main parts are:
Target VM acts as debug server
java -Xdebug -Xrunjdwp:transport=dt_socket,server=y,address="8000" -jar
test.jar
Target VM acts as debug client
java -Xdebug -Xrunjdwp:transport=dt_socket,address=127.0.0.1:8000,suspend=y
-jar test.jar
Based on how you run the target vm, client or server, you have to configure Eclipse differently.
Eclipse configuration if you start the target vm as client
Eclipse configuration if you start the target vm as server
The article gives also a gently introduction into the topic.
I would try to make the code more robust, make the properties file location configurable, or just make it load it from the classpath. Then you can just directly add the properties file to the eclipse classpath. Problem Sovled!