Java lib to change the icon used by an .exe - java

We have a netbeans-platform application, that creates a custom runnable .exe with the default NetBeans icon - as you can guess, when customers install it, they are not happy.
This NetBeans Wiki article and this NetBeans Bug (closed as wontfix) indicate that the platform can't do it natively, and suggest the use of a third-party executable to do it.
However, having a binary executable in our svn repo being called by maven during build time leaves me (and my boss) quite unhappy.
Is there a library in Java, preferably available in maven, that can change the icon an .exe file uses?
EDIT: Upon further research, I found this SO question... that wasn't answered either.
EDIT2: We are also not looking for another packager that can create an .exe for us. We are happy with the default NetBeans' Platform one, and it's already quite well integrated with our dev/release cycle.

It's not a library that accomplishes what you want, but the closest I could find was this - it'll read PE files and it's open source and Java. You may be able to look through the source to find the code that you need.

If you are already using maven you might use launch4j for creating an .exe. There is a maven plugin available. You also might take a look at this netbeans plugin.

Is there a reason you're not simply calling Window.setIconImages() on startup, and loading some images, possibly stored right within the JAR?

Related

Deploying JARs with Java 9 and above (JDK11 in this case) (JLink confusion?)

I'm a Java veteran, but I've been using JDK8 for a long time. I've decided I finally want to upgrade, so I've been using Java11. I've been enjoying the new features, but I've gotten the point where I need to deploy my software.
In the past I would export a runnable JAR from Eclipse and bundle it with an appropriate JRE. Then I'd use both to run the software from an OS-specific program (e.g. an EXE file that fires up the bundled JRE with the given JAR). Of course, now this isn't really an option because JREs are a thing of the past. Supposedly the new system in its place is much lighter weight and straight forward, the only problem is I can't figure out how to actually use it.
I've been reading about how to deploy programs with JDK9 and above and have seen people mention JLink and link documentation to it, but I can't seem to find a straight answer on how to just simply export a runnable JAR. The thing is - I don't really need all of the module support and don't really want to have to configure it. Is there a tool for simply exporting something I can run? How is this done now?
Sorry if this is a dumb question, I'm just genuinely confused at how this all works and can't really find anything online that lays it out in a clear and concise way. There's a lot of documentation on JLink and what it does, but I haven't really found anything that explains the root purpose for all of it.
TL;DR; how do I export working Java programs with JDK9 and above using Eclipse (latest version)?
Thank you for your time!
...how to just simply export a runnable JAR.
Well, if you're not planning on using modules for your application classes, the JAR part should be the same as before. You basically just have to create your own JRE using jlink, e.g.:
jlink --add-modules java.se --output jre
That would create a jre folder with a runtime image that includes all the java.se modules.
You can then bundle that with your JAR like before.
The interesting part here is that you can pick and choose which modules go into this runtime image. java.se is an aggregator module that transitively includes a bunch of other modules. But you could also specify your own specific list of modules, leaving out some of the ones you don't need, making the final runtime image smaller.
I've spent literally months on trying to figure out how to create a single, clickable executable using Java 9+. I now conclude that it is impossible. Whether you use jlink directly yourself, or indirectly via Maven or Gradle, the result is that jlink produces a full directory structure that you are left to "distribute to your users" (somehow, I guess magically, since nothing in Java 9+ tells you anything about how you're supposed to do this). Then, once your user (somehow) has this directory on their machine, they are forced to invoke runtime-image-directory/bin/your-program-name. As though your user is a programmer who is happy to have to install a directory structure, and drill down to invoke a specific file name, which is buried in a directory with lots of other files, rather than being a user who USED to be able to simply double-click on a .jar file to run it. This makes me really wonder if whomever designed all this thought at all about the "user experience". The fact that there appears, as of Java 9+, to be NO WAY to simply deliver ONE file (such as a .jar) to users, together with the fact that just BUILDING this "runtime image" is fantastically complicated, means that developers are going to abandon Java in droves. It really seems to me that the brainiacs at Oracle simply didn't think this through. They have created a death knell to Java by making something onerous for developers to build and distribute, and onerous for users to invoke. I don't see how this situation can be allowed to remain without Java ultimately dying off. Somebody please correct me if I am missing something here, but I've spent months now trying to figure out how to create a runnable jar in Java 9+, USING MODULES, and it appears there is no way to do it.

How to make an Executable ".exe" file from a java Code

I have an application that works fine and that I can execute from a .jar file. But I want to know how to make it runnable from any computer even if there is no JRE or the JRE version is not the good one. I thought about a .exe file but don't know how to do it.
I made my code with Eclipse and it use jxl,jdom and jfx librairies.
I tried to use Inno Setup 5.5.6 but when in Eclipse I run my build.xml as Ant Build it return me an error that says :
"'Launching JFX Build - Myapp' has encountered a problem.
The achive : C:/Program%20Files/eclipse/plugins/org.eclipse.swt.win32.win32.x86_64_3.104.0.v20150528.jar which is referenced by classpath, does not exist."
JavaFX provides specific utilities for bundling your application as a native package, which is referred to as "Self contained application packaging". These utilities are provided as a command-line tool, or as ant tasks. Additionally, the common IDEs support this via wizards, either out of the box (NetBeans) or via a plugin (e(fx)clipse for Eclipse). The details of how to use any of these are far beyond the scope of a stack overflow question, but the basic documentation is available here. A tutorial for e(fx)clipse is here.
Briefly, for e(fx)clipse, you should double-click the build.fxbuild file that is created in your project. Under the "Overview" tab, find the "Packaging format" option, and select "All" (or the specific type of package you want to create).
Note that you can only create a package targeted at the platform on which you are building, so if you want to create packages for windows, Mac, and Linux, you will need access to all three types of machine.
I know I am late. I faced same problem a trick worked for me. Look at the given directory in the error message. It contains a space (C:/Program Files/...). Move your e(fx)clipse to another directory where the directory doesn't contains any space.
Not sure it will work your everyone or not but it worked for me.
Thanks
There are various tools that let you wrap your Java application in a Windows executable. Some tools are only simple installers, others allow you to bundle your application with a specific JRE version.
A widely used but commercial tool is install4j, but there is a bunch of other tools, such as WinRun4J.

Deploy Jar With Java?

I was wondering how to include Java itself with a jar file so that people don't have to have Java installed already. Is it possible and if so, how do you do it?
To execute the jar in the first place you'd need to have java installed. So it would be best to include a JRE installer in a separate file if you'r including one. Also, you'd have to have a different installer for each target platform so this would be somewhat impractical for general distribution because of the inflated file size.
This is like asking "Can we include the chicken that lays the egg, in the egg?". Answer, no.
As to solving the bigger problem though, there is at least one strategy that might work well for applets, JWS apps. and (possibly) single Jars of desktop apps. that are launched from a link (I've never tried that, though). This approach uses JS to check for the right JRE before providing a link to the Jar.
In order to get a computer to do something, you need to have code that the operating system knows how to handle. Most modern operating systems do not know how to handle Java code unless you install a Java Runtime Engine - to them JAR files are just ZIP files.
Hence you need some code which can be executed directly (without Java) and the simplest is just to use a Java launcher. Many exist - see Java packaging tools - alternatives for jsmooth, launch4j, onejar - but e.g. launch4j is maintained and supports the <path> tag to specify a relative path to an included JRE. Those are unfortunately rather large, but you could provide two versions. One with the JRE, and one without (which then prompts the user to install a JRE).

Merging Multiple Jars in to a Single Jar

my application needs multiple jars to work. Since it is a desktop application i can not hold the user responsible of installing. So in my build script i unzip the jars content in to my build directory delete manifest files, compile my software and jar it again. Everything works as it should my question is are there any long term side effects to this process?
In the past, there were JARs with weird content (like the DB2 driver which contains com.ibm and com.IBM; after decompressing in a Windows filesystem, those two packages would be merged).
The only issue you need to be aware of are signed jars and other files in META-INF which might have the same name in multiple source JARs.
A simple solution for all these issues is to use One-JAR. It allows to wrap several JARs into one without unpacking them, first. And read this answer: Easiest way to merge a release into one JAR file
A simpler solution (IMO) is using Maven's assembly plugin, which is also described in one of the answers to another question which was linked to in a previous Q&A. This is provided you are using Maven (which is a recommended tool by its own right) as a build tool.
If you want a no fuss way for the end user to kick off a program with multiple jar dependencies you may want to look at Launch4j or Jsmooth (I prefer Launch4j). Both are programs that create executables that wrap jar(s) and the JRE together so that to the end user it appears no different then any other executable.
Another great option is ProGuard, which can also shrink and/or obfuscate the code too.
If your primary target platform is Windows desktop, then you could also consider generating an Windows native exe from the jars of your application
If some of the jars are signed you lose the signature by unpacking/repacking it.
Well you're throwing away the MANIFEST of your third party jars, so that could cause you problems. For example you could be causing security issues by throwing away the "Sealed" attribute.
Why not just create a simple installer and a script to launch your application which sets the CLASSPATH correctly?
One-JAR will do the job, and has a new release (0.97) which supports frameworks like Spring and Guice, which users are now packing into One-JAR archives. http://one-jar.sourceforge.net
Ference Hechler also did some great work inside Eclipse with the Eclipse export wizard: we worked together on FatJar/One-JAR from which the Eclipse work grew, and I can recommend that as an approach, though I don't know how well it handles the frameworks.

How do you handle different Java IDEs and svn?

How do you ensure, that you can checkout the code into Eclipse or NetBeans and work there with it?
Edit: If you not checking in ide-related files, you have to reconfigure buildpath, includes and all this stuff, each time you checkout the project. I don't know, if ant (especially an ant buildfile which is created/exported from eclipse) will work with an other ide seamlessly.
We actually maintain a Netbeans and an Eclipse project for our code in SVN right now with no troubles at all. The Netbeans files don't step on the Eclipse files. We have our projects structured like this:
sample-project
+ bin
+ launches
+ lib
+ logs
+ nbproject
+ src
+ java
.classpath
.project
build.xml
The biggest points seem to be:
Prohibit any absolute paths in the
project files for either IDE.
Set the project files to output the
class files to the same directory.
svn:ignore the private
directory in the .nbproject
directory.
svn:ignore the directory used for
class file output from the IDEs and any other runtime generated directories like the logs directory above.
Have people using both consistently
so that differences get resolved
quickly.
Also maintain a build system
independent of the IDEs such as
cruisecontrol.
Use UTF-8 and correct any encoding issues
immediately.
We are developing on Fedora 9 32-bit and 64-bit, Vista, and WindowsXP and about half of the developers use one IDE or the other. A few use both and switch back and forth regularly.
The smart ass answer is "by doing so" - unless you aren't working with multiple IDEs you don't know if you are really prepared for working with multiple IDEs. Honest. :)
I always have seen multiple platforms as more cumbersome, as they may use different encoding standards (e.g. Windows may default to ISO-8859-1, Linux to UTF-8) - for me encoding has caused way more issues than IDEs.
Some more pointers:
You might want to go with Maven (http://maven.apache.org), let it generate IDE specific files and never commit them to source control.
In order to be sure that you are generating the correct artefacts, you should have a dedicated server build your deliverables (e.g. cruisecontrol), either with the help of ant, maven or any other tool. These deliverables are the ones that are tested outside of development machines. Great way to make people aware that there is another world outside their own machine.
Prohibit any machine specific path to be contained in any IDE specific file found in source control. Always reference external libraries by logical path names, preferable containing their version (if you don't use maven)
The best thing is probably to not commit any IDE related file (such as Eclipse's .project), that way everyone can checkout the project and do his thing as he wants.
That being said, I guess most IDEs have their own config file scheme, so maybe you can commit it all without having any conflict, but it feels messy imo.
For the most part I'd agree with seldaek, but I'm also inclined to say that you should at least give a file that says what the dependencies are, what Java version to use to compile, etc, and anything extra that a NetBeans/Eclipse developer might need to compile in their IDE.
We currently only use Eclipse and so we commit all the Eclipse .classpath .project files to svn which I think is the better solution because then everyone is able too reproduce errors and what-not easily instead of faffing about with IDE specifics.
I'm of the philosophy that the build should be done with a "lowest common denominator" approach. What goes into source control is what is required to do the build. While I develop exclusively in with Eclipse, my build is with ant at the command line.
With respect to source control, I only check in files that are essential to the build from the command line. No Eclipse files. When I setup a new development machine (seems like twice a year), it takes a little effort to get Eclipse to import the project from an ant build file but nothing scary. (In theory, this should work the same for other IDEs, no? Surly they must be able to import from ant?)
I've also documented how to setup a bare minimum build environment.
I use maven, and check in just the pom & source.
After checking out a project, I run mvn eclipse:eclipse
I tell svn to ignore the generated .project, etc.
Here's what i do:
Only maintain in source control your ant build script and associated classpath. Classpath could either be explicit in the ant script, a property file or managed by ivy.
write an ant target to generate the Eclipse .classpath file from the ant classpath
Netbeans will use your build script and classpath, just configure it to do so through a free form project.
This way you get IDE independent build scripts and happy developers :)
There's a blog on netbeans site on how to do 3. but i can't find it right now. I've put some notes on how to do the above on my site - link text (quick and ugly though, sorry)
Note that if you're using Ivy (a good idea) and eclipse you might be tempted to use the eclipse ivy plugin. I've used it and found it to be horribly buggy and unreliable. Better to use 2. above.

Categories