All Forums Extensibility
erics01 4 posts Joined 06/10
24 Sep 2014
error when compiling Java UDF

Hi,
 
We have the next SQL file:
------------------------------------------------------ ------------------------------------------------------ --------------
CALL SQLJ.REMOVE_JAR('UA_Jar',0);
CALL SQLJ.INSTALL_JAR('CJ!/home/tdatuser/java/Parser.zip',' UA_Jar',0);
CREATE FUNCTION ua_family (agentString CHAR(30))
RETURNS CHAR(30)
LANGUAGE JAVA
NO SQL
PARAMETER STYLE JAVA
CALLED ON NULL INPUT
EXTERNAL NAME 'UA_Jar:Parser.parseUserAgent(java.lang.String) returns java.lang.String';
------------------------------------------------------ ------------------------------------------------------ --------------
 
We got the following error (can not found the 'Parser' class) when we run it through bteq:
+---------+---------+---------+---------+---------+--- ------+---------+----
CALL SQLJ.REMOVE_JAR('UA_Jar',0);
 *** Procedure has been executed.
 *** Total elapsed time was 1 second.

+---------+---------+---------+---------+---------+--- ------+---------+----
CALL SQLJ.INSTALL_JAR('CJ!/home/tdatuser/java/Parser.zip',' UA_Jar',0);
 *** Procedure has been executed.
 *** Warning: 9241 Check output for possible warnings encountered in Installing or Replacing a JAR.
 *** Total elapsed time was 1 second.
Check output for possible warnings.
------------------------------------------------------ ---------------------
    0 Wed Sep 24 08:13:56 EDT 2014 ua_parser/
 2095 Wed Sep 24 07:00:52 EDT 2014 ua_parser/CachingParser.class
 1209 Wed Sep 24 07:00:52 EDT 2014 ua_parser/Client.class
 1333 Wed Sep 24 07:00:52 EDT 2014 ua_parser/Device.class
 2081 Wed Sep 24 07:00:52 EDT 2014 ua_parser/DeviceParser.class
 1183 Wed Sep 24 07:00:52 EDT 2014 ua_parser/DeviceParser$DevicePattern.class
 2304 Wed Sep 24 07:00:52 EDT 2014 ua_parser/OS.class
 2177 Wed Sep 24 07:00:52 EDT 2014 ua_parser/OSParser.class
 1761 Wed Sep 24 07:00:52 EDT 2014 ua_parser/OSParser$OSPattern.class
 2427 Wed Sep 24 07:00:52 EDT 2014 ua_parser/Parser.class
 2070 Wed Sep 24 07:00:52 EDT 2014 ua_parser/UserAgent.class
 2241 Wed Sep 24 07:00:52 EDT 2014 ua_parser/UserAgentParser.class
 1651 Wed Sep 24 07:00:52 EDT 2014 ua_parser/UserAgentParser$UAPattern.class
45317 Wed Sep 24 06:29:00 EDT 2014 ua_parser/regexes.yaml
+---------+---------+---------+---------+---------+--- ------+---------+----
CREATE FUNCTION ua_family (agentString CHAR(30))
RETURNS CHAR(30)
LANGUAGE JAVA
NO SQL
PARAMETER STYLE JAVA
CALLED ON NULL INPUT
EXTERNAL NAME 'UA_Jar:Parser.parseUserAgent(java.lang.String) returns java.lang.String';
 *** Create function completed with error(s).
 *** Warning: 7980 A JAVA method in the specified Jar which matches that in the EXTERNAL NAME clause was not found.
 *** Total elapsed time was 2 seconds.
Errors/Warnings reported while creating a Java XSP/UDF
------------------------------------------------------ ---------------------
08:33:54,895 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback.groovy]
08:33:54,895 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback-test.xml]
08:33:54,896 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Found resource [logback.xml] at [jar:file:/opt/teradata/tdat/tdbms/15.00.00.07/bin/ javFnc.jar!/logback.xml]
08:33:54,946 |-INFO in ch.qos.logback.classic.joran.action.ConfigurationActio n - debug attribute not set
08:33:54,952 |-ERROR in ch.qos.logback.core.util.ContextUtil@7f5663a2 - Failed to get local hostname java.net.UnknownHostException: TDExpress15008_Sles10: TDExpress15008_Sles10
 at java.net.UnknownHostException: TDExpress15008_Sles10: TDExpress15008_Sles10
 at  at java.net.InetAddress.getLocalHost(InetAddress.java: 1374)
 at  at ch.qos.logback.core.util.ContextUtil.getLocalHostName( ContextUtil.java:30)
 at  at ch.qos.logback.core.util.ContextUtil.addHostNameAsProp erty(ContextUtil.java:39)
 at  at ch.qos.logback.classic.joran.action.ConfigurationActio n.begin(ConfigurationAction.java:47)
 at  at ch.qos.logback.core.joran.spi.Interpreter.callBeginAct ion(Interpreter.java:273)
 at  at ch.qos.logback.core.joran.spi.Interpreter.startElement (Interpreter.java:145)
 at  at ch.qos.logback.core.joran.spi.Interpreter.startElement (Interpreter.java:127)
 at  at ch.qos.logback.core.joran.spi.EventPlayer.play(EventPl ayer.java:40)
 at  at ch.qos.logback.core.joran.spi.Interpreter.play(Interpr eter.java:332)
 at  at ch.qos.logback.core.joran.GenericConfigurator.doConfig ure(GenericConfigurator.java:126)
 at  at ch.qos.logback.core.joran.GenericConfigurator.doConfig ure(GenericConfigurator.java:93)
 at  at ch.qos.logback.core.joran.GenericConfigurator.doConfig ure(GenericConfigurator.java:52)
 at  at ch.qos.logback.classic.util.ContextInitializer.configu reByResource(ContextInitializer.java:77)
 at  at ch.qos.logback.classic.util.ContextInitializer.autoCon fig(ContextInitializer.java:150)
 at  at org.slf4j.impl.StaticLoggerBinder.init(StaticLoggerBin der.java:85)
 at  at org.slf4j.impl.StaticLoggerBinder.<clinit>(StaticLogge rBinder.java:55)
 at  at org.slf4j.LoggerFactory.bind(LoggerFactory.java:121)
 at  at org.slf4j.LoggerFactory.performInitialization(LoggerFa ctory.java:111)
 at  at org.slf4j.LoggerFactory.getILoggerFactory(LoggerFactor y.java:268)
 at  at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java: 241)
 at  at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java: 254)
 at  at com.teradata.fnc.JarManager.<clinit>(JarManager.java: 61)
 at  at com.teradata.fnc.JavaPtest.<clinit>(JavaPtest.java: 269)
08:33:54,952 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - About to instantiate appender of type [ch.qos.logback.core.ConsoleAppender]
08:33:54,955 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - Naming appender as [stdout]
08:33:54,985 |-INFO in ch.qos.logback.classic.joran.action.LevelAction - ROOT level set to OFF
08:33:54,985 |-INFO in ch.qos.logback.core.joran.action.AppenderRefAction - Attaching appender named [stdout] to Logger[ROOT]
java.lang.ClassNotFoundException: Parser
 at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
 at java.security.AccessController.doPrivileged(Native Method)
 at java.net.URLClassLoader.findClass(URLClassLoader.java: 190)
 at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
 at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
 at com.teradata.fnc.JarURLLoader.locateClass(JarURLLoader .java:138)
 at com.teradata.fnc.JarManager.checkClass(JarManager.java :291)
 at com.teradata.fnc.JarManager.checkMethod(JarManager.jav a:227)
 at com.teradata.fnc.JavaPtest.main(JavaPtest.java:373)
+---------+---------+---------+---------+---------+--- ------+---------+----
 *** Warning: EOF on INPUT stream.
 *** BTEQ exiting due to EOF on stdin.
 *** Exiting BTEQ...
 *** RC (return code) = 0
We compiled with (on Linux TD node):
javac -target 1.6 -classpath /home/tdatuser/java/commons-collections-3.2.1.jar:/ home/tdatuser/java/snakeyaml-1.10.jar:/home/tdatuser/ java/javFnc.jar CachingParser.java Client.java Device.java DeviceParser.java OS.java OSParser.java Parser.java UserAgent.java UserAgentParser.java
 
 
We have several files, but the ua_parser/Parser.class file comes from the Parser.java file (and it just contains the public class Parser) :
------------------------------------------------------ ------------------------------------------------------ --------------
package ua_parser;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Map;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.constructor.SafeConstructor;
/**
 * Java implementation of <a href="https://github.com/tobie/ua-parser">UA Parser</a>
 *
 * @author Steve Jiang (@sjiang) <gh at iamsteve com>
 */
public class Parser {
  private static final String REGEX_YAML_PATH = "/ua_parser/regexes.yaml";
  private UserAgentParser uaParser;
  private OSParser osParser;
  private DeviceParser deviceParser;
  public Parser() throws IOException {
    this(Parser.class.getResourceAsStream(REGEX_YAML_PATH) );
  }
  public Parser(InputStream regexYaml) {
    initialize(regexYaml);
  }
  public Client parse(String agentString) {
    UserAgent ua = parseUserAgent(agentString);
    OS os = parseOS(agentString);
    Device device = deviceParser.parse(agentString);
    return new Client(ua, os, device);
  }
  public UserAgent parseUserAgent(String agentString) {
    return uaParser.parse(agentString);
  }
  public Device parseDevice(String agentString) {
    return deviceParser.parse(agentString);
  }
  public OS parseOS(String agentString) {
    return osParser.parse(agentString);
  }
  private void initialize(InputStream regexYaml) {
    Yaml yaml = new Yaml(new SafeConstructor());
    @SuppressWarnings("unchecked")
    Map<String,List<Map<String,String>>> regexConfig = (Map<String,List<Map<String,String>>>) yaml.load(regexYaml);
    List<Map<String,String>> uaParserConfigs = regexConfig.get("user_agent_parsers");
    if (uaParserConfigs == null) {
      throw new IllegalArgumentException("user_agent_parsers is missing from yaml");
    }
    uaParser = UserAgentParser.fromList(uaParserConfigs);
    List<Map<String,String>> osParserConfigs = regexConfig.get("os_parsers");
    if (osParserConfigs == null) {
      throw new IllegalArgumentException("os_parsers is missing from yaml");
    }
    osParser = OSParser.fromList(osParserConfigs);
    List<Map<String,String>> deviceParserConfigs = regexConfig.get("device_parsers");
    if (deviceParserConfigs == null) {
      throw new IllegalArgumentException("device_parsers is missing from yaml");
    }
    deviceParser = DeviceParser.fromList(deviceParserConfigs);
  }
}
------------------------------------------------------ ------------------------------------------------------ --------------
 
Who can help here ? We are looking for a Java UDF expert ..
 

Tags:
tomnolan 594 posts Joined 01/08
24 Sep 2014

Your Parser class has a package statement at the top: package ua_parser;
 
You will need to specify the fully-qualified package+class name in the EXTERNAL NAME clause of the CREATE FUNCTION command. Try this:
 
CREATE FUNCTION ua_family (agentString CHAR(30))
RETURNS CHAR(30)
LANGUAGE JAVA
NO SQL
PARAMETER STYLE JAVA
CALLED ON NULL INPUT
EXTERNAL NAME 'UA_Jar:ua_parser.Parser.parseUserAgent(java.lang.String) returns java.lang.String';
 

teraJava 4 posts Joined 08/12
09 Mar 2015

I am getting the same error when migrating an existing java UDF on TD version 14 to TD version 15. Has anything changed in they way EXTERNAL NAME parameter of replace function is specified? Here is what I am using, I have replaced variable names with generic names below. I did a show function on the version 14 database where this is already installed and tried to run it on the version 15.

REPLACE FUNCTION "SYSLIB"."UDFName" (

"var1" VARCHAR(100),

"var2" VARCHAR(2000),

"var3" VARCHAR(2000),

"var4" VARCHAR(250),

"var5" VARCHAR(5000))

RETURNS VARCHAR(200) CHARACTER SET LATIN

SPECIFIC "specFunName"

LANGUAGE JAVA

NO SQL

NO EXTERNAL DATA

PARAMETER STYLE JAVA

DETERMINISTIC

RETURNS NULL ON NULL INPUT

EXTERNAL NAME 'JarId:package.classname.functionname(java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String)returns java.lang.String';

The Error is

Failed [7980 : HY000] A JAVA method in the specified Jar which matches that in the EXTERNAL NAME clause was not found.

Where exactly are the jar files stored on the nodes? as last option I am thinking of trying with downloading the jar file from the TD version 14 database and using it instead of using the jar file on local client.
Thanks in advance.

You must sign in to leave a comment.