Unlock a world of possibilities! Login now and discover the exclusive benefits awaiting you.
I've been experimenting with all the different ways you can call a method from an external java library from within a Talend job. I was able to create a Routine that calls a method from the Apache Commons Lang library. As a test, I wanted to use the StringUtils.capitalize method to capitalize Strings in a variety of use cases. I figured a Routine would be most appropriate.
I added the Apache Commons Lang jar as a new library in the User Libraries screen. Then, I created a new Routine called ApacheStringUtils. Within it, I created a method called capitalize which called the StringUtils.capitalize method in the Apache Commons Lang library. The Routine looks like this:
package routines;
import org.apache.commons.lang3.StringUtils;
public class ApacheStringUtils {
/**
* capitalize: returns a String with a capitalized first character
*
*
* {talendTypes} String
*
* {Category} User Defined
*
* {param} string str: The string needing to be capitalized.
*/
public static String capitalize(String str) {
return StringUtils.capitalize(str);
}
/**
* uncapitalize: returns a String with an uncapitalized first character
*
*
* {talendTypes} String
*
* {Category} User Defined
*
* {param} string str: The string needing to be uncapitalized.
*/
public static String uncapitalize(String str) {
return StringUtils.uncapitalize(str);
}
}
This Routine showed no errors.
To test, I successfully ran the Routine in a tJava component with the following code:
System.out.println(ApacheStringUtils.capitalize("word"));
This job printed out "Word" as expected.
However, when I tried to use this same routine in a tMap expression, it failed due to the following NoClassDefFoundError exception:
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/lang3/StringUtils
at routines.ApacheStringUtils.uncapitalize(ApacheStringUtils.java:33)
at test_talend.manipulatecsvdatatest_0_1.ManipulateCSVDataTest.tFileInputDelimited_1Process(ManipulateCSVDataTest.java:2242)
at test_talend.manipulatecsvdatatest_0_1.ManipulateCSVDataTest.runJobInTOS(ManipulateCSVDataTest.java:2846)
at test_talend.manipulatecsvdatatest_0_1.ManipulateCSVDataTest.main(ManipulateCSVDataTest.java:2680)
Caused by: java.lang.ClassNotFoundException: org.apache.commons.lang3.StringUtils
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
... 4 more
This didn't make much sense to me, as it was running successfully in a tJava component. Why not here? When I pressed Ctrl+Space when filling in my expression, I was even able to see my ApacheStringUtils methods. In fact, the methods from the imported library's StringUtils class showed up as well. I tried using those directly, but received an error that those methods were "undefined for type StringUtils."
So, my question is: Why can I access an imported library via a routine in a tJava component but not a tMap expression?
I added the Apache Commons Lang jar as a new library in the User Libraries screen. Then, I created a new Routine called ApacheStringUtils