error when compiling Java UDF

Extensibility
Teradata Employee

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.ConfigurationAction - 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.addHostNameAsProperty(ContextUtil.java:39)

 at  at ch.qos.logback.classic.joran.action.ConfigurationAction.begin(ConfigurationAction.java:47)

 at  at ch.qos.logback.core.joran.spi.Interpreter.callBeginAction(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(EventPlayer.java:40)

 at  at ch.qos.logback.core.joran.spi.Interpreter.play(Interpreter.java:332)

 at  at ch.qos.logback.core.joran.GenericConfigurator.doConfigure(GenericConfigurator.java:126)

 at  at ch.qos.logback.core.joran.GenericConfigurator.doConfigure(GenericConfigurator.java:93)

 at  at ch.qos.logback.core.joran.GenericConfigurator.doConfigure(GenericConfigurator.java:52)

 at  at ch.qos.logback.classic.util.ContextInitializer.configureByResource(ContextInitializer.java:77)

 at  at ch.qos.logback.classic.util.ContextInitializer.autoConfig(ContextInitializer.java:150)

 at  at org.slf4j.impl.StaticLoggerBinder.init(StaticLoggerBinder.java:85)

 at  at org.slf4j.impl.StaticLoggerBinder.<clinit>(StaticLoggerBinder.java:55)

 at  at org.slf4j.LoggerFactory.bind(LoggerFactory.java:121)

 at  at org.slf4j.LoggerFactory.performInitialization(LoggerFactory.java:111)

 at  at org.slf4j.LoggerFactory.getILoggerFactory(LoggerFactory.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.java: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 (2)
2 REPLIES
Teradata Employee

Re: error when compiling Java UDF

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';

Re: error when compiling Java UDF

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.