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.
Related
i am currently writing a game on javaFX and i have plans to post it in the website i run in the future (end exploit the Ads while at it). The problem is that after searching around a little it seems there is no way to run a java application on a browser.
Allowing people to run it through the browser would really help sharing the program.
My question is: is there today(2018) any way to run a java application through the web? Though i like java, no browser support seems like a really, really bad idea.
Oh, i also heard of Java Web Start. Although it looks like it is just avoiding the problem (not running in the browser) it seems like a good way to share an application. The problem is that it seems it is (Will be?) deprecated? I am helpless, it is like java isn't even trying anymore...
PS: If it makes any difference my game would be a 2D game with 3rd person view. It will also require some server stuff since players will create "arenas" that others can challenge. I would say my game wouldn't be "simple".
Java Web Start does the job very well—if you are willing to pay for a code signing certificate. (They’re a lot more expensive than regular SSL certificates.) The idea is that a user clicks on a hyperlink on your page, which causes the user’s Java installation to launch your application (possibly after installing it). This requires users to have Java installed beforehand.
If you don’t have the resources or desire to go with a code signing certificate, you can look at https://docs.oracle.com/javase/9/deploy/self-contained-application-packaging.htm. It allows you to create native installation packages for JavaFX applications. The disadvantage: You need each platform to create an installer for it. Meaning, you need Windows to create a Windows installer, OS X to create an OS X installation image, and Linux to create a Linux package. Some may also require signing using native tools.
Java 9 includes the jmod and jlink tools, which are capable of creating a file tree with an executable shell script or .bat file. A major advantage is that you can build such a tree for any platform, regardless of your own platform, if you unpackage the foreign platform’s JDK on your machine. Another advantage is that the user doesn’t need to have Java installed at all. A disadvantage is that the script requires a terminal, unless running on Linux.
Of course, you can just go the manual route and distribute a zip file which contains your .jar file(s), a shell script you’ve written, and a .bat file you’ve written. It’s not elegant, but it’s better than nothing. But it may trip up some non-technical users.
There exist a number of tools which create a native executable from .jar files, but I am not familiar with them (and I prefer to avoid third party tools unless they are truly necessary).
Whatever approach you choose, the answer is the same: You distribute something on your web page which the user downloads and runs. Aside from the download process, the browser is not involved.
What you can’t do is have users run your application inside the browser. That is deprecated, with good reason: It’s a disaster for the browser performance, for the Java runtime, for security, and for the user experience. And Firefox has all but banned plugins, so you’d be locking out a substantial percentage of users.
I have a little .jar that executes a simple system administration task and so it needs to be run with elevated privilege. I've been researching this for hours and now know that it can be done in three ways:
1) ran from an elevated cmd prompt
2) convert the .jar to .exe and bundle it with a manifest file
3) use another .jar to launch my .jar and ask for permission.
Option 1) won't work for me because this will need to be deployed to other users that won't know how to do this. Option 2) isn't ideal because I chose to write this app in Java for its portability. This will likely be run on different systems and Java seems the most compatible. So that leaves Option 3) and is where my question comes in. I can't seem to sift through the multitude of info out there on how to accomplish creating a wrapper for my app. With my specs in mind what do you all recommend for creating a wrapper .jar that will prompt the user to allow my .jar to run? Thanks
On Windows, it is possible to run a Java application either as a desktop application, or as a Windows Service in the background. In the case of a Service, the Wrapper needs to be able to be installed, removed, started, stopped, have its status queried, etc. Depending on whether the application has a GUI or is meant to be run in a command window also determines how it will be run.
On Windows systems, the most way of launching the Wrapper is to make use of dedicated batch files to perform each action of controlling the Wrapper. This makes it possible for the end user to double click on the batch file icons or set up links in menus, just have a look if you have the java runtime env.
Nice tutorial: http://wrapper.tanukisoftware.com/doc/english/qna-service.html
Here it has some other possibilities, using Dedicated Batch File, Command Based Batch File or Standalone Binary : http://wrapper.tanukisoftware.com/doc/english/launch-win.html#dedicated
Think you can do this with .bat file. Make sure you have java runtime env, so that you can execute jar file using java -jar command.
If your looking to force the user to use elevated permissions then pure Java isn't going to cut it. I suggest you write native code and use the Java Native Interface (JNI)
I would like to "link" few file extensions to my java application under windows. When user double clicks file with "linked" extension, I would like to open my app and I need to know path to file that launched app.
If you deploy the app. using Java Web Start, an interest in file-types can be declared in the launch file. See the demo. of the file services, which..
..prompts the user to associate file extension .zzz (simply a file type unlikely to clash with existing file associations) of content type text/sleepytime. ..
When the user double clicks a .zzz file, it should open in the app. Actually, the word 'prompts' there is not the whole story. If you launch the sand-boxed version you will be prompted as to associating the file-type. The trusted version does not prompt.
To add more user-control to the process, look to the IntegrationService that was introduced in 1.6.0_18 (I don't have a demo. of that one yet). You might run it at start-up, after checking with the user.
this would have to be done during installation. how are you planning on letting your user install your application?
you have to realize at this stage that you just made things a whole lot more complicated. registering file extensions means meddling with the registry. what happens if the user doesn't want your application anymore? or moves the file that launches your application?
you'll have to pick an installation creator. here's a so question about that: https://stackoverflow.com/questions/3767/what-is-the-best-choice-for-building-windows-installers
and then you'll have to learn that installer creator's language. here's how what you're asking for is done in nsis. remember that the script takes care of questions like "if the user uninstalls my application, and i didn't change the file associations at install time, should i then remove these file associations on uninstall?" so it's a bit long. here it is anyways: http://nsis.sourceforge.net/File_Association
maybe it can be done in an easier way in another installer creator.
however, in this example, you give the register function of nsis the start command for your application, and then it adds %1 to it in the start command of the windows file association. so you should give it the start command
javaw -cp installpath\yourcode.jar package.name.MainClassName
and then things should work out. this will take some experimenting of course, and you will have to be quite sure about how to start your application from the command line.
good luck!
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.
On his blog Scott Kovatch writes:
Without getting into too much detail, typing ‘java MyAWTCode’ from a Terminal window violates a whole lot of assumptions about what an application is on Mac OS X, and needs a lot of cooperation between the AWT and the Process Manager to sort it out.
http://skovatch.wordpress.com/2011/01/03/secret-smoke-screens/
Out of curiosity - what assumptions are violated? Surely this is just a candidate for an API call with callbacks?
Sure, I can elaborate on that a bit.
The Process Manager starts with the assumption that all applications that present a UI on Mac OS X are bundled, are packaged in a folder named Application.app, binary in Contents/MacOS/Application, and most importantly, have an Info.plist to get things like the name of the application that will be shown in the application menu. When you run a Java application from the command line (Swing or SWT) there is no Info.plist, so we had to create a CFDictionary to be passed off to a private SPI that would register the application, give it a proper name in the Dock -- as opposed to just 'java' -- and could be force-quit.
Even then, it's not perfect, because the Dock also assumes it can store an alias to the bundled application when you right-click and choose Keep In Dock, but since there isn't one that fails silently. There's no way to store a shortcut or command line to start the application like Windows can.
The SWT just calls TransformProcessType, which is a start but is nowhere near sufficient to turn a Java application into a full UI application. For doing pure SWT testing and development it's enough to get you going. When you create an Eclipse RCP-based application for deployment you end up with a bundled application with the Eclipse launcher, and plugins and features, and you're ready to go.
Of course, if you go the extra mile and package your Java application into a bundle, this is all moot, but the vast majority of developers coming from other platforms don't bother and just want to run an executable JAR file or even a folder of class files with a shell script.
I am not sure what he had in mind, but I guess a big difference is the file structure: a normal MacOS X application is a bundle with the structure NameOfTheApp.app/Contents/MacOS/NameOfTheApp , and specific files in the Contents directory. When we use the terminal with a "java" command, the JVM has to create a "virtual" application specific to the Java code, and handle all the MacOS events for it. Also, when you open an application twice in the Finder, it simply activates the application the second time, while you need to launch separate applications every time you use "java MyAWTCode".