Controlling JRebel package scope - classloader

I am trying to speed up execution of code being debugged with JRebel. In particular, I notice that framework code is slow. I am wondering whether I can tell JRebel to ignore certain packages, in much the same way that we can setup JProfiler to ignore certain packages and patterns.

You most definitely can.
Use a system property (or add to jrebel.properties) meant just for that purpose. More information at JRebel agent properties.
-Drebel.exclude_packages=PACKAGE1,PACKAGE2,...
Specify the excluded packages in rebel.xml using Ant-styled patterns. More information at rebel.xml configuration.
<?xml version="1.0" encoding="UTF-8"?>
<application xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.zeroturnaround.com" xsi:schemaLocation="http://www.zeroturnaround.com http://update.zeroturnaround.com/jrebel/rebel-2_1.xsd">
<classpath>
<dir name="/path/to/module/build/directory/root">
<exclude name="com/yourapp/package1/internal/**"/>
</dir>
</classpath>
</application>
Both ways work similarly but since the second one enables to customize each module inividually it is generally preferred.

Related

Java XSLT processing throws TransformerConfigurationException when run on another machine

I am running a Java application which is supposed to do some XSLT processing based on javax.xml.transform.Transformer. I developed it on an older notebook using java-7-openjdk-amd64.
When I run it on another machine with java-8-openjdk-amd64 installed the Transformer throws the following exception:
javax.xml.transform.TransformerConfigurationException: Failed to
compile stylesheet. 1 error detected.
XPST0017: XPath syntax error [...]
Cannot find a matching 1-argument function named {http://xml.apache.org/xslt/java}java.text.SimpleDateFormat.new()
at net.sf.saxon.PreparedStylesheet.prepare(PreparedStylesheet.java:176)
at net.sf.saxon.TransformerFactoryImpl.newTemplates(TransformerFactoryImpl.java:139)
at net.sf.saxon.TransformerFactoryImpl.newTransformer(TransformerFactoryImpl.java:91)
The xsl file looks like this (leaving out unimportant details):
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:java="http://xml.apache.org/xslt/java" exclude-result-prefixes="java">
<xsl:template match="/">
<html>
<body>
<h1>Test Report</h1>
<h2>Test run</a> at
[<xsl:value-of
select="java:format(java:java.text.SimpleDateFormat.new('dd.MM.yyyy HH:mm:ss'), java:java.util.Date.new())" />]
</h2>
So the Transformer obviously has a problem with invoking SimpleDateFormat, but why? I could not find any information about this in respect to Java7 vs. Java8. I even copied the Jar file compiled with Jdk7 an and ran it on the other machine. Same problem, so it seems to be a runtime issue.
There are some Q+A on SO about java and XSLT but nothing turned out to be useful for me.
It turned out be that this declaration <xsl:stylesheet version="2.0" does not ensure that XSLT v2.0 is actually used. javax.xml.transform.Transformer "secretly" used XSLT v1.0 on the old machine (with java-7-openjdk-amd64) and XSLT v2.0 with Saxon v9.1.0 on the other machine (with java-8-openjdk-amd64).
The dependency was set by a maven pom.xml at compile time. But apparently this had no effect when running it with Jre7. I could have noticed it by looking at the stack trace (net.sf.saxon.TransformerFactoryImpl) but since there were no errors before, I was not aware of any specific TransformerFactory implementation.

enableAsyncMapping in WSDL file - Where exactly do I put it?

This is my first time creating Asynchronous Web Service clients. I have my wsdl file but I'm confused where to put:
<enableAsyncMapping>true</enableAsyncMapping>
Based on research, this is how to add it:
<bindings
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
wsdlLocation="AddNumbers.wsdl"
xmlns="http://java.sun.com/xml/ns/jaxws">
<bindings node="wsdl:definitions">
<package name="examples.webservices.async"/>
<enableAsyncMapping>true</enableAsyncMapping>
</bindings>
</bindings>
Should this be in a separate file or something? I read about the bindings file but still confused how to use it.
or can it be placed in the same WSDL file itself?
I am using the wsimport command to generate the client classes
I know it is old, but I needed it and google sent me here. It might help someone else in the future.
Using suggestions in one of the answers of this related question on wsimport, I created a custom xml file async.xml like this:
<jaxws:bindings xmlns:jaxws="http://java.sun.com/xml/ns/jaxws">
<jaxws:enableAsyncMapping>true</jaxws:enableAsyncMapping>
</jaxws:bindings>
And used wsdl2java with the following options (-b async.xml):
wsdl2java -client -d ClientDir -b async.xml myservice.wsdl
And I got the same (and more) version of the stubs returning Future<?>:
public Future<?> authorize
Cheers

Multiple XSLT files in a single pipeline with ant

I have multiple XSLT files that I'm using to process my source XML in a pipeline. I know about the trick with exsl:node-set but after having some issues with this workflow, I took the decision to split the various passes into separate XSL files. I'm much happier with the structure of the files now and the workflow works fine in Eclipse. Our release system works with ant. I can process the files like this:
<xslt basedir="src-xml" style="src-xml/preprocess_1.xsl" in="src-xml/original.xml" out="src-xml/temp_1.xml" />
<xslt basedir="src-xml" style="src-xml/preprocess_2.xsl" in="src-xml/temp_1.xml" out="src-xml/temp_2.xml" />
<xslt basedir="src-xml" style="src-xml/preprocess_3.xsl" in="src-xml/temp_2.xml" out="src-xml/temp_3.xml" />
<xslt basedir="src-xml" style="src-xml/finaloutput.xsl" in="src-xml/temp_3.xml" out="${finaloutput}" />
But this method, going via multiple files on disk, seems inefficient. Is there a better way of doing this with ant?
Update following Dimitre's suggestion
I've created myself a wrapper around the various other XSLs, as follows:
<xsl:stylesheet version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform' xmlns:fn='http://www.w3.org/2005/xpath-functions' xmlns:exslt="http://exslt.org/common">
<xsl:import href="preprocess_1.xsl"/>
<xsl:import href="preprocess_2.xsl"/>
<xsl:import href="preprocess_3.xsl"/>
<xsl:import href="finaloutput.xsl"/>
<xsl:output method="text" />
<xsl:template match="/">
<xsl:apply-imports />
</xsl:template>
</xsl:stylesheet>
This has... not worked well. It looks like the document had not been preprocessed before the final output XSL ran. I should perhaps have been clearer here: the preprocess XSL files are modifying the document, adding attributes and the like. preprocess_3 is based on the output of ..._2 is based on ..._1. Is this import solution still appropriate? If so, what am I missing?
The more efficient method is to perform a single, multipass transformation.
The files can remain as they are -- they will be imported using xsl:import instructions.
The savings are obvious:
Just one initiation (loading of the XSLT processor).
Just one termination.
Eliminates the two intermediate files and their creation, writing into, closing and deleting.
Hmm, you say I know about the trick with exsl:node-set, but you don't use it in your attempt ("Update following Dimitre's suggestion"). In case you don't know it, or for the others (like me) who don't know how to perform multipass transformation, here is a nice article: Multipass processing.
The drawback of this approach is that it requires engine specific xsl code. So if you know the engine, you could try this. If you don't know the engine, you could try with solutions from result tree fragment to node-set: generic approach for all xsl engines.
Looking at these sources one conclusion is sure: your current solution is more readable. But you are seeking efficiency, so some readability may be sacrificed.

How to control Spring-WS namespace single or double quote with XSLT

I want to change the double quotes to single quotes for a single namespace declaration in my document, while leaving all other namespace declarations as double quotes. How can I do this?
Here's the response document from the server:
<?xml version='1.0' encoding='UTF-8'?><soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body><InquiryResponse
xmlns="http://www.openuri.org/"><Header><HeaderAttr1>abcd</HeaderAttr1><HeaderAttr2>xxx</HeaderAttr2><HeaderAttr3>string</HeaderAttr3></Header><Body><InquiryResult><ResultItem1>theresulttext</ResultItem1><ResultItem2>abcd</ResultItem2><ResultItem3>0</ResultItem3></InquiryResult></Body></InquiryResponse></soapenv:Body></soapenv:Envelope>
I need something like (note that open:InquiryResponse has ' not ").
<?xml version="1.0" encoding="utf-8"?> <SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <SOAP-ENV:Body>
<open:InquiryResponse
xmlns:open='http://www.openuri.org/'><open:Header><open:HeaderAttr1>abcd</open:HeaderAttr1><open:HeaderAttr2>xxx</open:HeaderAttr2><open:HeaderAttr3>string</open:HeaderAttr3></open:Header><open:Body><open:InquiryResult><open:ResultItem1>theresulttext</open:ResultItem1><open:ResultItem2>abcd</open:ResultItem2><open:ResultItem3>0</open:ResultItem3></open:InquiryResult></open:Body></open:InquiryResponse>
</SOAP-ENV:Body> </SOAP-ENV:Envelope>
I have been able to do namespace prefix change, additional namespace declarations, whitespace fixups, character set change, all I need now is to change those two bytes.
I'm using Spring WS + Woodstox + Axiom to build a simple inquiry web service. It's a replacement for an existing service and I would like to make it byte-for-byte identical ($$ reasons). I can get the XML to identical type, but we don't know at this point which consumers use a grep or regex to find the data.
I am trying to attack this problem so far using an XSLT and PayloadTransformingInterceptor. I would be interested in other options as well.
Comments are pretty much correct: there is no "clean" programmatic solution to configuring low-levels with such precision. And given fragility, you are best off using textual mangling; most likely regexps would work well enough if this is for testing or such.
After re-reading your question and examples a few times I think I understand the problem :)
I think you should take a look at the PayloadTransformingInterceptor. You can transform the incoming and outgoing messages in that interceptor. A typical usage of that interceptor is to support an older version of your wsdl by transforming it to the new version. This interceptor can work both ways - in your case only outgoing.
I'm not sure if this can be fixed by using XSLT. If not, you can create your own Interceptor to provide the specific string replacement functionality you need.
The solution was to drop Spring-WS, and instead move to CXF. CXF allows interceptors at any stage of processing, and hence full access to the bytes of the message stream. Ugly, but working. Build an interceptor to hook the OutputStream at PRE_STREAM and then do the fix at PRE_STREAM_ENDING, and you will have full control over the SOAP Envelope.
Thank you all for your responses. It sucks but it works, and is reasonably easy to disconnect when we have the time to do it properly (!!).

How to execute XSLT 2.0 with ant?

I'm trying to run an XSLT transformation from an ant file.
I'm using a XSLT 2.0 stylesheet with a saxon 9 parser (supporting XSLT 2.0).
The problem is that it seems that ant is always calling an XSLT 1.0 parser.
Here's my ant file :
<xslt style="stylesheet.xslt"
basedir="core/"
extension=".xml"
destdir="core/"
classpath="D:\\DevTools\\saxon\\bin\\saxon9.jar">
</xslt>
If I call it directly (without ant), it's working.
Any idea ?
The problem is that while Saxon is added to the classpath, the default JAXP mechanism to determine which TransformerFactory is used and it will use the default that is Xalan. You either need to:
Set javax.xml.transform.TransformerFactory system variable to net.sf.saxon.TransformerFactoryImpl,
Add saxon9.jar to the CLASSPATH system variable, or
Use <factory name="net.sf.saxon.TransformerFactoryImpl"/> inside the xslt element
If you are having this problem, check that you are not using Ant 1.8.1, because there is a bug in Ant 1.8.1 that prevents this from working. (Though this is not the problem in the original post, because that was before Ant 1.8.1 was released).
Your options are:
Use a version of Ant that does not have the bug (e.g. Ant 1.7.1).
Explicitly specify saxon9.jar in the CLASSPATH to Ant before it starts, by either:
Setting the system CLASSPATH environment variable, or
Use the -lib command line option to ant
Define your own task using SAXON Ant (as described by another answer on this thread).
Workaround by adding processor="org.apache.tools.ant.taskdefs.optional.TraXLiaison" as an attribute of the xslt task element.
I would suggestion using option 1, followed by option 4.
Option 2 will work, but it places the responsibility on the person running ant to set up their environment and run ant properly. I assume you don't want that, which is why you are trying to get the classpath attribute on the xslt task to work.
Option 3 has limitations, because SAXON Ant requires downloading and installing its JAR file. Also SAXON Ant does not work with SAXON 9.2 or later (and SAXON Ant has not been updated since it was created in June 2008).
In theory, specifying a factory subelement makes the XSLT processor that you want to use explicit -- to prevent the class loader from finding a different XSLT processor earlier in its search, and using it instead of your XSLT processor which is further down in the CLASSPATH. In practice (at least in ant 1.7.0, 1.7.1 and 1.8.0) if the factory subelement is specified the xslt task ignores the classpath attribute -- which means you have to resort to explicitly specifying the CLASSPATH (option 2). So it doesn't help solve the original problem. However, this seems to have been fixed in the Ant source code, so could work in releases after 1.8.1.
This tutorial seems to give step by step instructions on how to do what you are asking:
http://www.abbeyworkshop.com/howto/xslt/ant-saxon/index.html
From that it appears you are doing the correct thing. Are you sure you need the double back slashes?
Update: The xslt Ant documentation mentions the 'factory' property which may help you get closer:
http://ant.apache.org/manual/Tasks/style.html
EDIT: Dr. Michael Kay has pointed out that the AntTransform is no longer supported, nor recommended.
Create a taskdef from the Saxon AntTransform class:
<taskdef name="saxon-xslt" classname="net.sf.saxon.ant.AntTransform" classpath="${basedir}/lib/saxon/saxon9.jar;${basedir}/lib/saxon/saxon9-ant.jar"/>
<saxon-xslt
in="${source.xml}"
out="${out.dir}/${output.xml}"
style="${basedir}/${stylesheet.xsl}"
force="true">
</saxon-xslt>
I have begun using the standard <xslt> task with the saxon jar specified in a <classpath>, but had been running into performance issues. It seemed to "hang" for a bit when the task was called. I have found that adding processor="trax" and specifying <factory name="net.sf.saxon.TransformerFactoryImpl"/> helps it run much faster.
<xslt in="${source.xml}"
out="${out.dir}/${output.xml}"
style="${basedir}/${stylesheet.xsl}"
processor="trax">
<factory name="net.sf.saxon.TransformerFactoryImpl"/>
<classpath refid="saxon-classpath" />
</xslt>
Rather than waiting for this to be fixed in 1.8.2 and then waiting for everyone to eventually upgrade to 1.8.2, you can roll your own XSLT macro (for situations where you explicitly want to use Saxon, rather than a user selected XSLT engine)
<macrodef name="xslt" uri="com.mycompany.mydepartment">
<attribute name="in" />
<attribute name="out" />
<attribute name="style" />
<attribute name="classpath" default="${saxon.jar.path}" />
<attribute name="taskname" default="mydep:xslt" />
<element name="params" optional="true" implicit="true" />
<sequential>
<java classname="net.sf.saxon.Transform"
classpath="#{classpath}"
taskname="#{taskname}">
<classpath path="${saxon.jar.path}" />
<arg value="-s:#{in}" />
<arg value="-xsl:#{style}" />
<arg value="-o:#{out}" />
<params />
</java>
</sequential>
</macrodef>
you can then invoke it like (assuming xmlns:mydep="com.mycompany.mydepartment" is set on the project element)
<mydep:xslt in="${myinput}"
out="${myoutput}"
style="${myxslt}">
<arg value="param1=value1" />
<arg value="param2=value2" />
<arg value="+param3=somefile.xml" />
</mydep:xslt>
You can find the docs for passing parameters to Saxon at http://www.saxonica.com/documentation/using-xsl/commandline.xml
At least in ant 1.8.0, the xslt task with a specified classpath is very slow.
The problem seems to be classpath loading. I ran ant under JDB and it spent all of the extra time in org.apache.tools.ant.AntClassLoader.loadClass reading zip files.
I tried this before running ant it it went a lot faster:
ant -lib /path/to/saxon/saxon9.jar
The macrodef from Tom Howard works better, and although it has an odd syntax for XSLT params, at least it's possible.