I’ve got a project at work that needs an MSI. I really didn’t want to use InstallShield, so I looked into WiX. WiX probably deserves its own thread, but I’ll just say that I’m a big fan.
The requirements for this installation, at first, seemed pretty straight forward. The installation does not have any UI or dialogs; meaning the user cannot choose any installation options or the destination path. For our purposes, that’s fine.
But here’s where it gets a bit difficult. We have to lay down Tomcat with a web service. That means that the project is dependent on the JRE. After some investigation, it appears that Sun doesn’t offer a jre bootstrapper. They only offer the jre installer itself, which is an msi wrapped in an executable. Anybody familiar with MSI knows that an MSI package cannot install another MSI package. This fact means that to install the JRE, we would have to either use a tool that included a jre bootstrapper or develop the bootstrapper ourselves.
We decided on a third option: include the contents of the jre and deploy it as a private jre. That means that the entire jre would be deployed to a subdirectory of the destination folder, and Tomcat would be configured to use this private jre. Fortunately, this use of the jre appears to not violate any redistribution agreements. This approach also means that our jre will not impact the target system, meaning no conflicts with existing jres. It also simplifies the installation scenario in that we don’t have to check for an existing jre - hence, no need for a bootstrapper, and we can continue to use WiX.
Now on to Tomcat. Tomcat can be run from the command line, or installed as a windows service. In our case, it must be installed as a windows service. To install Tomcat as a windows service, one must execute the service.bat file(located in tomcat’s bin folder) with the “install” argument.
After we’ve deployed tomcat and installed it as a service, we must deploy our web service package(packed as a WAR file). Tomcat, if it’s running(or when it’s run again) will pick up the war file and unpackage and deploy it automatically.
So far, this isn’t very complicated. At least I didn’t think so until I had to actually implement these requirements. The “install as a windows service” requirement presents some headaches. I mentioned that one must execute the service.bat file to install Tomcat as a service. We have to do this from the installer. After the batch file has been executed, we must then run NET START to start the service. That means that our installer has two custom actions: one to run the batch file, and another to start the service. Upon removal, the installer stops the service and uninstalls the service.
All of this behavior is implemented, and it runs… intermittently. On some machines, we get an MSI error stating that the product could not be installed. I’ve concluded that for some reason the batch file is not being executed. So for more information, I ran the MSI with verbose logging. Lo and behold, the batch file was executed.
It’s somewhat consistent. On the test machines where this is an issue, it’s consistent. But it doesn’t behave like this on all environments. On the machines where the batch file isn’t being executed, if we run the msi with verbose logging the batch file is always executed, and everything is installed correctly.
This is very frustrating. We can’t expect the customer to execute the msi package with verbose logging. Unfortunately, I’m not dedicated to this project, so I only get to work on it for a few hours every couple of weeks. At this point, I have no idea as to the root cause, and if it can be corrected.