How to restart the Java Process with -Djava.library.path? - java

I have an application that is started with JWS. The first time user launches this application he has to choose a path where Berkeley DB XML is installed. I do need this to set the native library path and restart the application with -Djava.library.path parameter. Berkeley DB XML java bindings uses JNI to make calls to the database. Since our users may have different OS I cannot rely on a default location.
So, I have a problem with getting current classpath. When I print out "java.class.path" it only gives me "/System/Library/Frameworks/JavaVM.framework/Resources/Deploy.bundle/Contents/Home/lib/deploy.jar". I have three jars that I cannot find in my sys props.
on my Mac.
I hope this was understandable and thanks for any tips beforehand.

Try to repaire permissions with DiskUtil.
Avoid using this pattern. What you could do is to store the command and execute that simulating that you are starting a new process.

Related

Write to C:\Program Files from Java program

I have written a Java application that includes a self updater. The self updater loads new program versions from a web server and replaces the application files. While this works perfectly if the application is installed e.g. in the users home directory, it fails on windows machines if it's installed in the C:\Program Files folder. This is because the JVM is executed under the user’s account which has no write access to the program directory.
If a native program, e.g. an installer, tries to write to the program folder, usually a popup appears asking the user to permit the write operation. This doesn’t happen for java applications. Why?
Is there any way to achieve that a write operation of a Java program to a restricted folder brings up the security popup so that the user can permit access to that folder?
Thanks for your responses. According to the answers I see the following options:
Java Web Start
For me this is not an option for end users. I think that no one can expect from an ordinary end user to know what Java Web Start is, what it’s good for and how it’s used e.g. I doubt that an ordinary Windows user knows how to uninstall a Java Web Start application.
Use an exe-launcher with manifest to launch the Java application
As far as I understand this solution the exe-launcher would request extended execution right at application start. This is not exactly what I want, cause for my use case it would be sufficient to get extended rights if an update is available and not on every application start.
Perform the update operation by calling a native executable
One could call a native executable to let it perform the update operation. In this way the application would only request extended rights if an update is available. This sounds not bad but includes some native coding for Windows and doesn’t work on other platforms.
Install a launcher in program folder and the application in user home
One can place a launcher in the program folder that calls the application that is installed in the user’s home directory. In this way it would be possible to update the application in the user’s home folder.
I use InnoSetup for installing my application on Windows and as far as I can see it a split installation is hard to achieve with this installer and probably with other too.
Install the complete application in the user’s home directory
Because the user has write access to his home directory there is no problem at all. For me this looks like the best option cause of its simplicity.
If you are using inno setup compiler to generate your launcher, then you can change your app directory permission.
For example, if you need full control and want to update files under AppName/data folder
[Dirs]
Name: "{app}";
Name: "{app}\data"; Permissions: everyone-full
[Files]
Source: data\*; DestDir: {app}\data\; Flags: ignoreversion recursesubdirs createallsubdirs; Permissions: everyone-full
Unfortunately the increased permissions need to be requested when you first start the program, you cannot promote to them later. Programs that look like they do that are actually restarting themselves with the higher privs behind the scenes.
I had a problem like this a few years ago with a Java app and in the end I installed the application to the user data folder instead of program files as otherwise the auto-updating was a nightmare. You can still add it to the start menu so to a user it looks exactly like any other program.

Change working dir in Java Webstart

Is there a way to change working dir for JVM when running Java Webstart?
When i use system.setProperties("user.dir", newDir) it sets it(system.getProperties() shows it does) but ignores it.
Is this a limitation in Java Webstart to always use the working dir where i started the jnlp file?
I am using all permissions in the jnlp file.
Please help!
EDIT: Whatever i do now, my webstart always uses user.dir to save files. Frustrating!
I've had this question in the past myself, but I've always found that, in the end, I didn't need it. Why do I say this?
Because your java web start app is not like an executable run from Program Files. It doesn't even exist on your computer like most programs (it is broken up into a bunch of different files and reassembled by the JVM). Therefore, you cannot say that the program has its own directory to do what it needs.
But it doesn't need to. Here's why:
Java has the Preferences API to help when you need to store data. The under-workings of the Preferences API is as mysterious as JWS, thus they are really a perfect fit. Either way, if you need to write things to a file, you should check this API to see if it can meet your needs.
If you need to write files for the user, then prompting them and allowing them to choose the location obviously means you won't use your current working directory to read/write files.
If you need to serialize objects, you should just create a program directory using the user.home resource as #AndrewThompson suggested. This will be "your" directory and is as good (in fact, better) than a directory in Program Files (if you're running on Windows, as an example).
In conclusion, in all cases (that I've come across), there's no need to change your current working directory. If you need your own folder, create one in user.home (because you won't run into file permissions issues there).
..all my settings file i use is created in the user.dir.
There is the mistake. Put them in a sub-directory of user.home & the problem is solved.
In the hypothesis you really really need to divert user.dir property for Java WebStart execution, here is the only option I have found: set this system environment variable (so system wide):
_JAVA_OPTIONS="-Duser.dir=C:\Temp"
But care about it, this option is read and applied to any JVM executions.
Why was it required in my context ? Because Java WebStart ClassLoader was looking for any single resource (class, properties...) in user profile before getting it from jar files in cache. As the user profile has been moved to a network storage, application start up became terribly slow. I am still investigating Java sources to understand (and avoid) this behavior. So my applications work perfectly without setting user.dir but that was the only work-around for the performance issue we got at the moment.
The recommended way to pass runtime parameters or user specific setting is through the jnlp argument
<application-desc main-class=".....">
<argument>user.home</argument>
..............

checking if windows update or any installer instace is running before starting my installer( java)

want to make a check in my installer before starting installation if any other installation is running beforehand. Like I want to make a check if windows update or any other installer is running i'll not start my installer.
I'm planning to check if any msiexec instance is running before hand. Is there any better approach, and will that be same for checking windows update. FYI my installer is in java
You should know that msiexec.exe will still be running for a couple of minutes after an installation is finished. This is a default behavior in the OS, it keeps the process alive for a couple of minutes, in case the user will start another installation, to save time from starting it all over again. So checking for the process could give you incorrect data.
Also, if you have your installer written in Java can you please explain why do you need to check for msiexec.exe processes?
Since your installer is in Java, I see no reason to check whether other installers are running, moreover there's no robust way to do so.
Does your installer try to replace system files? It should not.
Does your installer try to update a file in use? It must do it gracefully. And ask user to close an offending application; if it's not possible or user does not want to close the application right away, your installer asks user to restart the system when it completed installation.
Too much to care about, without other installers running. That's why it's wiser to use a specialized installer tool.
To check the OS for installations in progress you can use the following registry entry:
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\InProgress
Please note that Windows Installer does not allow multiple InstallExecuteSequences to be executed simultaneously, however you can launch multiple installation UIs from different packages. The package enters InstallExecuteSequence usually at the moment you press "Install" and grant all the permissions for starting the system changes (creating registry, copying files, etc...).
Here you can find more information about InstallUISequence and InstallExecuteSequence:
http://msdn.microsoft.com/en-us/library/windows/desktop/aa372404(v=vs.85).aspx
Thank u guys for your suggestions, I final decided to go with creating a windows native dll to check the status of WindowsInstaller. The Windows Installer service is currently running if the value of the dwControlsAccepted member of the returned SERVICE_STATUS_PROCESS structure is SERVICE_ACCEPT_SHUTDOWN. Then used JNI to to call it from my java class.

set up database directory

I am working on a Java Desktop program which upon its installation will designate a default database directory and working directory. Where should I save such information so that the next time the user open the program, the program knows where to look for database and working directory?
Things that come to mind:
store everything in the registry (well, did that in MATLAB version and if there is another way, definitely will not go there).
set up another database attached in the jar file to store everything
Is this a so called persistence problem? What are Java Persistence or Java Data Object? Do they have the way to make it working?
any other suggestions?
Take a look at the Java Preferences API. It is a standard Java SE mechanism for storing preferences that does so in a platform specific, but application neutral way. Uses the Registry on Windows, Preferences files on OS X, and I believe ~/.files on Unix.
The Preferences class was created to store things like... preferences in an OS-neutral fashion.
You could also just specify a directory location manually, through a launcher script, or create a default directory in the user's home, and keep both configuration and DB files there.
Your persistent memory is your hard drive, of course, so you need to store data there if you want it to persist from execution to execution. Really, anything goes. You could store the configuration in an XML file -- makes it user-readable outside of the application, which is really nice for debugging, and Java comes with libraries for XML parsing and generation. It would be OS-independent, unlike a registry solution, which is Windows specific. And you could use the XML approach to share information between apps, if that matters. Something to consider.
Update: Preferences are cool! Never saw that one before.

How to create installer once finished with Java Desktop Application with MySQL DB?

I have finished writing a Java Desktop application with a mySQL database. I want to make the application run outside netbeans and let it be installed on other computers. I know about building the project and creating the runnable jar file, however this requires me to export the database itself to the other computer I want the application to run on.
My question is two parts:
1)Is there a way I can create a setup file that also installs the database and the application together?
2)Also my database path is hard coded, does that mean I have to change the code every time I install my application for someone, what is the better way to do that?
Thanks
Yes. You can use some setup builder, like InnoSetup, for example. Personally, however, I like giving my customers a zip file, which they extract wherever they like. The executable jar should be able to handle everything by itself (I like it where there is no need to install the software, just unpack and run).
If it is hardcoded, then yes (but, what do you mean by hardcoded? path to file? ip address?). You should use properties or configuration files for paths and other external things your software depends on. The software should read from those files. Upon startup check for presence of such file(s) - if missing, the user should be shown a window in which the config can be entered.
As for deploying MySQL with your code - consider using a server for that, so that your users are not forced to install MySQL, instead they connect to it over the net. If you need the database only for storing data locally, why not using SQLite or a similar, file-based db engine?
The above answers are just suggestions and more-less reflect the way I am thinking. I would be happy to hear from someone with more experience. Nonetheless, I hope the answers help a little :)
I agree with Sorrow.
If I have to use MySQL, it is normally over the net since I don't want to allow my clients pass through the hazzles of installing MySQL themselves. If however you am stuck with using MySQL locally, investigate MySQL unattended installations + NSIS Installer.
If you can use any db you want, I just use javadb/derby. It comes bundled with most Java installations these days and if not all you need is to add a jar file to you application.
As per 'hardcoding' paths, I really don't understand what you mean. You really don't have 'paths' as it were, I am assuming what you mean is connection string. You don't have to hardcode your connection string, just put some parameters in a properties file and construct your connection string from them.
1) Is there a way I can create a setup file that also installs the database and the application together?
See my answer to Java based Standalone application.
2) Also my database path is hard coded, does that mean I have to change the code every time I install my application for someone, what is the better way to do that?
Have the DB installer pop a JFileChooser to ask the user where they want to install the DB. Store that path using the JNLP API PersistenceService. Here is my demo. of the PersistenceService.

Categories