Virtualizing Java with Symantec Workspace Virtualization

Machine Translations

A fairly common virtualization scenario in Enterprise environments is to virtualize Java applications. Typically this need arises because there are older Java applications that require very specific versions of Java, and often these versions of Java do not work very well with newer versions. There are ways that applications can be designed to resolve these issues, but many times the software is from a third-party, and the problems cannot be solved using these traditional methods.

In this example scenario, we have two Java applets, creatively named Application_1 and Application_2. These applets require Java v1.4.2_08 and v1.4.2_13 respectively. To complicate the situation, we cannot guarantee which version of Java may be installed traditionally. To simulate this, we will install Java 1.5.0_07 traditionally.

Installing Java

The first step in setting up this scenario is installing Java. It is important to install the Java Runtime Environment virtually prior to installing it traditionally in order to avoid conflicts. (The installer may notice that JRE 1.5 is installed and behave differently.) As with most "packaging" activities, this should ideally be done on a completely clean machine.

The command-line instructions that I use to do this are listed below. Each installer launches in interactive mode, and I choose the typical install option. In a real-world packaging scenario I would likely install these in a silent mode to guarantee the repeatability of the operation.

Installing Java Applications

For this part of the example scenario, I don't actually have two Java applications to work with, so I created a couple of applets from scratch. In a real-world scenario, the installation of these applications would be in the same manner as used in the previous section. For my purposes here, I will set up my sample applications manually.

As mentioned above, I have two sample Java applets to use in these layers. The source files for Application_1 are found in Figures 1 and 2. Application_2 is identical, but renamed as appropriate. Each of the .java files are compiled into .class files as referenced by the .html file for each applet.

For our purposes, we create two layers, named "Application_1" and "Application_2", and copy the .html and .class files for each application into their respective layers in the [COMMONDESKTOP] directory.

Configuring Virtual Layers

Each Java application will depend on its preferred version of Java, and therefore should find that version of Java before it finds others. There are two classes of problems that arise in this kind of situation: 1) two applications are involve that use the same files / registry keys and simply need to be ordered correctly so that they find their preferred settings before other settings, and 2) two applications use different files / registry keys and the application is aware of both sets. Depending on the versions of Java involved, either or both of these situations could be occurring. In our example case, we have both: the two versions of JRE 1.4.2 use identical registry keys, while the JRE 1.5.0 uses a slightly different set of keys.

To solve the first kind of application conflict we will use a feature of SWV called dependent layers. Each Java application will depend on its preferred Java layer. This has two primary effects. First, starting the Application_1 layer will also start the JRE 1.4.2_08 layer because of the dependency. Second, when layers and the base are overlaid on top of each other, Application_1 will find settings existing in the JRE 1.4.2_08 layer before it finds settings in other layers (that are named the same).

svscmd.exe Application_1 depends -add "JRE 1.4.2_08"

svscmd.exe Application_2 depends -add "JRE 1.4.2_13"

The second kind of application conflict is a little more complicated to solve. We need to prevent each of our Java applications from seeing the Java in the base. To implement this we need to add an "isolation rule" to each of the application layers. This must be done by editing the registry. Each layer stores its settings in a registry key similar to the ones below. The exact number on the end of the key name will depend on your exact system.

If you run the command "svscmd.exe enum -v" you will notice that each layer has an entry called "Redirect Locations" which specifies the location of the redirect areas for the read-only and read-write sublayers. We are going to add the rules to the read-only sublayer. Create a Multi-String registry value named "IsolationRules" in each of the layers. Each isolation rule occupies a single line in the multi-string, and has a general form of "Processes named x running from layer x are blocked from accessing objects named (x,x,x) found in layer x." The individual fields within the rule are separated with a tab character. (You won't be able to create them directly in regedit, but can create them in notepad and then paste them into regedit.) The rules that we create for our two layers look like the following.

So examining the first one and explaining it in English, the rule is that "processes named iexplore.exe (running from any path) running from layer ID a1d043ef-cc6a-4d4a-bbd6-689fcf81727c cannot see registry keys (that's what the 0x0002 flag indicates) named HKU\S-1-5*\Software\Classes\CLSID\{CAFEEFAC* and values named * found in the BASE." This is all pretty complicated, but fortunately it's exactly what we need to prevent our application from seeing the Java 1.5 registry keys in the base.

Now there's just one last thing remaining to figure out. We have to get the Internet Explorer process that is going to display our applet to run from the appropriate layer. For the purposes of this example, a simple batch file that executes IE from the layers is sufficient.

Obviously for a real-world scenario, something a bit more complicated is required. There is a more advanced feature in Software Virtualization that we can use to accomplish this: Auto-Run-From-Layer. This feature allows us to specify a certain set of patterns that define a kind of process that should automatically be made to run from a specified layer. In this case, I want to create a rule that says "when a process named iexplore.exe is launched by any parent process with the string Application_1 on the command-line then add that process to the layer."

In some real-world scenarios we have seen Java applications that launch an applet in Internet Explorer using WMI. In these cases, we could replace the second field "*" in these values with a process name pattern, such as "*wmiprvse.exe".

Note that the user interface in SVSAdmin currently only allows the first field to be set, giving you a rule where the extra fields default to "*", such as "[_B_]WINDIR[_E_]\notepad.exe<tab>*<tab>*". A more advanced rule that specifies all the fields can be specified on the command-line via SVSCmd.

Additional Notes

In creating and resolving this scenario, I ran into a few interesting problems that are worth mentioning here. First, a note about the keys to making the technique work. The two major points that must be right in order for this technique to work are (1) that you are blocking the correct keys from being accessed by the application, and (2) that the process is running from the correct context (i.e., the layer). To ensure the former, I found myself several times creating an isolation rule identical to the one I was trying to use for iexplore.exe, but for reg.exe. Then I would activate the layer, run a "reg query" command to see if the key was being blocked correctly, and adjust my isolation rule accordingly. To ensure the latter, one method is to try to deactivate the layer while the application you are concerned with is still running. If it's running from the layer, you will be prompted to end the process when you try to deactivate the layer. If the layer just deactivates without prompting, then the process is not running from the layer correctly.

Another interesting problem that I encountered during this process was that if your settings are configured incorrectly, when the Java plug-in starts in Internet Explorer it will re-write all its registry settings. This means that if the iexplore process is running from the layer, but the registry isolation is not correct, Java will write all its 1.5 settings into your Java 1.4 application layer. You can resolve this condition by resetting the layer. (I had to do this a number of times while developing my layers and getting just the right settings.)

Another good question is how to determine which registry keys to block for a specific scenario. This can be a little painful, but what I do is use a tool like Process Monitor from Microsoft (formerly from Sysinternals) to see what keys the application is accessing. I search within a log for something that indicates Java version; e.g., in this case I search for "1.5" and see where iexplore is reading some 1.5 settings from. Then I can block those keys. A second way to narrow this down is to create a broad block, say for "\REGISTRY\USER\*" and see what happens. Then modify the rule to block the next layer down, and so on, narrowing down what makes the application behave the way you want it to.

One final problem that I encountered in one test was that the Java applets I had built were compiled with the JDK 1.5. This created applications that were targeted for 1.5, and would not run with the 1.4 I had configured with my isolation rules. There are some pages on the web about figuring out what version a .class file is configured to use that can help you out if you suspect this may be the case.

Jeremy absolutely rocked this. This was the one hole in the Workspace Virtualization product, and it is now filled. For the 98% of applications that don't have specific dependencies let them all work together seemlessly. For the 2% that don't this is the article.

This shows the true flexibility and power of SWV.
No other vendor can virtualise multiple javas and use the IE from the base!
If you add the new layer setting "Deactivate when last process exits" you have layers that automatically activate and deactivate on demand.
Powerfull stuff!

The tools to use it do not. How can you expect any "normal" packager to get into this much complexity? If this is not able to be created "out of the box" with the toolset(s) provided (Admin Tool / Wise Package Studio) then nobody will even attempt it...

Worst of all, there are all of the marketing "himbeereboobies" propagating SVS / SWV as a click and package technologiy.

Hi Phil. You have a great point and it definitely would not be very convenient having to take a simple app and go through this level of configuration. However, consider this please. What Jeremy is describing here is something that can't be done conventionally. Sure, there are situations at which point extra not "out of the box" effort is needed to accomplish something, but if you are not doing anything of this nature and just doing straight forward packaging, there aren't to many apps out there that can't be packaged in a "click and package" fashion. Of course there is the other side of the coin...One can argue that this type of complexity handling should be built into the solution. That would be awesome, but is it really feasible considering the number of apps and configuration scenarios that would need to be considered for this? SWV does offer what you describe, but it also offers some really powerful tools to handle special situations. This is where Jeremy's article really shines, because he's showing us how we can take advantage of those tools to customize our environment so that we do not have to compromise on one solution over another just because they don't play nice together in a conventional environment.

I'm sorry, but will have to disagree there. One of the most common types of application that most companies *require* to be virtualised are Java based. It's perhaps one of the major reasons for virtualising applications, because the experience in the enterprise environment with Java based applications is one of conflicts, problems, and incompatibilites.

As for "this is an exception", how about (at least in SVS 2.X) configuring / reconfiguring permissions? Out of the box not possible (although technically it would be easy to do thius via the UI). CA, set permission on the FSLRDR%MagicNumber%...

There are other issues as well, that require a "non-standard" approach, where the standard tools just arn't enough. Again, I'm all for SVS / SWV whatever, however, the tools supplied do not do justice to the technology they are supposed to support. I really hope this chnages in the next Wise Package Studio SP4.

You actually make a good arguement with regards to most common apps, and we definately value any and all input from our community. Lets do this...In your opinion, thinking about 5 to 10 most common apps, can you give me a description of what you think this enhancement would look like? Maybe list out the apps and the special customization each one may require when virtualizing, that today would require additional not "out of the box" planning and configuration. Then, from an end-user perspective if we were to build something like this into the product, how would we need to design it so that it will provide the benefit you are looking for, but at the same time be able to handle the conditions specified for all the most common apps? Feel free to add anything else you feel would be important. If you can provide this I will be more then happy to submit an official enhancement request internally and get visibility for your concerns. If you like we can even exchange emails over private messaging on Connect so that we can brainstorm some ideas. Please let me know what you think.

You bring up some very good points with your comments. I completely agree that the existing tools do not make this task easy enough. We are working on features for upcoming releases that should help ease this. When I implemented this "feature" in SWV I really hesitated even exposing it to the public because it requires very specialized skills to be able to use it. I decided to "go public" with the feature because the only other option was to provide NO solution until we can make it easy to use. So we have gone from saying you just cannot solve this problem to saying it can be solved but it's not easy. A step in the right direction, but certainly not what our customers ultimate need.

Please realize that we are concerned about the points you raise, and are actively working on addressing them. We want the packaging experience for things like Java applets to be just as easy as it is for something like Adobe Reader. One thing that would greatly help us ensure that we solve the problem right would be to have real applications that we can develop and test with. The fact that most customers are using VERY proprietary Java programs makes it difficult for us to know when we've solved the problem, because we cannot validate. If you have Java applets/applications that are freeware, open source, or otherwise available to us for testing, please let us know about them.

Hi all
This is my first post.
I am searching to try 2nd solution with 1 application layer, 1 java layer hidden to s.o. and a java 1.4b12 (the last) installed on base.
This is my test with Isolation rule:
-My script test is: run a internet explorer session with <svscmd.exe "layer name" exec -p test.cmd -nowait>
where test.cmd is a script file that launch this command:
@"C:\programmi\internet explorer\iexplore.exe" "http://www.java.com/it/download/installed.jsp?detect=jre&try=1"

- When I run the script test from java hidden layer I obtain the version of the hidden layer. If I launch same script test.cmd from BASE I obtain version installed on BASE. When I launch script test from application layer version is BASE.
- Reset the layer, create a depends between application layer (master) and hidden java layer (slave), activate application layer (java come up withiut problem) and retest with script: no change.
- Create Isolation rules in directory RO of Application Layer with layer id = application layer, reset layers and retest: NO CHANGE.
- Modify exclusion string removing CAFEEFAC* and put only \REGISTRY\* , NO CHANGE.

One of the techniques that I find most useful for troubleshooting these issues is to use reg.exe as my test utility instead of iexplore.exe. It's much smaller, and can be used to perform very targeted operations. I use svscmd to "exec" cmd.exe from the layer, then I can run "reg query HKLM\SOFTWARE\Classes", etc. Combining that with changing the exclusion string (as you already have been doing) usually helps me pinpoint what I am trying to isolate and verify that the rule is working correctly.

I'm reading through this and trying to sort a situation that i think this will work for. We need a virtual IE layer to only see a specific version of Java install virtually. I'm looking to put in an isolation rule but have some questions.

1. Does the isolation rule sit on the VIE layer or VJava layer?

2. Does the reg entry go in the virtual layer or on the local machine?

3. the HKLM\System\Altiris\FSL location doesnt currently exist, should it be created?

4. How can you specify the excact sublayer folder ie 1,2,3,4 when it could well be diferent on other machines requiring this configuration?

Apologies if I've missed something glaringly obviously, I shall take myself to one side if so.

2. Does the reg entry go in the virtual layer or on the local machine?

3. the HKLM\System\Altiris\FSL location doesnt currently exist, should it be created?

4. How can you specify the excact sublayer folder ie 1,2,3,4 when it could well be diferent on other machines requiring this configuration?

The isolation rules can exist in either layer so long as the target of the isolation rules are correct.

The rules are created on the base registry of the machine. Open regedit and navigate to the read-only sublayer. Do not create the rules using the SWV admin tool layer editor.

No, that location is for legacy installations, currently the product installs to HKLM\SYSTEM\CurrentControlSet\services\FSLX\Parameters\FSL

If you have two layers, e.g., Java 1.7 and Internet Explorer 8, and the read-only sublayer for Java is (RO = 1) and the read-only sublayer for Internet Explorer 8 is (RO = 3), you would create the rules in HKLM\SYSTEM\CurrentControlSet\services\FSLX\Parameters\FSL\1\IsolationRules or HKLM\SYSTEM\CurrentControlSet\services\FSLX\Parameters\FSL\3\IsolationRules. When you export these layers, the rules in the RO sublayer are exported along with it. When you import this layer to a new machine, the rules are present in the RO sublayer.

One more thing, if you have trouble with a specific use-case for isolating Java, please open a seperate thread on the board so we can gather and discuss the details pertinent to your situation. I've had some success in isolating Java in different scenarios and would like to share my findings with you.