Run Windows Desktop Applications Under The Linux Sub-System - java

A while back I made a switch from C# to Kotlin. Initially I was using Windows 10, but moving to Kotlin highlighted some of the limitations in Windows; notably long Java class paths, and the Windows 280 character limit.
I know there are workarounds to get shorter class paths, like rolling them up into a JAR file, but for the project I was working on (building CorDapps with Corda), none of the workarounds...worked. This was due to some internal code in Corda, which loaded JAR files from the class path using reflection, however the code didn't recursively check those JAR files for class paths.
I eventually switched to Ubuntu and then MacOS and these problems were no more, since neither OS suffers from such limits. However, Windows now has WSL/WSL2 so I can install Ubuntu as a subsystem in Windows 10. That got me thinking...
Is it possible to run Windows applications in the context of a linux system on WSL?
To elaborate on my question, I'd like to be able to run IntelliJ IDEA on Windows as my IDE for Kotlin, but have it consume the JDK installed under a WSL Ubuntu instance, and also execute Kotlin applications under the same instance. Is this at all possible?

Related

JavaFX Could not find or load main class Java 8 Linux

I know this is often a common issue but the Java 8 aspect confuses me. I'm aware that since Oracle removed JavaFX from the Java distribution, this issue is usually resolved with VM arguments (--module-path,--add-modules, etc).
However, I'm exporting a .jar file using jre 1.8.0_202 in eclipse. And this works great without any arguments on my windows machine. Sadly when I move this jar to my linux machine, I see the classic "Cloud not find or load main class". For reference, the linux machine is running 1.8.0_342. I would think that this shouldn't be an issue because I'm using older Java versions?
Any insight on why this works on one platform and not the other?

Running standard exe from java .jar file on clients computers

I have a program that I want to run as an exe on a clients computer. After I made my program in Java I used Jsmooth to create the exe. The program runs perfectly fine from my own local computer, but when I try running the same program on another computer the program prompts me to install Java. After installing Java, the program STILL wants me to install Java. I thought it might be different versions of Java, but I compiled the Jar with the most LTS of Java, and my JRE was on the most recent version. What should I do?
JVMs are quite large. Out of the box, JSmooth therefore doesn't include one. I think you can ask it (I'm recalling exe4j perhaps, a different tool that does the same thing as jsmooth), by stating which path contains one relative to the executable. You cannot fold it straight into the exe, though. It'll then be an installation process where you end up with:
C:\Program Files\AnthonysAwesomeApp\Anthony.exe
C:\Program Files\AnthonysAwesomeApp\jre\lib\rt.jar
C:\Program Files\AnthonysAwesomeApp\jre\bin\java.exe
... and the other 5000 files of a JRE installation
Where 'Anthony.exe' is made by JSmooth, and you told JSmooth that it should use the JRE found in location ".\jre".
That should probably still work.
The more general problem is that the entire deployment model is more or less obsolete; JREs do not exist anymore, at least, oracle/team openjdk has ceased producing them and has ceased mentioning the very concept, but some third party deployers such as Azul still produce them. Java1.8 is the last version that can truly be said to have had the concept of a JRE.
A JDK is a superset of a JRE (It has everything a JRE has, and more), and JDKs still exist, so you should just be able to ship an entire JDK.
The new model is jlink, modules, and treeshaking, and it doesn't feel like any of the exe maker projects such as JSmooth have been updated for it. In general, java is used a ton on servers, but java on the desktop is not observed that much. If you want to delve into those - you have a lot of reading to do, and the experience is not as smooth (heh) as JSmooth.

Automatic and seamless way to install a JVM when distributing app

Let's say I want to distribute a Java desktop app in a native-like way. Is there a tool/technique to build Java desktop application installers that will automatically and seamlessly install a JVM if one does not exist on a system already?
Installing Java apps for users who do not have a JVM is a 2-step process (first install the JVM, then the app). I'd like to match the experience of installing a typical native desktop app by making it a one-step process (or as much one-step-ish as possible).
For Windows, I suggest using NSIS installer to wrap installation of the JRE and your program. That will allow real "installation", ie. JRE will be installed to Program Files and it will be possible to uninstall it from Windows control panel ("public JRE"). You need to bundle the JRE installer for that.
Alternatively, you can bundle the whole JRE ("private JRE") together with your program. You can use Launch4J which configures the launch of your Java application (VM options, classpath etc.) as an EXE file, have the JRE somewhere as one of the folders of your distribution and point Launch4J to use it.
Or, simply have the unpacked JRE ("private JRE") in one of the folders of your distribution and use relative paths to use that one instead of the one installed on the system.
The advantage of a private JRE is that you control which Java version it is. With a public JRE, the user may be able to uninstall it or change the version and then come complaining that your program is not working ;)
For Linux, if you distribute you application as an RPM, you can just declare a Java package to be your dependency. Linux package manager should take care of it all. On the other hand, you can still bundle JRE in your own RPM to be independent of the "main" version installed on the user's machine.

Selecting the correct Java, JRE and JDK versions when building an executable JAR for distribution?

I am putting together my first Java package for distribution to users, and am running into some difficulties. I have jar packages that I've built that users can't run; the error messages vary, but are all "version" something or another. I suspect I'm selecting the wrong build paths, and I'm not quite sure where to start troubleshooting because I don't clearly understand the differences between the Java executable (javaw.exe), the JDK and the JRE; I have some questions that I'd like answered which will help in that understanding. I'm used to the way that C# executables compile in VS; wrapping my head around how executable jar files come together is still a little mysterious to me.
Although I've done a few google searches, most of what I'm finding is how to build a jar file, but not how to manipulate/use/select the Java, JRE and JDK versions appropriately to ensure compatibility. I do understand that the JRE includes the virtual machine that allows Java bytecode to run anywhere, and that the JDK includes development tools...but as to figuring out which version I AM running, vs which version is used when building jar files and which version SHOULD be used...I am completely lost.
I'm using Eclipse Indigo under 64-bit Win7. My build path includes the following:
JRE System Library: C:\Program Files\java\jre7\*
External paths: C:\<MyDocuments>\java\lib\commons-io-2.4*
I also have, installed on my machine, the following paths which are NOT included in the build:
C:\Program Files (x86)\java\jre7\
C:\Program Files (x86)\java\jre1.5.0_22\
C:\Program Files (x86)\java\jdk1.7.0_21\
The users that will be running this executable file are only supported (by corporate IT) up to JRE5. I suspect that my building this pointing it jre7 is one of the things that's messing with me.
My first stupid question is whether there's a difference between "Java" and the "JRE" when it comes to version numbers. For instance, when I read about JavaSE7 or JavaEE7, are they talking about the JRE version for the standard or enterprise editions? Are the development kits and runtime environments just components to JavaSE/EE? Or are they separate and distinct products?
Then, my understanding is that I should build this jar using the lowest-common-denominator JRE expected from my users. In this particular case, because the corporate standard is JRE5, I should build this pointing to JRE5 instead of JRE7. Is that a correct assumption?
Does it matter if I build using the 64bit or 32bit version? Some older machines may still be 32bit running JRE5, so I need to make sure I'm backwards compatible.
The Program Files (x86) naming conventions confuse me. JRE7 installed as \jre7. However, JRE5 installed as \jre1.5.0_22, and I also have jdk1.7.0_21, which, based on the JRE name, I assume to be the Java7 Development Kit. Do I need to install the Java5 Development Kit to properly build this program? And am I properly interpreting the versions from the filenames? that 1.5 represents Java5 and 1.7 represents Java7?
Then, my last question I know there's an Eclipse option to copy the external libraries to the project. I assume that if I do this, this will be included with the jar so the users do NOT need to have the Apache Commons jars on their local machines in order for this to run properly. Does the manifest include any confirmations that these files were included? I've been unable to find any references...so I'm trying to verify if I'm even pulling the Commons libraries over and where to look to get that confirmation.
This is just speculation, but I think you may have to re-write the program with the java5 jdk, because some of the APIs/libraries used in java7's jdk may not be recognized by the java5 jre. (Just like it wouldn't be possible to play PS4 games on a PS2... without any serious modding)
If you write the program in Eclipse, you can just select what library you want to use as you create the Java project. At the "Create a Java Project" screen, you can select the "Use an execution environment JRE:" or "Use a project specific JRE" or "Use default JRE" option. (I have jdk6 and jdk7 installed on my computer so I'm able to select those two options; which is why you may have install the jdk5 in order to create a java 5 project.)
You are properly interpreting the filenames. jre1.5.0_22 is java 5 update 22.
There is a way to specify which JRE is used to run the jar file.
cmd prompt >
"C:\Program Files (x86)\java\jre1.5.0_22\bin\javaw.exe" -jar "filepath_filename.jar"
Drop the "w" from the javaw.exe, and you'll be able to see any console and/or stack trace output.

What packaging tool should I use for a Mac/Windows Java app?

I have a Java desktop app that runs on both the MacOS and Windows.
I understand that I cannot have one distribution for each, which is not a requirement.
I need to know what tool or tools is best to use when delivering a Java app for each.
The tool should install prerequisites (in this case, Java and some JARs) and look native to the respective operating system.
As for OS X's java situation:
Currently, JDK 6 is bundled in the OS.
Presumably, the next version of the OS will still include JDK 6.
It's publicly stated that the OS will have a well-defined place to install multiple copies of Java runtimes, a public interface choosing which of the Java version, etc. See here.
Apple started contributing back its own code to the open JDK community, so JDK 7 should be available as a separate download, see here. 
So, you're not expected to include Java runtime itself into your Java app even then. You're not supposed to install Java in a ramdom place on a filesystem, for example.
As for how you should deploy java apps on OS X:
Double-clicking jar just works.
However, that won't be pretty, because you would only have a generic Java icon in the Dock. You don't want that.
You should use Jar Bundler to make it an honest OS X app. On Mac, it comes with XCode. See the documentation here. You can do that on a non-Mac machine too, using this open-source project.
On Windows, I would recommend either JSmooth or WinRun4J.
On a Mac, the situation is a bit more complex (as the comments point out), but just distributing an executable JAR is probably good enough for now.

Categories