NoClassDefFoundError: opennlp/tools/chunker/ChunkerModel - java

Got this error while trying opennlp chunking:
NoClassDefFoundError: opennlp/tools/chunker/ChunkerModel
Here is the basic code:
import java.io.*;
import opennlp.tools.chunker.*;
public class test{
public static void main(String[] args) throws IOException{
ChunkerModel model = null;
InputStream modelIn = new FileInputStream("en-parser-chunking.bin");
model = new ChunkerModel(modelIn);
}
}

I don't see any NLP-specific reasons here, so just check tutorials about NoClassDefFoundError, for example:
Verify that all required Java classes are included in the
application’s classpath. The most common mistake is not to include all
the necessary classes, before starting to execute a Java application
that has dependencies on some external libraries.
The classpath of the
application is correct, but the Classpath environment variable is
overridden before the application’s execution."
or related question.
In particular, check that you have appropriate (and only one) version of opennlp jar in your classpath.
*it is not a good style to import all content of the package (by using wildcard) - instead, use IDE's support: e.g. ctrl+shift+o in Eclipse (ctrl+alt+o in IDEA) automatically resolves all needed imports.

Related

How to fix "The package org.neuroph.core is not accessible" in Java

I would like to use the Neuroph Library to add a Neural Network to my application. How do I correctly include the library in my project, import it, and use it?
I am new to Eclipse
I've added it the necessary JARs as an external library to my project's build path.
import org.neuroph.core.*;
public class ChatBotCore {
public static void main(String[] args) {
//No code regarding Neuroph work due to import issues.
}
}
I expected the import to work correctly however I got "The package org.neuroph.core is not accessible"

MarkLogic using JavaAPI

I have been trying a normal Java API using the same example as mentioned in this page. I had to download various JARs:
java-client-api-3.0.7.jar
slf4j-api-1.7.25.jar
com.fasterxml.jackson.databind.jar
jackson-core-2.2.0-rc1.jar
apache-httpcomponents-httpclient.jar
javax.ws.rs.jar
It still gives me NoClassDefFoundError on
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/http/params/HttpParams at com.marklogic.client.DatabaseClientFactory.newClientImpl(DatabaseClientFactory.java:322)
My Code:
import com.marklogic.client.DatabaseClient;
import com.marklogic.client.DatabaseClientFactory;
import com.marklogic.client.document.*;
import com.marklogic.client.io.*;
public class JavaML {
public static void main(String args[]) {
System.out.println("Here");
DatabaseClient client =
DatabaseClientFactory.newClient(
"localhost", 8000,"admin", "######",
DatabaseClientFactory.Authentication.DIGEST);
JSONDocumentManager docMgr = client.newJSONDocumentManager();
docMgr.write("/afternoon-drink",
new StringHandle("{name: \"Iced Mocha\", size: \"Grandé\", tasty: true}"));
String doc = docMgr.read("/afternoon-drink", new StringHandle()).get();
//System.out.println(doc);
}
}
Run:
javac -cp .;%CLASSES% JavaML.java
java -cp .;%CLASSES% JavaML
%CLASSES% - path to all the jars mentioned above.
Please help - am I missing something? Or is it a mandate that I have to download all these JARs?
It appears from the error message that you are missing the httpcore-4.1.jar.
However, there are a number of other dependencies that you are likely to be missing as well.
If you are maintaining your own set of dependencies and building your classpath manually, then you should download the Java API zip, which includes all of the necessary dependencies in the /lib directory.
However, it would be much easier if you were to use a build/dependency management tool, such as Gradle or Maven. If you have the Java API as a dependency, it will download all of it's dependencies and will compile your application with the necessary libraries on your classpath. It makes upgrades much easier, facilitates automation, and is a best practice in favor of manually collecting and organizing dependencies.

Changing the Priority of Java Classloaders

It's possible this has already been asked, but if so I've been unable to find it.
The Ask
Is there a way in Java 1.7/1.8, short of implementing a custom classloader, to make the application classpath higher-priority (loaded earlier) than the extension classpath?
The Issue
We have a platform with multiple apps using Apache's log4j library. We also have a custom JCA security provider installed in [jre]/lib/ext which also uses log4j. In order to do so, log4j has to be installed along with the provider in the ext directory.
One of the apps on the platform (Apache's activemq) relies on an older version of log4j/slf4j than the provider's. And since the provider's log4j jars are in [jre]/lib/ext, they override activemq's, causing a NoSuchMethodError to occur:
java.lang.NoSuchMethodError: org.slf4j.spi.LocationAwareLogger.log(Lorg/slf4j/Marker;Ljava/lang/String;ILjava/lang/String;Ljava/lang/Throwable;)V
So is there a way to make the jars in the application classpath supersede the extension directory?
Reproduction
You can reproduce this issue by installing these jars into [jre]/lib/ext:
log4j-1.2.17.jar
slf4j-api-1.7.2.jar
slf4j-log4j12-1.7.2.jar
And by installing these jars in the application classpath:
log4j-1.2.14.jar
slf4j-api-1.5.11.jar
slf4j-log4j12-1.5.11.jar
And by running this code:
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import org.slf4j.LoggerFactory;
import org.slf4j.spi.LocationAwareLogger;
public class LogApp {
public final static LocationAwareLogger logger =
(LocationAwareLogger) LoggerFactory.getLogger(LogApp.class);
public static void main(String[] args) throws NoSuchAlgorithmException {
// Make sure custom security provider has been initialized.
SecureRandom rand = SecureRandom.getInstanceStrong();
rand.doubles();
//ClassLoader cl = ClassLoader.getSystemClassLoader();
LogApp.logger.error("error: {}: {}", "string", new Exception());
LogApp.logger.log(null, LogApp.class.getCanonicalName(),
logger.ERROR_INT, "some message", new Exception());
}
}
Which should generate this error:
Exception in thread "main" java.lang.NoSuchMethodError: org.slf4j.spi.LocationAwareLogger.log(Lorg/slf4j/Marker;Ljava/lang/String;ILjava/lang/String;Ljava/lang/Throwable;)V
at LogApp.main(LogApp.java:23)
Answer
Run Java with this parameter:
-Xbootclasspath/p:[path_to_app_libs]/log4j-1.2.14.jar:[path_to_app_libs]/slf4j-api-1.5.11.jar:[path_to_app_libs]/slf4j-log4j12-1.5.11.jar
If you have control how your java is run, you can use -Xbootclasspath/a:path/to/your.jar to force loading specific jar ahead of extensions.
Upgrading log4j in lib/ext might be easier solution. Hopefully, whatever requires log4j in lib/ext will survive newer version, otherwise, you will have issues in any case, as bootclasspath will take precedence and force your lib/ext code to use new version.
In any case, having libraries with specific versions of log4j is bad pratice. Anything but final application, should probably use slf4j without specific binding, or possibly JUL.

How to use GeoScript groovy library inside Java project?

I have spring/postgis service with some spatial capabilities, but I haven't found Java library that can interpolate point to a linestring.
I'd like to to use this geoscript library to do that, but I'm not sure how to do that.
I've read about how to dynamically load groovy class in Java code, but I'm not sure how to do that with external library code. Should I just add this geoscript to build.gradle?
Or maybe there is some more efficient ways to do that?
I just gave it a try and it worked flawlessly. In the end a compiled Groovy library is just Java byte code.
Citing from Groovy in Action, Chapter 1.1.2 Playing nicely with Java: seamless integration:
Groovy is only
a new way of creating ordinary Java classes—
from a runtime perspective, Groovy is Java
with an additional JAR file as a dependency.
So add these dependencies
compile 'org.codehaus.groovy:groovy-all:2.4.5'
compile 'org.geoscript:geoscript-groovy:1.6.0'
and this repository
maven {
url "http://repo.boundlessgeo.com/main"
}
to your gradle build file and you are good to go.
This is the Java code I tried:
import geoscript.geom.LineString;
import geoscript.geom.Point;
public class Main {
public static void main(String[] args) {
LineString line = new LineString(new Point(1,2), new Point(3,4), new Point(4,5));
Point point = line.interpolatePoint(0.5);
System.out.println(point); // printed POINT (2.5 3.5)
}
}

Supplying a different version of JAXB for JAX-WS in Java 1.6

I have a third party jar that ships with a jaxb-impl.jar and includes it in its manifest classpath. The problem is, it seems as though supplying your own version of JAXB (regardless of which version it may be) seems to break the SoapFaultBuilder in JAX-WS.
According to the Unofficial JAXB Guide, it seems as though Sun deliberately changed the package name when it folded JAXB into the JDK in order to avoid conflicts with the stand-alone version. However, the SoapFaultBuilder (part of JAX-WS I believe) that ships with the JDK is explicitly dependent on the new, internal package name. This causes it to fail when building a fault message if you've added a stand-alone JAXB jar (even if it is the same version number of JAXB).
Here is my small test case: I make a trivial Web Service:
package wstest;
import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.jws.soap.SOAPBinding.Style;
//Service Endpoint Interface
#WebService
#SOAPBinding(style = Style.RPC)
public interface HelloWorld{
#WebMethod String getHelloWorldAsString(String name);
}
And an implementation that simply throws an exception. (Since the problem only occurs in the SOAPFaultBuilder):
package wstest;
import javax.jws.WebService;
//Service Implementation
#WebService(endpointInterface = "wstest.HelloWorld")
public class HelloWorldImpl implements HelloWorld{
#Override
public String getHelloWorldAsString(String name) {
//return "Hello World JAX-WS " + name;
throw new RuntimeException("Exception for: " + name);
}
}
And a class to publish the web service:
package wstest;
import javax.xml.ws.Endpoint;
//Endpoint publisher
public class HelloWorldPublisher{
public static void main(String[] args) {
Endpoint.publish("http://localhost:9999/ws/hello", new HelloWorldImpl());
}
}
I run the HelloWorldPublisher, and then run this client against it:
package wstest;
import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;
public class HelloWorldClient{
public static void main(String[] args) throws Exception {
URL url = new URL("http://localhost:9999/ws/hello?wsdl");
//1st argument service URI, refer to wsdl document above
//2nd argument is service name, refer to wsdl document above
QName qname = new QName("http://wstest/", "HelloWorldImplService");
Service service = Service.create(url, qname);
HelloWorld hello = service.getPort(HelloWorld.class);
System.out.println(hello.getHelloWorldAsString("Matt"));
}
}
This correctly spits out the exception that was thrown by the Web Service. However, when I add any version of jaxb-impl.jar, whether on the classpath or in the endorsed lib, I get this stack trace:
Exception in thread "main" java.lang.ExceptionInInitializerError
at com.sun.xml.internal.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:107)
at com.sun.xml.internal.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:78)
at com.sun.xml.internal.ws.client.sei.SEIStub.invoke(SEIStub.java:107)
at $Proxy19.getHelloWorldAsString(Unknown Source)
at wstest.HelloWorldClient.main(HelloWorldClient.java:21)
Caused by: java.lang.ClassCastException: com.sun.xml.bind.v2.runtime.JAXBContextImpl cannot be cast to com.sun.xml.internal.bind.api.JAXBRIContext
at com.sun.xml.internal.ws.fault.SOAPFaultBuilder.<clinit>(SOAPFaultBuilder.java:533)
... 5 more
The exception occurs because com.sun.xml.bind.v2.runtime.JAXBContextImpl from my jaxb-impl extends com.sun.xml.bind.api.JAXBRIContext instead of com.sun.xml.internal.bind.api.JAXBRIContext (note the missing 'internal' sub-package in the package hierarchy).
Also according to the Unofficial JAXB Guide, they say you need to use endorsed lib in order to correctly override the version of JAXB. As it turns out though, SOAPFaultBuilder uses JAXBContext.newInstance() to search the classpath for a file named /META-INF/services/javax.xml.bind.JAXBContext, then manually load (and reflexively create) a JAXBContext based on the class name specified in the file. So it doesn't matter - classpath or endorsed lib gives you the same behavior.
One workaround is to add -Djavax.xml.bind.JAXBContext=com.sun.xml.internal.bind.v2.ContextFactory to the command line, which causes JAXBContext.newInstance() to ignore the /META-INF/services/javax.xml.bind.JAXBContext file on the classpath and manually specifies the built-in version of JAXB. The other workaround is to simply not specify your own JAXB and use the version built into the JDK, but it seems from the Unofficial JAXB Guide, that Sun designed this system to be able to handle supplying your own JAXB implementation. Has anyone been able to successfully supply a version of JAXB and still be able to successfully capture fault messages? (Everything runs fine for me as long as there are no faults generated by the Web Service).
I was stuck on this problem but was able to use the "work around" listed in this forum Q&A by setting a system property like so:
System.setProperty("javax.xml.bind.JAXBContext",
"com.sun.xml.internal.bind.v2.ContextFactory");
The crux of this issue is there is a change in the JAXB API, the runtime implementation you are attempting to use does not match the version of the JAXB API bundled with the JDK.
In order to use a different version, you should copy coresponding versions of jaxb-api.jar and jaxws-api.jar into an endorsed lib (e.g. %JAVA_HOME%\lib\endorsed).
A complete list of options is given in section 7.1.2 of the Unofficial JAXB Guide
It is a mistake to copy the implementation jars (e.g. jaxb-impl.jar) into endorsed lib, these should simply be on your classpath.
Also note that you can get into trouble if you attempt to use a newer version of jaxb without also including a compatible version of jaxws. This is because the old jaxws attempts to reference the old jaxb, so if you're changing one make sure you do both. (Stack-trace in package com.sun.xml.internal.ws implicates an old jax-ws implementation. Even the latest release of Java still ships with old version 1 jaxb and jaxws apis).
another possible solution without modifying the system properties is described at API docu
https://docs.oracle.com/cd/E17802_01/webservices/webservices/docs/1.6/api/javax/xml/bind/JAXBContext.html
you can place a jaxb.properties file inside of the package of your model class.
javax.xml.bind.context.factory=com.sun.xml.internal.bind.v2.ContextFactory

Categories

Resources