Forum Stats

  • 3,872,464 Users
  • 2,266,426 Discussions
  • 7,911,213 Comments

Discussions

Java Embedding in BPEL

2»

Answers

  • 3741383
    3741383 Member Posts: 20
    edited Jul 31, 2018 5:55AM

    i had changed it into that, but sadly still facing the same error.. is it because of the java Exception? i tried with different variables but still facing the same prob, do you think my code is wrong?

  • 3741383
    3741383 Member Posts: 20
    edited Jul 31, 2018 6:30AM

    @Martien van den Akker sir can you help me, please?

  • 3741383
    3741383 Member Posts: 20
    edited Aug 9, 2018 11:43PM

    can you help me sir @3168278

  • Martien van den Akker
    Martien van den Akker Member Posts: 2,777 Bronze Crown
    edited Aug 22, 2018 5:26AM Answer ✓

    Hi,

    First off: this is quite a bit of functional code you want to try to do in embedded java. I'm not so fond of that. I'd use embedded java only for small, simple calculations or logging/auditing. The thing is that you can properly test and debug your code in embedded java. Also exception-handling cannot be done very nicely and declaratively. Since you apparently have a class that works as a stand-alone class, I'd register it as a spring bean. Possibly by adding a few accompanying beans that serve as  an input and result. See for instance my article here: https://blog.darwin-it.nl/2012/09/forget-about-wsif-welcome-spring.html This way you can add this bean declaratively to your composite and wire it to your bpel. That will generate a wsdl and a partnerlink for you. So you can just invoke it. That way you can test and debug the class stand alone in JDeveloper and then only need to get your input and output variables assigned properly.

    However, in your case you probably struggle with the lines

    XMLElement pwdElement = (XMLElement)getVariableData("setVar","/n8SetVar","/ns8:pwd");          String text = pwdElement.getTextContent();       

    and

    setVariableData("setVar","/n8SetVar","/ns8:setPwd",result);

    These are fields within a complex variable, where you need to set a proper xpath and message part. Two ways to solve this

    • If you want to keep these references, create a temporary assign statement with a copy-rule that assigns a dummy string to the particular element. If you select the assign and switch to the source, you'll find the copy rule with in the to-part the specific reference to the variable-part-element. Use that information to correct the getVariableData() and setVariableData() statements. Then remove the dummy assign. The error you posted noted '<faultcode>ns0:selectionFailure</faultcode>' which refers to one of these statements. Probably the first one. But I can't see in the stacktrace which line is meant (since the embedded java is compiled into a class during compilation of the bpel).
    • Much easier is to declare two xsd:string based variables to hold the password and store the result. Then first assign the value of the setVar variable to the variable 'password'. Then you just can refer to it with getVariableData('password'). No xpath needed. Then the setVariableData() becomes setVariableData('result'). I believe you don't need to convert the XMLElement to string. I have in one of my earlier projects a simple embedded sub-process that does logging like:
    <bpelx:inlineSubProcess name="SubProcessAddAuditTrailEntry">    <variables>      <variable name="logMessage" type="xsd:string"/>    </variables>    <sequence name="SequenceAddAuditTrailEntry">      <extensionActivity>        <bpelx:exec name="addAuditTrailEntry">          <![CDATA[final String bpelName = "HREmployeeEventToITProcess.bpel";  String logMessage = (String) getVariableData("logMessage");  addAuditTrailEntry(bpelName+": "+logMessage);]]>        </bpelx:exec>      </extensionActivity>    </sequence>  </bpelx:inlineSubProcess>

    You see here that I have a logMessage Variable based on xsd:string. I can just refer to it as String logMessage = (String) getVariableData("logMessage");  If I translate this to your situation I would probably get something like:

    <scope name="hashAPassword">    <variables>      <variable name="password" type="xsd:string"/>      <variable name="result" type="xsd:string"/>    </variables>    <sequence name="SequenceHashAPassword">      <extensionActivity>        <bpelx:exec name="addAuditTrailEntry">          <![CDATA[String text = (String) getVariableData("password");  try{        MessageDigest md = MessageDigest.getInstance("SHA1");            byte[] data = new byte[40];             md.update(text.getBytes("iso-8859-1"), 0, text.length());             data = md.digest();             StringBuffer buf = new StringBuffer();        for (int i = 0; i < data.length; i++) {                 int halfbyte = (data[i] >>> 4) & 0x0F;                 int two_halfs = 0;                 do {                     if ((0 <= halfbyte) && (halfbyte <= 9)) {                         buf.append((char) ('0' + halfbyte));  }                   else {                         buf.append((char) ('a' + (halfbyte - 10))); }                    halfbyte = data[i] & 0x0F;                } while (two_halfs++ < 1);       }       String result = buf.toString();     System.out.println(result);     setVariableData("result"); }catch(Exception e){ }]]>        </bpelx:exec>      </extensionActivity>    </sequence>  </scope>

    Add this to your BPEL. Then right click on the scope to transform it to an embedded subprocess and you can call it based on the originating message variables.

    Regards,

    Martien

    PS1: I just got back from vacation this week, so I have a pile of messages to follow-up on

    PS2: I did not test this, I rely on the proper functioning on your code and copy and pasted it in my example to refactor it.

    Amy Childress-Oracle3741383
This discussion has been closed.