Bug 390494 - unit and performance tests fail during "transform" using new JRE
Summary: unit and performance tests fail during "transform" using new JRE
Status: VERIFIED FIXED
Alias: None
Product: Platform
Classification: Eclipse Project
Component: Releng (show other bugs)
Version: 4.2   Edit
Hardware: PC Linux
: P3 normal (vote)
Target Milestone: 4.3 M3   Edit
Assignee: David Williams CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks: 374441
  Show dependency tree
 
Reported: 2012-09-26 17:49 EDT by David Williams CLA
Modified: 2013-05-30 16:44 EDT (History)
3 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description David Williams CLA 2012-09-26 17:49:14 EDT
After updating our windows test machine JRE to JDK(7u7) in c:\java\jdk1.7.0_07 
see bug 390286

We've started to get this error in our "junits" (actually, its our performance tests, but will probably see in tonight's "nightlies" if indeed is from VM). 


genResults:
     [copy] Copying 1 file to c:\hb\workspace\ep4-perf-win32\workarea\I20120920-1300\eclipse-testing\results\xml
     [xslt] Transforming into c:\hb\workspace\ep4-perf-win32\workarea\I20120920-1300\eclipse-testing\results\html
     [xslt] Processing c:\hb\workspace\ep4-perf-win32\workarea\I20120920-1300\eclipse-testing\results\xml\org.eclipse.ant.tests.ui_win32.win32.x86_7.0.xml to c:\hb\workspace\ep4-perf-win32\workarea\I20120920-1300\eclipse-testing\results\html\org.eclipse.ant.tests.ui_win32.win32.x86_7.0.html
     [xslt] Loading stylesheet c:\hb\workspace\ep4-perf-win32\workarea\I20120920-1300\eclipse-testing\test-eclipse\eclipse\plugins\org.eclipse.test_3.3.100\JUNIT.XSL
     [xslt] : Error! The first argument to the non-static Java function 'replace' is not a valid object reference.
     [xslt] : Error! Cannot convert data-type 'void' to 'reference'.
     [xslt] : Fatal Error! Could not compile stylesheet
     [xslt] Failed to process null
An error has occurred. See the log file
C:\hb\workspace\ep4-perf-win32\workarea\I20120920-1300\eclipse-testing\workspace\.metadata\.log.
Comment 1 David Williams CLA 2012-09-26 17:51:43 EDT
Markus, you seemed to be an expert on this "JUNIT.XSL" file, 
have you ever seen an error similar to 

     [xslt] : Error! The first argument to the non-static Java function 'replace' is not a valid object reference.
     [xslt] : Error! Cannot convert data-type 'void' to 'reference'.
     [xslt] : Fatal Error! Could not compile stylesheet
     [xslt] Failed to process null

Thinks its just an incompatible version of Xalan or something in the VM?
Comment 2 David Williams CLA 2012-09-26 18:09:45 EDT
I have found some info on the web, such as 

http://stackoverflow.com/questions/10760798/securitymanager-and-xslt-extensions-in-java7-update4-broken

I may have to revert to using older VM after just asking for an update (bug 390286)
Comment 3 David Williams CLA 2012-09-27 02:50:44 EDT
From some other reading, sounds like the "right" solution is to put xalan jars in VM's lib\ext directory OR we might want to just add Orbit's Xalan's 2.7.1 bundle to our "base builder".
Comment 4 Markus Keller CLA 2012-09-27 05:56:39 EDT
This is bug 384757.

The right solution is for Oracle to finally fix http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7167657 , e.g. by taking out their bad changes from  http://java.net/projects/jaxp-sources/sources/svn/revision/3040 .

Unfortunately, I don't know how to make this happen, so I agree the "right" workaround for us is to use a working version of Xalan.

I think the best workaround is to add a dependency on Xalan from Orbit and the second best workaround is to use the lib/ext hack.
Comment 5 David Williams CLA 2012-09-27 09:42:46 EDT
(In reply to comment #4)
> This is bug 384757.
> 
> The right solution is for Oracle to finally fix
> http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7167657 , e.g. by taking
> out their bad changes from 
> http://java.net/projects/jaxp-sources/sources/svn/revision/3040 .
> 
> Unfortunately, I don't know how to make this happen, so I agree the "right"
> workaround for us is to use a working version of Xalan.
> 
> I think the best workaround is to add a dependency on Xalan from Orbit and
> the second best workaround is to use the lib/ext hack.

I'll first try adding xalan to our plugin "stack" and I'll do it as an entirely optional "build machine" operation, if ant property specified, so effects no one else (and avoids questions of CQs, etc.) ... will know more by noon or so.
Comment 6 David Williams CLA 2012-09-27 14:52:44 EDT
(In reply to comment #5)
> (In reply to comment #4)
> > This is bug 384757.
> > 
> > The right solution is for Oracle to finally fix
> > http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7167657 , e.g. by taking
> > out their bad changes from 
> > http://java.net/projects/jaxp-sources/sources/svn/revision/3040 .
> > 
> > Unfortunately, I don't know how to make this happen, so I agree the "right"
> > workaround for us is to use a working version of Xalan.
> > 
> > I think the best workaround is to add a dependency on Xalan from Orbit and
> > the second best workaround is to use the lib/ext hack.
> 
> I'll first try adding xalan to our plugin "stack" and I'll do it as an
> entirely optional "build machine" operation, if ant property specified, so
> effects no one else (and avoids questions of CQs, etc.) ... will know more
> by noon or so.

I've tried working around the issue indirectly, by adding xalan bundles (and prereqs) to our "basebuilder" at test time only ... and tried about a dozen variations ... and nothing worked. I suspect there is a way to make it work by changing our code, or changing our basebuilder, but copying the jars in lib/ext would be much easier. Otherwise, we will simply stay on the older VMs.
Comment 7 Markus Keller CLA 2012-09-27 16:11:50 EDT
http://rakeshdiscovery.blogspot.de/2008/12/xalan-java-xsltc.html says:

OR you can also force the SUN JDK to use Xalan by setting the System property :

    System.setProperty("javax.xml.transform.TransformerFactory",
        "org.apache.xalan.processor.TransformerFactoryImpl");

=> I could make it work locally like this:

1) add this to the Ant invocation's VM args:
-Djavax.xml.transform.TransformerFactory=org.apache.xalan.processor.TransformerFactoryImpl

2) add org.apache.xalan and org.apache.xml.serializer to the Ant classpath
Comment 8 David Williams CLA 2012-09-28 00:19:22 EDT
(In reply to comment #7)
> http://rakeshdiscovery.blogspot.de/2008/12/xalan-java-xsltc.html says:
> 
> OR you can also force the SUN JDK to use Xalan by setting the System
> property :
> 
>     System.setProperty("javax.xml.transform.TransformerFactory",
>         "org.apache.xalan.processor.TransformerFactoryImpl");
> 
> => I could make it work locally like this:
> 
> 1) add this to the Ant invocation's VM args:
> -Djavax.xml.transform.TransformerFactory=org.apache.xalan.processor.
> TransformerFactoryImpl
> 
> 2) add org.apache.xalan and org.apache.xml.serializer to the Ant classpath

Yes, I did try setting the system property. But didn't work. 

So, how did you "add to ant's classpath"? 

I would have thought putting the bundles in basebuilder would effectively put them on "classpath" (findable) but ... I have a feeling our base builder does not "update" its knowledge of what is "installed", dynamically. Perhaps by some old design ... perhaps just by carrying forward old settings? 

Our current config.ini in base builder, has 

#osgi.bundles=org.eclipse.equinox.common@2:start, org.eclipse.update.configurator@3:start, org.eclipse.core.runtime@start
#osgi.bundles=org.eclipse.equinox.common@2:start,org.eclipse.equinox.ds@2:start, org.eclipse.update.configurator@3:start,org.eclipse.core.runtime@start
osgi.bundles=org.eclipse.equinox.common@1:start,org.eclipse.equinox.ds@3:start, org.eclipse.update.configurator@2:start,org.eclipse.core.runtime@start

I include the commented out lines so you can see what presumably was history. 

I guess it'd be hard to tell without looking at whole thing, but would that config.ini "update" based on additions to plugins or dropins? (I tried both)

I'd like to change to something "modern" ... but ... we don't have enough stuff in our basebuilder to make it easy: 

osgi.bundles=reference\:file\:org.eclipse.equinox.simpleconfigurator_1.0.300.v20110815-1744.jar@1\:start
org.eclipse.equinox.simpleconfigurator.configUrl=file\:org.eclipse.equinox.simpleconfigurator/bundles.info


At any rate, if you know some way to "add to ant's classpath" without changing our code, let me know. 
(This would be the class path of the ant bundle in the basebuilder, by the way ... we are running "antRunner" at that point.)

Thanks.
Comment 9 Markus Keller CLA 2012-09-28 06:04:21 EDT
(In reply to comment #8)
> So, how did you "add to ant's classpath"?

Hmm, I only tried running an Ant file out of Eclipse:
- Run As > Ant Build...
- on the JRE tab: add -Djavax.xml.transform.TransformerFactory=... 
- on the Classpath tab: add the 2 bundles as User Entries (paste full system path into Add Variable... dialog)

I don't think this will work via OSGi. The problem is that the ServiceLoader that reads the "javax.xml.transform.TransformerFactory" setting and performs the lookup via the META-INF/services/javax.xml.transform.TransformerFactory file is not OSGi-aware, so it won't see the bundles on the bundle classpath.

The way to make it work in a runtime workbench is to add this to the VM args when launching the Eclipse application (this worked on my Windows box):

-Djavax.xml.transform.TransformerFactory=org.apache.xalan.processor.TransformerFactoryImpl
-Xbootclasspath/a:${project_loc:/org.apache.xalan};${project_loc:/org.apache.xml.serializer}

I had the org.apache.xalan and org.apache.xml.serializer projects checked out from Orbit. You probably have to hardcode the paths to the JARs. And remember to use ":" as path separator on Linux (not ";").
Comment 10 David Williams CLA 2012-10-01 02:19:35 EDT
(In reply to comment #9)
> (In reply to comment #8)
> > So, how did you "add to ant's classpath"?
> 

> The way to make it work in a runtime workbench is to add this to the VM args
> when launching the Eclipse application (this worked on my Windows box):
> 
> -Djavax.xml.transform.TransformerFactory=org.apache.xalan.processor.
> TransformerFactoryImpl
> -Xbootclasspath/a:${project_loc:/org.apache.xalan};${project_loc:/org.apache.
> xml.serializer}
> 

I tried and tried, but I could not get this to work in the context of our unit tests. I am not sure if its the basebuilder? the antRunner app? or those combined with JUnit/xalan code, but by the time it needed that Factory class in that context, it was no longer looking at the "bootstrap classpath". I'd say there's a 10 to 20% chance I was just doing something stupid ... but, I tried many variations and many diagnostics and convinced myself that whatever "custom lookup" mechanism it has, it wasn't finding it in that context by using that method. Obviously it works in some contexts, since worked for you from workbench ... but no joy for me. 

But, the good news is with all those hours and hours of work and research, I learned that since Java 1.6, you can specify ext directories as a system property on the command line -Djava.ext.dirs=... [who knew!] ... so, back to the first proposal of using "ext dir" solution, but this is a better one that doesn't have to change the ext dir that everyone uses, we can create our own, and just we use it. 

To implement it did turn out to be a LOT more complicated than I thought ... to not change current behavior, if optional argument not specified, plus, so many weird patterns of escaping, quoting, passing arguments (between windows and linux), and so many "layers" of our own scripts to "get through". (And, I still need to document it better). 

At any rate, I solved for windows and linux (testing on my home machines) but I broke some builds along the way, so want to make sure they still work on build.eclipse.org hudson, roughly as they were, before trying again to move up to Java u7 again. Should be some time Monday. 

[Apologies for the delay in our "quick tests of the performance tests" effort ... if I'd known it'd been so complicated, in hindsight I would have done things differently.] 

I was anxious to move up to u7, since looking though the release notes, it looked like there MIGHT have been some low level nio bugs fixed that MIGHT have been effecting those resource tests that were taking abnormally long.
Comment 11 Markus Keller CLA 2012-10-01 08:26:28 EDT
The "-Djavax.xml.transform.TransformerFactory=..." needs to be in the vmargs of the VM that runs the <xslt> task in test.xml. That's the one launched by $vmcmd at the end of runtests.sh.

Executing this command in the eclipse-testing folder worked for me:

./runtests -os linux -ws gtk -arch x86 -properties ~buildmeister/mk/vm.properties -vm "/home/buildmeister/bin/jdk7/bin/java -Djavax.xml.transform.TransformerFactory=org.apache.xalan.processor.TransformerFactoryImpl -Xbootclasspath/a:/home/buildmeister/mk/org.apache.xalan_2.7.1.v201005080400.jar:/home/buildmeister/mk/org.apache.xml.serializer_2.7.1.v201005080400.jar" debug

Note that I had to spell out the full paths (i.e. couldn't use ~ etc.) inside the double-quoted argument to -vm.
Comment 12 David Williams CLA 2012-10-03 02:43:25 EDT
I'm going to count this as fixed, even though I've not documented it in the "how to run tests" readme file. The rationale is that it is a "work around" for a VM bug, and may not be supported in the future. Not to mention, it's complicated to explain, since as is, it is more for the "outer VM", not the -vm running the tests. 

But, there is an outline of what documentation would look like, if people need this work around on their local systems or other Hudson builds/tests (Or, they can use Markus's suggestions). 

I. a command argument would be added to the "runtest" description

-extdirprop <path(s) to ext dir(s)>

II. a description along the lines of 

Originally added as a work around for bug 390494, the extdirprop can be used to specify directories to be used on the -Djava.ext.dirs property (which was introduced in 1.6 JREs). 

One complication is the user needs to decide if they need to keep the default ext dirs, or if they can just specify their special one. Plus, the path delimiter differs on each platform, plus I found it required to escape the path delimiter, at least on windows [but, admittedly, This was before I finished the scripts, so might not be required with the final way the scripts are used (and variables quoted)]. 

Some example default ext dirs are given below. A user might have to find their VM's default before using this property, so they can specify desired defaults along with their custom one(s). Some VMs have a handy -XshowSettings parameter that would show all properties ... else a small ant script or tiny Java app made to list all properties. 

Examples: 

Mac:

java.ext.dirs=/Library/Java/Extensions\:/System/Library/Java/Extensions\:/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home/lib/ext


Windows

java.ext.dirs = c:\java\jdk7u2\jre\lib\ext^;C:\Windows\Sun\Java\lib\ext


Linux

java.ext.dirs=/opt/public/common/jdk1.6.0_27.x86_64/jre/lib/ext\:/usr/java/packages/lib/ext

Note, the usual pattern is there is one that "comes with" the VM distribution, and another directory that is specific to the machine it is on, so it can be used by multiple VMs or multiple users on the same VM. Typically, this latter one is empty ... at least in my limited experience. 


In practice, for local testing, you'd have your custom ext dir where ever you'd like. For our particular work around for the VM bug that required xalan in extdir, for running tests on build.eclipse.org, I added the xalan jars to a zip file on build machine at  
/shared/eclipse/buildtests/xalanjars/xalan.zip
This allows adding a build step on Hudson, to 
wget -O xalan.zip http://build.eclipse.org/eclipse/buildtests/xalanjars/xalan.zip
unzip extdirxalan.zip -d extdirxalan

which allows, in subsequent build steps, to use as an ext dir, the value of 
%WORKSPACE%\extdirxalan, or on nix systems $WORKSPACE/extdirxalan

Note too, on our Hudson build, we have another parameter "extdir" that we pass to our script meant to be ran from Hudson, which by the time it gets to the normal "runtests.sh" script is translated to -extdirprop=${extdir} (if extdir is specified). 

So, as one example, on Windows on Hudson configuration, we use

SET extdir=c:\java\jdk1.7.0_07\jre\lib\ext^;%WORKSPACE%\extdirxalan

Which later becomes an argument to runtests.sh such as  
-extdirprop=c:\java\jdk1.7.0_07\jre\lib\ext^;%WORKSPACE%\extdirxalan

Which later, for the VM running xalan, become a -D parameter such as 
-Djava.ext.dirs=c:\java\jdk1.7.0_07\jre\lib\ext^;%WORKSPACE%\extdirxalan

If not obvious, if extdir (or, extdirprop) is not specified, we don't specify -Djava.ext.dirs to the VM so it would use whatever defaults it normally would. 

===========

So, hopefully that makes it clear why I don't want to commit this to our public documentation just yet :) 
There could be some ways to simplify things. But, its important not to "hard code" in the assumption we are running on Hudson, with VMs that have this bug ... since many users use other VMs (or other versions of these VMs) and would never need to worry about this parameter. 

Another clarification ... using the xalan files in the ext dir does not require the -Djavax.xml.transform.TransformerFactory parameter to be specified.
Comment 13 David Williams CLA 2013-05-30 16:44:59 EDT
mass change to 'verified', as these bugs are either routine or obviously fixed build breaks.