on 02-10-2007 10:38 PM
Hi,
I´m trying the "Easy RFC lookup from XSLT mappings using a Java helper class" article and I getting a weird problem.
The result of the RFC lookup called inside the java class is maintained in a kind of cache and I always get the same results independent of the parameters I use in the following calls.
Just after calling a Complete Cache Refresh (SXI_CACHE) I got a new result to the lookup.
If I call in the Interface Mapping Test option it runs fine. However, when I call it from my scenario (SOAP Adapter Sender) the first result of the lookup will be returned until a forced cache refresh.
Any ideas?
Thank you,
Fabiano.
Fabiano,
I think your problem is due to static variables inside the Java class. The values are persisted across multiple executions and only a forced cache refresh works.
The reason behind "Interface Mapping Test option" working fine is it would reinitialize your static variable every time but at the runtime i.e. integration engine runtime , the static variables will be those memory locations which would be initialized when a cache refresh was done...
Even I had faced similar problems in module development....
Hope this helps..
-- Amol
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hello Fabiano,
I had the same problem like you had.
The main Problem is that with the example code the request variable is created as NodeList object. In XSLT a variable is somekind of a constant and can't be changed. As the request object is empty after the first request the programm fails at the following line:
Source source = new DOMSource(request.item(0));
So I've created a workaround for this problem.
In the call of the template I've put the request as a parameter object at the template call:
<xsl:with-param name="req">
<rfc:PLM_EXPLORE_BILL_OF_MATERIAL xmlns:rfc="urn:sap-com:document:sap:rfc:functions">
<APPLICATION>Z001</APPLICATION>
<FLAG_NEW_EXPLOSION>X</FLAG_NEW_EXPLOSION>
<MATERIALNUMBER><xsl:value-of select="value"/></MATERIALNUMBER>
<PLANT>FSD0</PLANT>
<VALIDFROM><xsl:value-of select="//Recordset/Row[name='DTM-031']/value"/></VALIDFROM>
<BOMITEM_DATA/>
</rfc:PLM_EXPLORE_BILL_OF_MATERIAL>
</xsl:with-param>
With this change the request will be provided as a String object and not as a NodeList object.
Afterwards the RfcLookup.java has to be changed to the following:
package com.franke.mappings;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Map;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import com.sap.aii.mapping.lookup.Channel;
import com.sap.aii.mapping.api.StreamTransformationConstants;
import com.sap.aii.mapping.api.AbstractTrace;
import com.sap.aii.mapping.lookup.RfcAccessor;
import com.sap.aii.mapping.lookup.LookupService;
import com.sap.aii.mapping.lookup.XmlPayload;
/**
* @author Thorsten Nordholm Søbirk, AppliCon A/S
*
* Helper class for using the XI Lookup API with XSLT mappings for calling RFCs.
* The class is generic in that it can be used to call any remote-enabled
* function module in R/3. Generation of the XML request document and parsing of
* the XML response is left to the stylesheet, where this can be done in a very
* natural manner.
*
* TD:
* Changed the class that request is sent as String, because of IndexOutOfBound-exception
* When sending multiple requests in one XSLT mapping.
*
*/
public class RfcLookup {
/**
* Execute RFC lookup.
* @param request RFC request - TD: changed to String
* @param service name of service
* @param channelName name of communication channel
* @param inputParam mapping parameters
* @return Node containing RFC response
*/
public static Node execute( String request,
String service,
String channelName,
Map inputParam)
{
AbstractTrace trace = (AbstractTrace) inputParam.get(StreamTransformationConstants.MAPPING_TRACE);
Node responseNode = null;
try {
// Get channel and accessor
Channel channel = LookupService.getChannel(service, channelName);
RfcAccessor accessor = LookupService.getRfcAccessor(channel);
// Serialise request NodeList - TD: Not needed anymore as request is String
/*TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer();
Source source = new DOMSource(request.item(0));
ByteArrayOutputStream baos = new ByteArrayOutputStream();
StreamResult streamResult = new StreamResult(baos);
transformer.transform(source, streamResult);*/
// TD: Add xml header and remove linefeeds for the request string
request = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"+request.replaceAll("[\r\n]+", "");
// TD: Get byte Array from request String to send afterwards
byte[] requestBytes = request.getBytes();
// TD: Not used anymore as request is String
//byte[] requestBytes = baos.toByteArray();
trace.addDebugMessage("RFC Request: " + new String(requestBytes));
// Create input stream representing the function module request message
InputStream inputStream = new ByteArrayInputStream(requestBytes);
// Create XmlPayload
XmlPayload requestPayload =LookupService.getXmlPayload(inputStream);
// Execute lookup
XmlPayload responsePayload = accessor.call(requestPayload);
InputStream responseStream = responsePayload.getContent();
TeeInputStream tee = new TeeInputStream(responseStream);
// Create DOM tree for response
DocumentBuilder docBuilder =DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document document = docBuilder.parse(tee);
trace.addDebugMessage("RFC Response: " + tee.getStringContent());
responseNode = document.getFirstChild();
} catch (Throwable t) {
StringWriter sw = new StringWriter();
t.printStackTrace(new PrintWriter(sw));
trace.addWarning(sw.toString());
}
return responseNode;
}
/**
* Helper class which collects stream input while reading.
*/
static class TeeInputStream extends InputStream {
private ByteArrayOutputStream baos;
private InputStream wrappedInputStream;
TeeInputStream(InputStream inputStream) {
baos = new ByteArrayOutputStream();
wrappedInputStream = inputStream;
}
/**
* @return stream content as String
*/
String getStringContent() {
return baos.toString();
}
/* (non-Javadoc)
* @see java.io.InputStream#read()
*/
public int read() throws IOException {
int r = wrappedInputStream.read();
baos.write(r);
return r;
}
}
}
Then you need to compile and upload this class and it should work.
I hope that this helps you.
Best regards
Till
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Apply the bugfix described in note 1029025 to your system.
Regards
Stefan
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
HI,
I have some links , try if useful.
Lookups with XSLT - https://www.sdn.sap.com/irj/sdn/go/portal/prtroot/docs/library/uuid/8e7daa90-0201-0010-9499-cd347ffb...
/people/sravya.talanki2/blog
Regards
Chilla...
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi Amol!
The example code uses a static inner class to help the input. I have chaged it to a normal class but with no success. The problem is still the same.
The code is here:
<a href="https://www.sdn.sap.comhttp://www.sdn.sap.comhttp://www.sdn.sap.com/irj/sdn/go/portal/prtroot/docs/library/uuid/05a3d62e-0a01-0010-14bc-adc8efd4ee14">https://www.sdn.sap.comhttp://www.sdn.sap.comhttp://www.sdn.sap.com/irj/sdn/go/portal/prtroot/docs/library/uuid/05a3d62e-0a01-0010-14bc-adc8efd4ee14</a>
Thank you,
Fabiano.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
We are experiencing the same problem. We are on PI 7.10 SP8.
We are adviced by SAP to apply note 1049312 however we are in doubt about the impact as in the note SAP states:
Disable the XSL Transformer resuse by XI. Note that this might lead to performance decrease in complex XSLT mappings. No other side effects should be caused by this
Also the note is not released for PI7.1X
Anybody a clue?
Regards,
Emile
User | Count |
---|---|
87 | |
10 | |
10 | |
10 | |
7 | |
6 | |
6 | |
5 | |
5 | |
4 |
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.