cancel
Showing results for 
Search instead for 
Did you mean: 

ArrayIndexOutOfBoundsException in UDF

Former Member
0 Kudos

Hi PI Experts,

I am trying to develop an UDF(All Values of Queue) which takes a string as input contains pipe(|) delimiter for both fields and field values. Also, string contains both Header and Detail.

Header fields will come once and Detail in 'N 'number of times in a single line.


Below is the input string  ::
*******************************

Headerfield1|fieldValue1|Headerfield2|fieldValue2|Headerfield3|fieldValue3|Headerfield4|fieldValue4|Headerfield5|fieldValue5|Headerfield6|fieldValue6|Itemfield1|fieldvalue1|Itemfield1|fieldvalue1|Itemfield2|fieldvalue2|Itemfield3|fieldvalue3|Itemfield4|fieldvalue4|Itemfield1-1|fieldvalue1-1|Itemfield2-1|fieldvalue1-2|Itemfield3-1|fieldvalue3-1|Itemfield4-1|fieldvalue4-1|Itemfield1-2|fieldvalue1-2|Itemfield2-2|fieldvalue2-2|Itemfield3-2|fieldvalue3-2|Itemfield4-2|fieldvalue4-2|

Say in above string, Headerfield1 is a field and its corresponding value is fieldValue1


In UDF, we are passing input string in variable input and required field in the variable field.

I am trying to pass the field name and expecting its corresponding field value as output

Below is the UDF
********************
public void StringSplit(String[] input, String[] field, ResultList result, Container container) throws StreamTransformationException{

String str = input.toString();
String tokens[] = str.split("\\|");
Map<String, String>tokensMap = new HashMap();
  int j =0;
  for(int i =0; i <tokens.length ; i++)
  {
    if(j == i)
    {
     String key = tokens[i].toString();
       if (key.contains("-"))
     {
     String key2 = key.substring(0, key.indexOf("-"));
     if(tokensMap.containsKey(key2))
     {
     tokensMap.put(key2, tokensMap.get(key2)+","+tokens[i+1].toString());
     }
     else
     {
     tokensMap.put(key.substring(0, key.indexOf("-")),tokens[i+1].toString());
     }
     }
     else
     {
     tokensMap.put(tokens[i].toString(),tokens[i+1].toString());
     }
     j = i+2;
    }
   }
  String[] result1 = tokensMap.get(field).split(",");
  for (int i = 0; i < result1.length; i++)
{
if (result1[i].equals("") || result1[i].equals(null) )
result.addSuppress();
else
      result.addValue(result1[i]); 
}
}
*********************


This UDF, takes input string and splits with pipe(|) and kept it in tokens later add it to tokensMap. Finally get the required field and stores into the result1 and by using for loop adding into the result list. I am getting an error below.

Error
******

Exception:[java.lang.ArrayIndexOutOfBoundsException:] in class com.sap.xi.tf.

Error Log Screen Shot attached. PFA.

Please check the error and suggest where I need to change.

Thanks in advance

Thank you,
Chakradhar N

Accepted Solutions (1)

Accepted Solutions (1)

markangelo_dihiansan
Active Contributor
0 Kudos

Hi,

Since your UDF is of queue type, you have to take into account ResultList.CC (ContextChange) and ResultList.SUPPRESS (Suppressed) into your checking. For example, if it is a contextChange, the split would be a null pointer, same with suppress.

Add a check like this:

for(int a=0;a<input.length;a++){

     String str = input.toString();

     if(!(str.equals("ResultList.CC")||str.equals("ResultList.SUPPRESS")){

          RestofYourLogicHere;

     }

}

Regards,

Mark

Former Member
0 Kudos

Hi Mark,

Thanks for your answer..

As you told i have included below condition to by code

for(int a=0;a<input.length;a++){

     String str = input.toString();

     if(!(str.equals("ResultList.CC")||str.equals("ResultList.SUPPRESS")){

          RestofYourLogicHere;

     }

}

Now, i am facing below error

Java Area import, Line 15:
package com.sap.aii.security.lib does not exist
import com.sap.aii.security.lib.*;


Java Area import, Line 16:
package com.sap.aii.af.service.resource does not exist
import com.sap.aii.af.service.resource.*;

Error Screen Shot attached. PFA.

As per the error it is clear that i have to import both com.sap.aii.security.lib.* & com.sap.aii.af.service.resource.*;.

I have checked few threads but it is not clear where i will get the jar files and how i need to import.

Please let me know where i can get these jar files and how to import into our PI. I am using SAP PI 7.1

Thanks in advance.

Thank you,

Chakradhar N

markangelo_dihiansan
Active Contributor
0 Kudos

Hi Chakradhar,

Please change if(!(str.equals("ResultList.CC")||str.equals("ResultList.SUPPRESS"))

to if(!(str.equals(ResultList.CC)||str.equals(ResultList.SUPPRESS))

The double quotes are not needed.

Not sure where you get security.lib and af.service.resource error from. Perhaps you are using these libraries in other parts of your code?

Regards,

Mark

Former Member
0 Kudos

Hi Mark,

Thanks for the clarification..

Yes, i have removed double quotes and used it and the above error(com.sap.aii.security.lib.* & com.sap.aii.af.service.resource.*;.) is fixed, as you told it was caused with another UDF.
i am using below code, but still i am facing an error
Exception:[java.lang.ArrayIndexOutOfBoundsException: 29] in class com.sap.xi.tf._ method StringSplit[[Ljava.lang.String;@34f02d16, [Ljava.lang.String;@4201a81, com.sap.aii.mappingtool.tf7.rt.ResultListImpl@57ac0d44, com.sap.aii.mappingtool.tf7.rt.Context@609b1853]

Code  ::

******

public void StringSplit(String[] input, String[] field, ResultList result, Container container) throws StreamTransformationException{

    for(int a=0;a<input.length;a++){

    String str = input.toString();  

     if (!(str.equals(ResultList.CC)||str.equals(ResultList.SUPPRESS))){

      String[] tokens = str.split("//|");

   Map<String, String>tokensMap = new HashMap();

   int j =0;

    for(int i =0; i <tokens.length ; i++)

    {

       if(j == i)

       {

        String key = tokens[i].toString();

        if (key.contains("-"))

        {

        String key2 = key.substring(0, key.indexOf("-"));

         if(tokensMap.containsKey(key2))

         {

          tokensMap.put(key2, tokensMap.get(key2)+","+tokens[i+1].toString());

         }

         else

         {

          tokensMap.put(key.substring(0, key.indexOf("-")),tokens[i+1].toString());

          }

        }

        else

        {

        tokensMap.put(tokens[i].toString(),tokens[i+1].toString());

        }

       j = i+2;

       }

    }

String[] result1 = tokensMap.get(field).split(",");

   for (int i = 0; i < result1.length; i++)

{

  if (result1[i].equals("") || result1 [i].equals(null) )

   result.addSuppress();

  else

      result.addValue(result1.toString()); 

  }

   }

}

}

Error says at 29th line. Could you please validate where i am wrong.

Thanks in advance.

Thank you,

Chakradhar N

markangelo_dihiansan
Active Contributor
0 Kudos

Hi Chakradhar,

The error is coming from this line

String[] result1 = tokensMap.get(field).split(",");


but that is because of the your tokenizer logic. Please debug this in an IDE such as NWDS or Eclipse

Regards,

Mark

Former Member
0 Kudos

Hi Mark,

Thanks for the suggestion

When i test this code in Eclipse, this is working fine. But when we use same code it is not working in PI.

Please find the attached eclipse test screenshots.

Please let me know what would be the reason for the error only in PI.

Thanks in advance

Thank you,
Chakradhar N

markangelo_dihiansan
Active Contributor
0 Kudos

Hi,

Can you show us a screenshot of your display queue inputs to the UDF?

Regards,

Mark

Former Member
0 Kudos

Hi Mark,

Thanks for the response

I am supplying input parameters as input and field, where input has complete string and field has field name. In the attached screen shot i am using nodefunction "replaceString" since i am getting extra string(<?xml version="1.0" encoding="UTF-8"?><stringinp><![CDATA[) in input.

Please find the attached screen shots of inputs to the UDF.

Thanks in advance.

Thank you,

Chakradhar

markangelo_dihiansan
Active Contributor
0 Kudos

Hi,

I modified your code a bit, please use this one:

Here are the changes: String str = input.toString() -> String str = input[a].toString();

String[] tokens = str.split("//|"); -> String[] tokens = str.split("\\|");

result.addValue(result1.toString());  -> result.addValue(result[i].toString();


  for(int a=0;a<input.length;a++){

    String str = input[a].toString(); 

     if (!(str.equals(ResultList.CC)||str.equals(ResultList.SUPPRESS))){

      String[] tokens = str.split("\\|");

   Map<String, String>tokensMap = new HashMap();

   int j =0;

    for(int i =0; i <tokens.length ; i++)

    {

       if(j == i)

       {

        String key = tokens[i].toString();

        if (key.contains("-"))

        {

        String key2 = key.substring(0, key.indexOf("-"));

         if(tokensMap.containsKey(key2))

         {

          tokensMap.put(key2, tokensMap.get(key2)+","+tokens[i+1].toString());

         }

         else

         {

          tokensMap.put(key.substring(0, key.indexOf("-")),tokens[i+1].toString());

          }

        }

        else

        {

        tokensMap.put(tokens[i].toString(),tokens[i+1].toString());

        }

       j = i+2;

       }

    }

String[] result1 = tokensMap.get(field[0]).split(",");

   for (int i = 0; i < result1.length; i++)

{

  if (result1[i].equals("") || result1 [i].equals(null) )

   result.addSuppress();

  else

      result.addValue(result1[i].toString());

  }

   }

}

Also, the sample input is incorrect, please use this one


Headerfield1|fieldValue1|Headerfield2|fieldValue2|Headerfield3|fieldValue3|Headerfield4|fieldValue4|Headerfield5|fieldValue5|Headerfield6|fieldValue6|Itemfield1|fieldvalue1|Itemfield1|fieldvalue1|Itemfield2|fieldvalue2|Itemfield3|fieldvalue3|Itemfield4|fieldvalue4|Itemfield1-1|fieldvalue1-1|Itemfield2-1|fieldvalue1-2|Itemfield3-1|fieldvalue3-1|Itemfield4-1|fieldvalue4-1|Itemfield1-2|fieldvalue1-2|Itemfield2-2|fieldvalue2-2|Itemfield3-2|fieldvalue3-2|Itemfield4-2|fieldvalue4-2|

See output from test:

Hope this helps,

Mark

Former Member
0 Kudos

Hi Mark,

Issue got resolved, I am very thankful for your help..

Thank you,

Chakradhar N

Answers (2)

Answers (2)

Former Member
0 Kudos

Thanks to both(Javi & Mark) of you for very quick reply.

javier_alcubilla
Contributor
0 Kudos

Hi

To trace into the UDF

MappingTrace mtrace = container.getTrace();

mtrace.addInfo(<trace_var_name>);

Regards

Javi