Specifying the location of Java communication libraries - java

Is there a workaround or a solution to having to place the javax.comm.properties file and the win32com.dll file in their respective folders?
My program works fine when I have the files stored as below:
%JAVA_HOME%/jre/lib/ext/comm.jar
%JAVA_HOME%/bin/win32com.dll
%JAVA_HOME%/lib/javax.comm.properties
This worked well until IT changed the permissions on our computers so that we can no longer write to these folders. I'd like to be able to install the Java program I wrote that uses the serial port once without needing to re-install it every time IT decides to update our JVMs. Does anyone know of a way to do this?

It's always a good practice to decouple the execution of your application from the configuration of the machine it is running on. In your case the first task will be identifying where you want to store the extra libraries and configuration files that are needed (its probably best to bundle them with your application). Once that is done, then you can configure your application to find them at launch:
Assuming the following directory tree:
myapp
|
--lib (archives and shared libraries stored here)
|
--resources (configuration files go here)
You could do:
java -Xbootclasspath/a:myapp/lib/comm.jar -cp "myapp/lib/*:myapp/resources" -Djava.library.path="myapp/lib"
Your JAR and DLL files would go into the lib sub-folder, and the property file would go into the resources subfolder.

Related

Java Jar file main class run when runs from command line, but not from Windows batch file

I'm re-using a standalone Swing-based Java class which backs up and restores mysql databases.
I've tested running it from a Windows batch file (.bat) on my dev system, and it works there.
But, if I run the batch file on a different Windows , I get a "main class not found" exception.
However, when I run the command directly on the command line, it works.
The command in the batch file to run it is:
java -cp lda-services.jar;bip-services-1.6.0.0-SNAPSHOT.jar;decryptor-1.6.0.0-SNAPSHOT.jar;slf4j-api-1.7.31.jar;commons-io-2.6.jar com.ilcore.util.SosaMaintenanceJFrame
The SosaMaintenanceJFrame class is contained in the lda-services jar.
Here's the error message:
Error: Could not find or load main class com.ilcore.util.SosaMaintenanceJFrame
Caused by: java.lang.ClassNotFoundException: com.ilcore.util.SosaMaintenanceJFrame
The class is definitely in the jar file, as I've extracted it the file and seen it.
Any thoughts on why this would be happening? I need to run inside a batch file so the user can just click on it to run it.
Most likely explanation
Your paths are relative, which means that the batch file isn't going to work unless you run it from the right place. In general, having a batch file that has an invisible rider stapled to it with: "I break in mysterious ways if not run from the appropriate dir" is a crappy batch file - make it better.
Better solution
Or, even better, get rid of it. You don't need batch files to distribute java programs.
Proper ways to distribute java programs:
The modern take is very very different from what you have here: JREs are dead, you must ship an installer that does the whole thing, notably including a java runtime (no longer called a JRE, and one you ship and keep up to date if relevant). That's perhaps a bridge too far for what you're doing here. Relevant tools include jlink.
A slightly less modern take involves jars with manifests:
Your jar file should contain a manifest. This manifest must contain 2 relevant entries:
Class-Path: lda-services.jar bip-services-1.6.0.0-SNAPSHOT.jar decryptor-1.6.0.0-SNAPSHOT.jar slf4j-api-1.7.31.jar commons-io-2.6.jar
and
Main-Class: com.ilcore.util.SosaMaintenanceJFrame
You can use jar's -m switch, or just include the manifest (it's just a file in the jar): it's at META_INF/MANIFEST.MF and it's a text file, each line is an entry, and an entry consists of a key: value pair.
When a jar contains this, just double clicking the jar and running java -jar thejar.jar will then take care of it all: Java will load the stated jars as part of the classpath, and these, crucially, are resolved as paths relative to the directory the jar is in, so it DOES work when you try to launch them from elsewhere, i.e. if you do:
C:
CD \
java -jar "c:\Program Files\MyApp\myapp.jar"
it works fine, whereas that batch script would fail due to being in the wrong place.
Build systems let you define the manifest too, check your build systems docs for how to do this, it'll be easy, and there are tons of tutorials if you search the web for e.g. 'manifest executable jar maven' or whatnot.
You can consider making a shaded jar. But I wouldn't.
A shaded jar takes all your dependencies and packs them into your main jar, so that there is only one jar. There is now no need for a Class-Path entry (the jar you run is obviously already on the classpath and there's nothing else to include) and your app is shipped as 'just' a single jar file.
But this is mostly a red herring: There are no consumer JREs anymore so you've made the user experience from a D- to a D. If you actually care about giving your users a nice experience, there's no getting around an installation process of some sort and once you have that, having the separate jars is no longer a problem. Separate jars are less hairy when signed jars are involved, are much easier to keep up to date, and have a significantly faster turnaround (when you build your stuff and want to ship what you built, shading takes ages, so it's nice to cut that step out). The faster your CI system tells you about failing tests, the better.
Meet in the middle
You don't have to upgrade to modules and the like. What you can do instead is use something like launch4j. The aim is to end up with a zip file along with the installation instructions: Make a dir somewhere. unzip this zip in it. Doubleclick 'myapp.exe'. Done.
The zip would contain an entire JRE, all your jar file deps, and your main app, and an exe file which launch4j made for you, that launches your app using the JRE packed into the jar. This means you know exactly which JRE is being used, and it'll work even on systems that didn't have one installed yet (which, these days, should be all of them - the notion of 'end user downloads a JRE from oracle and the user + oracle work together to keep that thing up to date and security-issue-free', is dead).
The fact that it's an EXE is nice: Now if the user e.g. alt+tabs through their apps, they get your app, with your name, and your icon, instead of 'javaw.exe' with an ugly coffee mug logo.
But when I try running it from the jar file generated by Maven, however, I get a "class not found" exception.
Even if you didn't get that error, you'd get another one unless you'd used Maven Shade, as that's the only way you're going to run that with a single jar. My guess as to why that particular error occurs is that the app class you're attempting to run is in fact in one of the *SNAPSHOT* jars

How to refresh a java application after making a file change

This may sounds like a dumb question to some, but I am not a Java developer, we have moved a Java app from Rackspace server to AWS linux server and upgraded MySql from 5.2.x to 5.7.x. Some SQL statements are causing issues so I am trying to fix those inside the .java files. However, when I save the file, and use .sftp library from VSCode to push the changes to the linux server, then refresh the site, it does not reflect the changes. Is there anything else I need to be doing every time I make a change?
I was able to update some string in a .jsp file and that worked when I refreshed, so I am not sure why when I change a .java file, it does not reflect change.
The entire directory is confusing to me, I believe it was done so that all files, configs, tomcat files, etc. would be under one git folder so that it can just be dropped anywhere. I find a lot of sources state that a .war file would be created and you would place that file in the tomcat apps directory.
Here is the basic layout of the directory of the app
-www/live/njun
-build.xml
+lib
+scripts
+sql
+src
-tomcat(has some config files, scripts, webapps folder)
-web
-content
-index.jsp
-trampoline
-includes folders with .java files
-tickets
-ticketsMgr.java (this is the file I modified but I could not see any differences in app)
-index.jsp (this is one I modified and did reflect in browser)
-WEB-INF
-classes/com/njun
-lots of folder that have .Class files(although when I open them it's all gibberish characters)
This is the basic structure of what I am looking at.
I tried going to the /opt/tomcat/bin and > sh startup.sh - to restart tomcat. That didn't work.
I also ran the > sh startup.sh version inside of the tomcat folder above,
/tomcat/bin/sh startup.sh - that shows me some info where the home, base tmpdir, jre_home, etc. But that didn't work neither.
I am not being asked to make major modifications on this app, I figure I can manage the SQL errors myself. If we get to the point where we need enhancements done to this app, we would hire a Java developer.
Please let me know if I am missing something and I can provide.
Thanks in advance,
That's because a .java file is just source code. You need to compile it and upload the corresponding .class file generated when you compile the .java sources. How to compile and run a Java program. Or well, since it runs on a Tomcat instance, you might have a JAR or WAR file. But the idea is still the same, since those are just basically zip files that hold your .class files (among other stuff that's less relevant for your issue).

Distributing Java Application and files

I have just written a java application to talk to a blood machine. And it posts its data to a web server using OAuth security and XML, and the application works great.
But now I need to distribute it to customers who have these machines. This program is in a .jar file and its also requires other .jar files which are in my project/dist folder.
During the execution it uses little .png files which are displayed as icons on the screen, that the user can click etc.
I want to some how wrap all of this together (including the images) and distribute them either by an installer or i can use a web server.
What is the best way to accomplish this, i tried to copy the .jar and the dist folder (as per the instructions that came out of netbeans) but when I run java -jar myfile.jar it prints out the text i had from the IOException because i have not included the .png files.
Code for the PNG files:
Im using this:
try
{
databaseimage = ImageIO.read(new File("image/database.png"));
databaseDisconnectedImage = ImageIO.read(new File("image/database_delete.png"));
}
catch (IOException ioe)
{
System.out.println("Problem Creating Systray: "+ioe.getMessage()+" Current Working Directory is: "+System.getProperty("user.dir"));
}
You have a number of alternatives including the following:
Build an installer that installs the relevant files on the user's machine. You can either write it from scratch or use a commercial or open-source tool to create the installer. (Installing on multiple operating system types gets complicated ...)
Restructure your application so that all resources (e.g. images) are fetched via the classpath rather than directly from the file system. Then create an executable "Uber-JAR", by exploding all of the dependent JARs and resources, assembling the files into one tree, and JAR-ing the tree. (The JAR is made executable by adding a couple of entries to the manifest.)
Create a JNLP launcher for the application. This only works if the end-user is going to be able to access the website that hosts the application files, but it neatly solves the problems of updating the application, and ensuring that the user is using an up-to-date JVM.
Which is best? Each alternative has pros and cons, and you will need to work out which is best for you.
Heavy-hitting solution is to use Maven and create an executable jar, a.k.a. an assembly, a.k.a. a jar-with-dependencies. A jar can contain both its dependencies and the meta-data to run it properly.
java -jar Client-1.0-SNAPSHOT-jar-with-dependencies.jar
Would work. I assume there's a similar solution using Ant, which is another tool to build Java programs.
More manually: Just think for a second - whatever command including the classpath you use to run your program, make sure to save that into a script. All files that it needs bundle it up into a .zip and send that over, with the instructions to unzip and cd into it. Ultimately you're just running a bunch of files, you just need to send them over and preserve directory structure so your script will work.

Java + jar file

I have written a quick Java wrapper that fires off the NMAP executable and waits for it to finish. I am using Eclipse. I would like to include the NMAP source/executable
in my Java jar file so that I have a self-contained package.
Within Eclipse I have added the NMAP folder hierarchy. Within Eclipse I can see Java firing off the NMAP utility correctly, and waiting for the utility to end before exiting.
So far, so good. I then export a JAR file for with eclipse. I can see the NMAP folder hierarchy present. However when I try to run the JAR file it is having trouble finding nmap.exe. Can a foreign executable be called from with a jar file? if not, what are
my options? If so, why can't it find it within the jar file when it could find it within Eclipse?
Thanks.
You will need extract the .exe and its required support files onto the disk before you can access them as regular files (which execution through standard methods requires, I believe). You can look up examples of how to copy a resource from a jar to a file using getResourceAsStream() on one of your class files in the jar.
Once extracted, you can execute is as you are doing now (you might need to ensure execution rights, etc. based on your OS)
The "execute native program" facility does not understand how to invoke EXE-files inside other files (like ZIP or JAR).
If you want to do this, you must extract the files to a file system location and invoke it there. Due to the diversity of Linux distributions (PowerPC? other library versions etc) you should probably ask the user to install it instead and invoke that instead of bringing your own.
To my knowledge, you cannot execute an executable embedded in a jar file.
One solution would be to embed the executable in the jar file. Then use getClass().getResourceAsStream("/path/to/executable") to retrieve the bytes and output them to a temporary file (File.createTempFile()). On UN*X system, you will have to chmod u+x file before trying to execute. Eventually, you could delete the temp file or create the file once and reuse it everytime and call deleteOnExit().
Of course, this solution implies that you have executable(s) that work on all platforms.
Your solution probably works in eclipse because your "executable" file is not in a jar.
You may also have to be careful of how you are distributing this because Nmap isn't free for use in commercial software.
There is an open source library for Java to call Nmap but it assumes that Nmap is installed on the OS on which you are running your code. That API is Nmap4j and it is on sourceforge.net.

How to refer a jar outside exe in Java desktop application?

I have a Java application installed. The jar is bundled into an .exe file using Launch4J. Now I want to create a patch for this application.
If I create another jar containing only updated files, how can I refer it in the original code?
I have java application installed. ..Now I want to create a patch for this application.
This is one of the strengths of the Java Web Start launch technology that comes with the J2SE. Simply update the Jar on the server, and the next time the app. launches, it will be updated.
The update can be honed for your use-case, configured to be done lazily or eagerly, before or after launch, or even programatically controlled using the JNLP API's DownloadService.
..And the jar is bundlled into an .exe file ..
'Unfortunately', JWS works on Windows, ..and Mac., and *nix - so you may have to expand your horizons.
BTW - I have no idea how to do the same with Launch4J, but then, that is really the wrong question. I aim to provide an answer to the right question, which is "How do I deploy & update a Java rich client?". ;)
I've never worked with Launch4J, however I think you should try to affect the classpath. JRE always loads the classes from the classpath. From this point of view, jars have no added value and just serve as a containers for your *.class files and resources.
Now, if you succeed to configure your tool to do something like:
classpath = C:\Temp\my_patch_path;$your_current_classpath
then its enough to put your changed files into C:\Temp\my_patch_path (of course preserving the package structure). JRE will load your classes first in this case.
Hope, this helps
Mark
It is might not be possible to do this without changing the contents of the exe.

Categories