IBM-Cloud / java-cloudant

Sample Java application which uses Bluemix Cloudant NoSQL service.
Apache License 2.0
10 stars 23 forks source link

Is there a trick to getting this to run on locally in eclipse? #2

Closed Danwakeem closed 8 years ago

Danwakeem commented 8 years ago

This may be a silly question but I created a bluemix instance from the boilerplates section (which I am assuming is being generated from the code in this repo) and when the app deployed itself to bluemix it works fine. But when I try and run this app local I can not get it to work.

I created a local Liberty server and changed the VCAP_SERVICES string to a minified and escaped version of the vcap services in bluemix and I get strange errors when it gets to this line:

db = cloudant.database(databaseName, true);

One of the errors says 'Give up' and then says something about org.apache.cxf.interceptor.Fault: org/apache/commons/io/IOUtils

If you need more information or need me to include a stack trace I can but I am just curious if you could help me.

Thanks!

rvennam commented 8 years ago

The full stack trace will help...near the bottom, do you see any java.lang.NoClassDefFoundError ? If so, your server.xml doesn't have the right features (couchdb-1.0) and the application is failing due to a missing library.

To install the feature from the command line, type: bin/installUtility install couchdb-1.0

If you are installing into 8.5.5.5 or earlier and the feature supports that version, use the featureManager command, for example: bin/featureManager install couchdb-1.0 --when-file-exists=ignore Config Instructions

To use the feature at runtime add the following to your server.xml file

couchdb-1.0
Danwakeem commented 8 years ago

Yeah I am getting that NoClassDefFoundError!

That is strange though I added the exact same features that are listed on the bluemix liberty server that is deployed. I checked in the bluemix dashboard under runtimes > files > app > wlp > usr > servers > defaultServer > server.xml.

Anyway, here is the stack trace I am getting

[ERROR   ] Error occurred during error handling, give up!
org/apache/commons/io/IOUtils
[ERROR   ] SRVE0777E: Exception thrown by application class 'org.apache.cxf.interceptor.AbstractFaultChainInitiatorObserver.onMessage:116'
java.lang.RuntimeException: org.apache.cxf.interceptor.Fault: org/apache/commons/io/IOUtils
    at org.apache.cxf.interceptor.AbstractFaultChainInitiatorObserver.onMessage(AbstractFaultChainInitiatorObserver.java:116)
    at [internal classes]
Caused by: org.apache.cxf.interceptor.Fault: org/apache/commons/io/IOUtils
    at org.apache.cxf.service.invoker.AbstractInvoker.createFault(AbstractInvoker.java:163)
    ... 1 more
Caused by: java.lang.NoClassDefFoundError: org/apache/commons/io/IOUtils
    at com.cloudant.client.org.lightcouch.internal.CouchDbUtil.close(CouchDbUtil.java:134)
    at com.cloudant.client.org.lightcouch.CouchDbClient.execute(CouchDbClient.java:503)
    at com.cloudant.client.api.CloudantClient.executeRequest(CloudantClient.java:329)
    at com.cloudant.client.internal.views.ViewRequester.executeRequestWithResponseAsJson(ViewRequester.java:34)
    at com.cloudant.client.internal.views.ViewRequester.getResponseAsJson(ViewRequester.java:28)
    at com.cloudant.client.internal.views.ViewRequestImpl.getResponse(ViewRequestImpl.java:34)
    at com.cloudant.client.internal.views.AllDocsRequestResponse.getResponse(AllDocsRequestResponse.java:44)
    at example.nosql.ResourceServlet.get(ResourceServlet.java:119)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.ibm.ws.jaxrs20.server.LibertyJaxRsServerFactoryBean.performInvocation(LibertyJaxRsServerFactoryBean.java:651)
    ... 1 more

[ERROR   ] SRVE0315E: An exception occurred: java.lang.Throwable: java.lang.RuntimeException: org.apache.cxf.interceptor.Fault: org/apache/commons/io/IOUtils
    at com.ibm.ws.webcontainer.webapp.WebApp.handleRequest(WebApp.java:4983)
    at [internal classes]
Caused by: java.lang.RuntimeException: org.apache.cxf.interceptor.Fault: org/apache/commons/io/IOUtils
    at org.apache.cxf.interceptor.AbstractFaultChainInitiatorObserver.onMessage(AbstractFaultChainInitiatorObserver.java:116)
    ... 1 more
Caused by: org.apache.cxf.interceptor.Fault: org/apache/commons/io/IOUtils
    at org.apache.cxf.service.invoker.AbstractInvoker.createFault(AbstractInvoker.java:163)
    ... 1 more
Caused by: java.lang.NoClassDefFoundError: org/apache/commons/io/IOUtils
    at com.cloudant.client.org.lightcouch.internal.CouchDbUtil.close(CouchDbUtil.java:134)
    at com.cloudant.client.org.lightcouch.CouchDbClient.execute(CouchDbClient.java:503)
    at com.cloudant.client.api.CloudantClient.executeRequest(CloudantClient.java:329)
    at com.cloudant.client.internal.views.ViewRequester.executeRequestWithResponseAsJson(ViewRequester.java:34)
    at com.cloudant.client.internal.views.ViewRequester.getResponseAsJson(ViewRequester.java:28)
    at com.cloudant.client.internal.views.ViewRequestImpl.getResponse(ViewRequestImpl.java:34)
    at com.cloudant.client.internal.views.AllDocsRequestResponse.getResponse(AllDocsRequestResponse.java:44)
    at example.nosql.ResourceServlet.get(ResourceServlet.java:119)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.ibm.ws.jaxrs20.server.LibertyJaxRsServerFactoryBean.performInvocation(LibertyJaxRsServerFactoryBean.java:651)
    ... 1 more

I couldn't find a feature to add that mentioned apache commons io?

rvennam commented 8 years ago

For the missing apache commons libraries, you can create a shared library definition like:

 <couchdb id='cloudantNoSQLDB-rvennam-java-cloudant-cloudantNoSQLDB' jndiName='couchdb/rvennam-java-cloudant-cloudantNoSQLDB' libraryRef='cloudantNoSQLDB-library' username='${cloud.services.rvennam-java-cloudant-cloudantNoSQLDB.connection.username}' password='${cloud.services.rvennam-java-cloudant-cloudantNoSQLDB.connection.password}' url='${cloud.services.rvennam-java-cloudant-cloudantNoSQLDB.connection.url}' enableSSL='true' host='${cloud.services.rvennam-java-cloudant-cloudantNoSQLDB.connection.host}' port='${cloud.services.rvennam-java-cloudant-cloudantNoSQLDB.connection.port}'/>
    <library id='cloudantNoSQLDB-library'>
        <fileset id='cloudantNoSQLDB-fileset' dir='${server.config.dir}/lib' includes='commons-codec-1.6.jar commons-io-2.0.1.jar commons-logging-1.1.3.jar httpclient-4.3.6.jar httpclient-cache-4.3.6.jar httpcore-4.3.3.jar jackson-annotations-2.2.2.jar jackson-core-2.2.2.jar jackson-databind-2.2.2.jar jcl-over-slf4j-1.6.6.jar org.ektorp-1.4.2.jar slf4j-api-1.6.6.jar slf4j-jdk14-1.6.6.jar'/>
    </library>

and add those jars to the lib dir as done in the Bluemix app.

https://www.ibm.com/support/knowledgecenter/was_beta_liberty/com.ibm.websphere.wlp.nd.multiplatform.doc/ae/twlp_couchdb_config.html

OR

Temporarily, you can add the jars to the WEB-INF/lib dir of your application.

I will document this in the README

Danwakeem commented 8 years ago

I do have that part in my server.xml file.

Here is what that file looks like

<server>
    <featureManager>
        <feature>beanValidation-1.1</feature>
        <feature>cdi-1.2</feature>
        <feature>ejbLite-3.2</feature>
        <feature>el-3.0</feature>
        <feature>jaxrs-2.0</feature>
        <feature>jdbc-4.1</feature>
        <feature>jndi-1.0</feature>
        <feature>jpa-2.1</feature>
        <feature>jsf-2.2</feature>
        <feature>jsonp-1.0</feature>
        <feature>jsp-2.3</feature>
        <feature>managedBeans-1.0</feature>
        <feature>servlet-3.1</feature>
        <feature>websocket-1.1</feature>
        <feature>cloudant-1.0</feature>
        <feature>couchdb-1.0</feature>
        <feature>localConnector-1.0</feature>
    </featureManager>
    <cdi12 enableImplicitBeanArchives="false"/>
    <httpEndpoint host="*" httpPort="${port}" id="defaultHttpEndpoint"/>
    <webContainer extractHostHeaderPort="true" trustHostHeaderPort="true"/>
    <include location="runtime-vars.xml"/>
    <logging consoleLogLevel="INFO" logDirectory="${application.log.dir}"/>
    <httpDispatcher enableWelcomePage="false"/>
    <applicationMonitor dropinsEnabled="false" updateTrigger="mbean"/>
    <config updateTrigger="mbean"/>
    <couchdb enableSSL="true" host="${cloud.services.test-java-applet-cloudantNoSQLDB.connection.host}" id="cloudantNoSQLDB-test-java-applet-cloudantNoSQLDB" jndiName="couchdb/test-java-applet-cloudantNoSQLDB" libraryRef="cloudantNoSQLDB-library" password="${cloud.services.test-java-applet-cloudantNoSQLDB.connection.password}" port="${cloud.services.test-java-applet-cloudantNoSQLDB.connection.port}" url="${cloud.services.test-java-applet-cloudantNoSQLDB.connection.url}" username="${cloud.services.test-java-applet-cloudantNoSQLDB.connection.username}"/>
    <library id="cloudantNoSQLDB-library">
        <fileset dir="${server.config.dir}/lib" id="cloudantNoSQLDB-fileset" includes="commons-codec-1.6.jar commons-io-2.0.1.jar commons-logging-1.1.3.jar httpclient-4.3.6.jar httpclient-cache-4.3.6.jar httpcore-4.3.3.jar jackson-annotations-2.2.2.jar jackson-core-2.2.2.jar jackson-databind-2.2.2.jar jcl-over-slf4j-1.6.6.jar org.ektorp-1.4.2.jar slf4j-api-1.6.6.jar slf4j-jdk14-1.6.6.jar"/>
    </library>

    <webApplication contextRoot="JavaCloudantDBApp" id="JavaCloudantApp" location="JavaCloudantDBApp.war" name="JavaCloudantApp"/>
</server>
Danwakeem commented 8 years ago

Ahh okay adding those jar files to the WEB-INF/lib did the trick... Is there a reason commons-io is not included in that directory when you start a bluemix app from the boiler plate but the cloudant-client.jar is?

rvennam commented 8 years ago

While it might be a temporary solution, to avoid classloading conflicts, you should not provide the client driver JAR files in the WEB-INF/lib directory of your application.

The shared library route is the way to go.

Non-IBM apache jars are not included in the boilerplate.

rvennam commented 8 years ago

Use these commands to download the jars and copy them to your server lib dir:

# Download all the jars
mvn dependency:get -Dartifact=org.ektorp:org.ektorp:1.4.2

# Copy to liberty server lib directory
mvn dependency:copy-dependencies -f $HOME/.m2/repository/org/ektorp/org.ektorp/1.4.2/org.ektorp-1.4.2.pom -DoutputDirectory=$HOME/wlp/usr/servers/defaultServer/lib