Hive custom UDF class not found issue - java

I was building my UDF as below:
test_udf.java
package test;
import org.apache.commons.lang.StringUtils;
import org.apache.hadoop.hive.ql.exec.UDF;
import org.apache.hadoop.io.Text;
public class Strip extends UDF{
private Text result = new Text();
public Text evaluate(Text str){
if ( str == null){
return null;
}
result.set(StringUtils.strip(str.toString()));
return result;
}
public Text evaluate(Text str,String stripChars){
if ( str == null){
return null;
}
result.set(StringUtils.strip(str.toString(),stripChars));
return result;
}
}
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>sdf.dennis.com</groupId>
<artifactId>test_udf</artifactId>
<version>1.0</version>
<name>hive</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.hive</groupId>
<artifactId>hive-exec</artifactId>
<version>2.1.1</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
<version>3.0.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.2</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
I used command mvn clean package. Then a test_udf-1.0.jar was generated in target folder.
However, I added the jar file into hive and create a temporary function, it showed:
hive> add jar file:///home/dennis/java/target/test_udf-1.0.jar;
Added [file:///home/dennis/java/target/test_udf-1.0.jar] to class path
Added resources: [file:///home/dennis/java/target/test_udf-1.0.jar]
hive> create temporary function test_s as 'test.strip';
FAILED: Class test.strip not found
FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.FunctionTask
hive> create temporary function test_s as 'test.Strip';
FAILED: Class test.Strip not found
FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.FunctionTask
I can't figure out what the mistake I made?
unziped files:
about_files groovyjarjarantlr jodd module.properties plugin.properties
about.html groovyjarjarasm junit mozilla plugin.xml
antlr groovyjarjarcommonscli keytab.txt net properties.dtd
assets hdfs-default.xml krb5-template.conf org PropertyList-1.0.dtd
au hive-exec-log4j2.properties krb5_udp-template.conf org-apache-calcite-jdbc.properties schema
ccache.txt hive-log4j2.properties license org.apache.hadoop.application-classloader.properties shaded
codegen images LICENSE.txt org.codehaus.commons.compiler.properties stylesheet.css
com javaewah log4j2.component.properties overview.html templates
common-version-info.properties javax Log4j-config.xsd overviewj.html testpool.jocl
core-default.xml javolution Log4j-events.dtd package.jdo tez-container-log4j2.properties
fr jersey Log4j-events.xsd parquet webapps
google jetty-dir.css Log4j-levels.xsd parquet-logging.properties yarn-default.xml
groovy jline META-INF parquet.thrift yarn-version-info.properties

May be try with Macros.
CREATE TEMPORARY MACRO fn_maskNull(input decimal(25,3))
CASE
WHEN input IS NULL THEN 0 else input
END;
-- usage
select fn_maskNull(null), fn_maskNull(101);
More info : https://medium.com/#gchandra/create-user-defined-functions-in-hive-beeline-ff965285d735

Related

Weka Filter class is not found

Writing code on Eclipse with Weka. Trying to use the weka.filters.Filter method but I constantly receive this error:
java.lang.NoClassDefFoundError: weka/filters/Filter
Everything else seems to be imported right and I see the filter class in the Package Exploration.
Thank you to everyone in advance
Haven't used Eclipse in a long time, as I prefer IntelliJ IDEA.
Here is what I did:
Create a new workspace
Create a new Java project
Unchecked Create module-info.java and clicked on Next
Added my external weka.jar under Classpath and clicked on Finish:
Created class Testing.java in package myweka with this content:
package myweka;
import weka.filters.Filter;
import weka.filters.MultiFilter;
public class Testing {
public static void main(String[] args) throws Exception {
Filter f = new MultiFilter();
System.out.println(f);
}
}
Here it is what it looks like in Eclipse:
Executed the class without problems (just outputs the classname in the console).
Instead of simply adding an external jar to your project, you could set up a Maven project. Here are the steps:
Create a new directory to house all your code
Create a file called pom.xml (Maven Project Object Model) and add this content (the libraries that are required for the project are listed inside the dependencies tag, this example uses Weka 3.9.5; the 3.8.5 dependency is commented out; you can only use either or):
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>MyGroup</groupId>
<artifactId>MyWeka</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>MyWeka</name>
<description>Project using Weka.</description>
<dependencies>
<!-- Weka 3.9.5 -->
<dependency>
<groupId>nz.ac.waikato.cms.weka</groupId>
<artifactId>weka-dev</artifactId>
<version>3.9.5</version>
</dependency>
<!-- Weka 3.8.5 -->
<!--dependency>
<groupId>nz.ac.waikato.cms.weka</groupId>
<artifactId>weka-stable</artifactId>
<version>3.8.5</version>
</dependency-->
</dependencies>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.3.2</version>
</plugin>
</plugins>
</build>
</project>
Create directory src/main/java/myweka in the same directory as the pom.xml file.
Place the following content as Testing.java in that directory:
package myweka;
import weka.filters.Filter;
import weka.filters.MultiFilter;
public class Testing {
public static void main(String[] args) throws Exception {
Filter f = new MultiFilter();
System.out.println(f);
}
}
Launch Eclipse and create a new workspace.
Import your project
Import the project as an Existing Maven Project
Select the directory where your pom.xml is located and click on Finish.
Once Eclipse has finished the import, you can execute the myweka.Testing class, which will just output the filter's classname in the console.

Program runs fine when I run in VSCode, but the package the maven extension builds doesn't run

Background: I am using VS Code and the VS Code Java extension pack (which includes a maven extension) to write a project that uses htmlunit. Currently, I'm just using someone else's code just to see if I can get my environment working. I am a total noob to maven and VS Code and a semi-noob to Java.
When I run my program using the VS Code run tab, it runs as expected*. When I use the maven package command to build an executable jar, the jar builds fine but when I run it with java -jar ___.jar I get an error:
Exception in thread "main" java.lang.NoClassDefFoundError: com/gargoylesoftware/htmlunit/FailingHttpStatusCodeException
at reliant.Main.main(Main.java:44)
Caused by: java.lang.ClassNotFoundException: com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
... 1 more
Here is the code that uses htmlunit:
package reliant; //I know now this is not how package naming conventions work, but I don't think it causes a problem
import java.io.IOException;
import com.gargoylesoftware.htmlunit.BrowserVersion;
import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException; //the import that seems to be buggy
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlForm;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
public class RedditClient {
private final WebClient CLIENT = new WebClient(BrowserVersion.CHROME);
private final String username;
private char[] password;
public RedditClient(String username, char[] password) {
this.username = username;
this.password = password;
CLIENT.getCookieManager().setCookiesEnabled(true);
}
public void checkLogin() {
System.out.println(username + ", " + new String(password));
}
public void login() {
String loginURL = "https://www.reddit.com/login";
try {
HtmlPage loginPage = CLIENT.getPage(loginURL);
HtmlForm loginForm = loginPage.getFirstByXPath("//form[#id='login-form']");
//System.out.println(loginPage.getWebResponse().getContentAsString());
loginForm.getInputByName("user").setValueAttribute(username);
loginForm.getInputByName("passwd").setValueAttribute(new String(password));
loginForm.getElementsByTagName("button").get(0).click();
} catch (FailingHttpStatusCodeException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public String getHTML(String url) {
try {
return CLIENT.getPage(url).getWebResponse().getContentAsString();
} catch (FailingHttpStatusCodeException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
public void close() {
CLIENT.close();
}
}
And here is line 44 of Main.java:
RedditClient c = new RedditClient(username, password);
This seems to look right to me, I added htmlunit to my maven dependencies. I can show you a screeenshot of the maven dependencies if you want, but I omitted it for now since it's kind of long/hard to read.
Here is the pom file:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>reliant</groupId>
<artifactId>redditlogin</artifactId>
<version>2.0</version>
<name>redditlogin</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>htmlunit</groupId>
<artifactId>htmlunit</artifactId>
<version>1.14</version>
</dependency>
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.13.1</version>
</dependency>
<dependency>
<groupId>net.sourceforge.htmlunit</groupId>
<artifactId>htmlunit</artifactId>
<version>2.41.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
<plugins>
<!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>reliant.Main</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
<!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
<plugin>
<artifactId>maven-site-plugin</artifactId>
<version>3.7.1</version>
</plugin>
<plugin>
<artifactId>maven-project-info-reports-plugin</artifactId>
<version>3.0.0</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
The fact that the jar file errors out but running in VS Code proceeds as expected* makes no sense to me whatsoever.
Also, on an unrelated note, why is a "class not found" error a run-time error? Why is maven able to successfully build the package?
*I say "as expected" because there is a bug in the code I'm using, but it is a very-specific runtime error. Basically, the code I'm using was designed to log in to reddit before reddit got the OAuth thing so now the line that tries to get the login form returns null and that breaks the rest of it. The point is, I see no reason for why running in VS Code vs running the jar should have any different outcomes. I don't even know where to begin with something like this.
Thank you for help, please let me know if there is anything I can add to make this question easier to answer.
Ok so turns out this was pretty silly. Basically, the classpath listed my dependencies (because of how I set up the pom) but that doesn't mean that it specified the path to those dependencies. In fact, it didn't specify a path at all, so whenever java tried to run the jar, it looked for the dependencies in the current directory. I know that because when I put the dependencies in the same directory as the jar, it worked. The better solution here would be to modify the pom to add a prefix to the classpath so that the java knows where to find the dependencies. Unfortunately, my dependencies are in different places so that's not really an option for me; instead, I'm going to try to find out how to make a fat/uber jar.

pmd import: Entry[import from realm ClassRealm[maven.api, parent: null]]

I am trying to add a custom rule written in java language to the pmd maven plugin.
I expected everything to work fine when executing pmd:check goal from IntelliJ 2016.3.2 Community Edition, but instead I get the following message.
execute goal org.apache.maven.plugins:maven-pmd-plugin:3.9.0:pmd (pmd) on project pmd-custom-rule-use: Execution pmd of goal org.apache.maven.plugins:maven-pmd-plugin:3.9.0:pmd failed: An API incompatibility was encountered while executing org.apache.maven.plugins:maven-pmd-plugin:3.9.0:pmd: java.lang.NoSuchMethodError: net.sourceforge.pmd.renderers.AbstractRenderer.(Ljava/lang/String;Ljava/lang/String;)V
--- here goes some of my .m2 jars listings ---
[ERROR] Number of foreign imports: 1
[ERROR] import: Entry[import from realm ClassRealm[maven.api, parent: null]]
The configuration of the plugin is
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-pmd-plugin</artifactId>
<dependencies>
<dependency>
<groupId>com.codingtogo</groupId>
<artifactId>pmd-custom-rule</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
<configuration>
<rulesets>
<ruleset>/myCustomRules/myRuleSet.xml</ruleset>
</rulesets>
<sourceEncoding>utf-8</sourceEncoding>
<targetJdk>1.7</targetJdk>
<excludes>
<exclude>**/*Bean.java</exclude>
<exclude>**/generated/*.java</exclude>
</excludes>
<excludeRoots>
<excludeRoot>target/generated-sources/stubs</excludeRoot>
</excludeRoots>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
</build>
The ruleset xml file is like
<?xml version="1.0"?>
<ruleset name="My custom rules"
xmlns="http://pmd.sf.net/ruleset/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://pmd.sf.net/ruleset/1.0.0
http://pmd.sf.net/ruleset_xml_schema.xsd"
xsi:noNamespaceSchemaLocation="http://pmd.sf.net/ruleset_xml_schema.xsd">
<rule name="WhileLoopsMustUseBracesRule"
message="Avoid using 'while' statements without curly braces"
class="com.codingtogo.WhileLoopsMustUseBracesRule">
<description>
Avoid using 'while' statements without using curly braces
</description>
<priority>3</priority>
<example>
<![CDATA[
public void doSomething() {
while (true)
x++;
}
]]>
</example>
</rule>
</ruleset>
The dependency of the plugin is the jar where the class referenced in the ruleset is defined. The pom configuration of that project is
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.codingtogo</groupId>
<artifactId>pmd-custom-rule</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<!-- https://mvnrepository.com/artifact/net.sourceforge.pmd/pmd -->
<dependency>
<groupId>net.sourceforge.pmd</groupId>
<artifactId>pmd</artifactId>
<version>5.0.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
And the class source code is
package com.codingtogo;
import net.sourceforge.pmd.lang.java.ast.ASTWhileStatement;
public class WhileLoopsMustUseBracesRule {
public Object visit(ASTWhileStatement node, Object data) {
System.out.println("hello world");
return data;
}
}
If I take the dependency from my jar from the pmd maven plugin out, then it runs and produces the error
[ERROR] Error instantiating a rule
java.lang.ClassNotFoundException: com.codingtogo.WhileLoopsMustUseBracesRule
and the build is successful. I pinpoint it because the initial error was an api incompatibility problem but, if I take the dependency from my jar out, then the api incompatibility error is gone.
Thanks in advance :)
--- EDIT [SOLVED] ---
The problem was that I was using the wrong dependency as pointed out by #Johnco. Also, I was using the wrong classes. This is the final setup.
package com.codingtogo;
import net.sourceforge.pmd.lang.java.ast.ASTWhileStatement;
import net.sourceforge.pmd.lang.java.rule.AbstractJavaRule;
public class WhileLoopsMustUseBracesRule extends AbstractJavaRule {
public Object visit(ASTWhileStatement node, Object data) {
System.out.println("hello world");
return data;
}
}
Note the extends class is now AbstractJavaRule and not AbstractRule.
<dependency>
<groupId>net.sourceforge.pmd</groupId>
<artifactId>pmd-java</artifactId>
<version>6.2.0</version>
</dependency>

Use ANTLR v4 runtime within eclipse plugin

Hello I am new in eclipse-plugin development and I am starting a project to incorporate a translator in an eclipse-plugin and for this purpose I started by using the eclipse plugin hello word example and the grammar file provided in this example, I am able to compile my project and run the plug in but when I try to load the parser I get an exception 'Caused by: java.lang.NoClassDefFoundError: org/antlr/v4/runtime/CharStream', I don't know what the problem could be, I have already tested the parser, but outside plug in environment and works fine.
I am also trying to incorporate maven to download the dependencies and run antlr so I added this in the pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.plugin.helloworld</groupId>
<artifactId>org.plugin.helloworld</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.antlr</groupId>
<artifactId>antlr4</artifactId>
<version>4.7.1</version>
</dependency>
</dependencies>
<build>
<defaultGoal>install</defaultGoal>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.antlr</groupId>
<artifactId>antlr4-maven-plugin</artifactId>
<version>4.7.1</version>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.antlr</groupId>
<artifactId>antlr4-maven-plugin</artifactId>
<version>4.7.1</version>
<configuration>
<sourceDirectory>src/evaluator</sourceDirectory>
<outputDirectory>src/evaluator</outputDirectory>
<visitor>true</visitor>
<listener>false</listener>
</configuration>
<executions>
<execution>
<id>antlr</id>
<goals>
<goal>antlr4</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
I am using the lexer and the parser as follows:
public class SampleHandler extends AbstractHandler {
#Override
public Object execute(ExecutionEvent event) throws ExecutionException {
IWorkbenchWindow window = HandlerUtil.getActiveWorkbenchWindowChecked(event);
CharStream in = CharStreams.fromString("\"12*(5-6)\"");
evaluatorLexer lexer = new evaluatorLexer(in);
CommonTokenStream tokens = new CommonTokenStream(lexer);
evaluatorParser parser = new evaluatorParser(tokens);
MessageDialog.openInformation(
window.getShell(),
"Helloworld",
parser.eval().toString());
return null;
}
}
And the referenced libraries like this:
I set the build.properties as follows
source.. = src/
output.. = bin/
bin.includes = plugin.xml,\
META-INF/,\
.,\
icons/,\
lib/antlr4-runtime-4.7.1.jar,\
lib/ST4-4.0.8.jar,\
lib/antlr4-4.7.1.jar,\
lib/antlr4-runtime-4.7.1-sources.jar
I read about adding as a bundle in the manifest but I can't find that option in the dependencies tab just the org.antlr.runtime not the v4.
You need to add the jars to the Bundle-Classpathin the MANIFEST.MF.
In the MANIFEST.MF editor do this on the 'Runtime' tab. In the 'Classpath' section click 'Add...' and add the jars, be sure to leave the '.' entry which represents your normal code.
Your Bundle-Classpath should end up looking something like:
Bundle-ClassPath: .,
lib/antlr4-runtime-4.7.1.jar,
lib/ST4-4.0.8.jar,
lib/antlr4-4.7.1.jar,
lib/antlr4-runtime-4.7.1-sources.jar

What's wrong with how I am using maven to build natty?

I am trying to use NATTY by including it as a maven dependency. I just did the Hello, World Maven tutorial -- but am otherwise unfamiliar with Maven. The instructions on the natty site say to include natty as a dependency in the pom.xml. I have done so like this
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>my-app</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.joestelmach</groupId>
<artifactId>natty</artifactId>
<version>0.9</version>
</dependency>
</dependencies>
</project>
I then run $mvn package and the project builds successfully. I see one jar file in my /target: my-app-1.0-SNAPSHOT.jar so I assume that the natty dependencies are baked into that jar.
To test, I create a simple class in a file called Temporary.java to hold the natty demo code:
import com.joestelmach.natty.*;
import com.joestelmach.natty.generated.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
public class Temporary{
public static void main(String [] args) {
Parser parser = new Parser();
List groups = parser.parse("the day before next thursday");
for (DateGroup group : groups) {
List dates = group.getDates();
int line = group.getLine();
int column = group.getPosition();
String matchingValue = group.getText();
String syntaxTree = group.getSyntaxTree().toStringTree();
Map parseMap = group.getParseLocations();
boolean isRecurreing = group.isRecurring();
Date recursUntil = group.getRecursUntil();
}
}
}
But when I run $ javac -cp target/my-app-1.0-SNAPSHOT.jar Temporary.java I get
Temporary.java:1: error: package com.joestelmach.natty does not exist
import com.joestelmach.natty.*;
What am I doing wrong?
You need to make sure that when you package your jar using maven that your dependencies are included.
I believe you need to add this to your pom.xml
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass></mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
Make sure when running it you use the .jar that has the "jar-with-dependencies.jar" at the end. This will ensure that your natty dependency is included.

Categories

Resources