One of the core features of SVS is the ability to eliminate conflicts between different software in different Virtual Software Packages (VSPs). One of the more common cases where customers want to leverage this ability is with Java. It's common for an organization to want/need to deploy apps side-by-side that have dependencies on different versions of JVM, NetBeans, etc. With SVS, you can do it. Here's how.
Editors' note: The content in this article is closely related to the content in Launching Two Versions of an App When Both Are Installed to the Same Location. Reading the perspective of two different authors should be helpful in understanding the "perspective" issue discussed below.
SVS will capture and virtualize Java according to SVS's rules. If you do not understand these rules you may think that Java is not being virtualized properly. In this article, we will discuss SVS's rules and behavior. Hopefully you will get the information you need to virtualize Java properly.
Gaining the Proper Perspective
The most important concept when trying to run multiple versions of Java at the same time is perspective. SVS uses perspective in order to build a view of the file system and registry. If there is a conflict in the file system or registry, the perspective of the process will determine which version of the file or registry value the application will see.
Applications can run from two different perspectives.
- The first perspective is from the perspective of base. All applications not installed into a layer will run from the perspective of the base by default.
- The second perspective is from a specific layer all applications in layers will run from this perspective by default.
Let us assume that we have two layers, Layer1 and Layer2, with a conflict. If an application running from the perspective of Layer1 requests the resource with the conflict it will see the version in Layer1. If an application running from the perspective of Layer2 requests the resource with the conflict it will see the version in Layer2. If an application running from the perspective of the base requests the resource with the conflict the outcome is not deterministic unless you modify the priority of one of the layers.
What Happens when you put Java in a layer?
SVS will capture Java into a layer. Java applications will work. If you only have one version of Java on your computer at a time you will most likely get the results you expect. If you have multiple versions of Java on your computer at the same time you will need to be diligent in making sure your applications get the correct version of Java. I will attempt to help you ensure that this will happen. The tool we will use to accomplish our goals is SVSCMD.exe. SVSCMD is a command line tool that is used to manage SVS and is installed with SVS.
The commands we will be using are:
|EXEC:||Executes an application from the perspective of a specific layer|
|IGNORE:||Tells SVS not to virtualize the view of a specific application.|
|PRIORITY:||This is used to manage conflicts|
There are two main ways to run Java applications. The first one is to run them from within a browser. The second is to start Java.exe and run the applications in a specific instance of a JVM. We will start by getting applications running inside a web browser to work properly.
Inside a Web Browser
When you run a Java application inside a web browser the JVM will run from inside the same process as the web browser so when the JVM is running it will run with the same perspective as the web browser. The default behavior is for explorer to run from the perspective of the base. The information explorer uses to look up the Java plug-in is stored In HKEY_CLASSES_ROOT(HKCR). The HKCR key is virtualized different than the rest of the system. In the case of HKCR the information in a layer will always take priority over the information in the base. To test which version of Java your JVM is seeing you may visit the following test page.
This page has a Java application that will display some information about your environment and which version of Java you are running.
Java in the Base
When you visit the test web page you will see the version of Java you installed. No surprises here.
Java in a Layer
When you visit the test page you will see the version of Java you have installed to the layer. This should be what you expect since there are no conflicts.
Java 5 in a Layer, Java 6 in the Base
When the Java 5 layer is active there is a conflict between the two versions of Java. Which one will you get when you open the test page? You will get that you are running version Java version 5. This is because when explorer looks up the Java plug-in it will see the version in the layer first because of the way that HKCR is virtualized. If you have an application that needs to use Java 6 you may use the following command:
SVSCmd.exe IGNORE –P "c:\Program Files\Internet Explorer\iexplore.exe
This will tell SVS not to virtualize this instance of Internet Explorer. When this instance of explorer looks up the Java plug-in it will not see Java 5 which resides in the layer.
Java 5 in a Layer, Java 6 in a Layer
When both of these applications are active when IE launches which one will you see? The result is not deterministic. You may fix this problem trying two different approaches. The first is to change the priority of one of the layers. We will use the following command to change the HKCR priority of Java 6 to come before Java 5
SVSCMD.EXE "Java 6" PRIORITY -T HKCR -L 65.4
Now every time IE tries to launch Java it will always get Java 6. Now that Java 6 is the default you may have a need to make a specific Java application run with Java 5. The following command will help you with this.
SVSCmd.exe "Java 5" EXEC -P "c:\Program Files\Internet Explorer\iexplore.exe http://www.java.com/en/download/help/testvm.xml"
The instance of Java started by this command will now use Java 5 since the lookup order for this instance of IE was started in side the Java 5 layer.
Running Java as a Separate Executable
Sometimes a Java application does not run in a web browser but as a separate executable like Eclipse. I have attached a layer that contains JavaVersion.jar and JavaVersion.exe. The source code for these applications is also attached. JavaVersion.jar is a Java application that prints what version of Java is being used. JavaVersion.exe is used to launch Java from the perspective of a specific layer. For the following examples this approach is the same as if JavaVerison.exe was installed on the base.
Java in the Base
Run JavaVersion.exe you will get the version of Java you have installed on your computer.
Java in a Layer
Run JavaVerion.exe you will get the versions of Java you have installed in a layer.
Java 5 in a Layer, Java 6 in the base
Run JavaVerions.exe you will get Java 6. This is because the lookup of Java by cmd.exe uses the normal priority, an application running from the perspective of the base will see the information in the base first. If you need the Java application to run as if from the Java 5 layer you will need to use the following command.
SVSCMD.EXE "Java 5" EXEC -P "c:\JavaVerion.exe "
As before this instance of JavaVersion.exe will run from the perspective of the Java 5 layer.
Java 5 in a Layer, Java 6 in a Layer
This is a similar situation to the web browser example. There is a conflict and both Java 5 and Java 6 have the same priority. It is not deterministic which version should win we can set the priority of the Java 6 layer to come before the Java 5 layer with the following command.
SVSCMD.EXE "Java 6" PRIORITY –T NORMAL –L 85.4
Now when both layers are active you will get the Java 6 layer instead of the Java 5 layer. What if you have an application that needs the Java 5 layer? You may use the following command to get an application to run from the perspective of the Java 5 layer.
SVSCMD.EXE "Java 5" EXEC –P C:\JavaVersion.exe
I think that we have covered all our bases we can now launch multiple versions of a web browser all using different versions of Java. We can also use multiple versions of Java at the same time in different applications.