Support Questions

Find answers, ask questions, and share your expertise
Announcements
Celebrating as our community reaches 100,000 members! Thank you!

NoClassDefFoundError: net/sf/json/JSONObject

avatar
Contributor

Hi,

I've been trying to run an update processor script for nifi using Groovy. I am reusing the below script from Github.

import groovy.json.JsonBuilder
import groovyx.net.http.RESTClient

import static groovy.json.JsonOutput.prettyPrint
import static groovy.json.JsonOutput.toJson
import static groovyx.net.http.ContentType.JSON

//@Grab(group='org.codehaus.groovy.modules.http-builder',
     //   module='http-builder',
        //version='0.7.1')

def processorName = 'Save File'
def host = 'localhost'
//def host = 'agrande-nifi-1'
def port = 9090
def nifi = new RESTClient("http://$host:$port/nifi-api/")

println 'Looking up a component to update...'
def resp = nifi.get(
    path: 'controller/search-results',
    query: [q: processorName]
)
assert resp.status == 200
assert resp.data.searchResultsDTO.processorResults.size() == 1
// println prettyPrint(toJson(resp.data))

def processorId = resp.data.searchResultsDTO.processorResults[0].id
def processGroup= resp.data.searchResultsDTO.processorResults[0].groupId
println "Found the component, id/group:  $processorId/$processGroup"

println 'Preparing to update the flow state...'
resp = nifi.get(path: 'controller/revision')
assert resp.status == 200

// stop the processor before we can update it
println 'Stopping the processor to apply changes...'
def builder = new JsonBuilder()
builder {
    revision {
        clientId 'my awesome script'
        version resp.data.revision.version
    }
    processor {
        id "$processorId"
        state "STOPPED"
    }
}
resp = nifi.put(
    path: "controller/process-groups/$processGroup/processors/$processorId",
    body: builder.toPrettyString(),
    requestContentType: JSON
)
assert resp.status == 200
// create a partial JSON update doc
// TIP: don't name variables same as json keys, simplifies your life
builder {
    revision {
        clientId 'my awesome script'
        version resp.data.revision.version
    }
    processor {
        id "$processorId"
        config {
            properties {
                'Directory' '/tmp/staging'
                'Create Missing Directories' 'true'
            }
        }
    }
}

println "Updating processor...\n${builder.toPrettyString()}"

resp = nifi.put(
    path: "controller/process-groups/$processGroup/processors/$processorId",
    body: builder.toPrettyString(),
    requestContentType: JSON
)
assert resp.status == 200

println "Updated ok."
// println "Got this response back:"
// print prettyPrint(toJson(resp.data))
println 'Bringing the updated processor back online...'
builder {
    revision {
        clientId 'my awesome script'
        version resp.data.revision.version
    }
    processor {
        id "$processorId"
        state "RUNNING"
    }
}
resp = nifi.put(
    path: "controller/process-groups/$processGroup/processors/$processorId",
    body: builder.toPrettyString(),
    requestContentType: JSON
)
assert resp.status == 200

println 'Ok'

Except i have commented out the Maven dependency part using @Grab part. I have directly download the http-builder-0.6.jar and put it into groovy designated Library directory to have the classes available. I have also downloaded and put the json-lib.jar in the library.

I'm still getting below exception at run-time

groovyx.net.http.ContentType.JSON

Caught: java.lang.NoClassDefFoundError: net/sf/json/JSONObject

java.lang.NoClassDefFoundError: net/sf/json/JSONObject

at groovyx.net.http.HTTPBuilder.<init>(HTTPBuilder.java:175)

at groovyx.net.http.HTTPBuilder.<init>(HTTPBuilder.java:194)

at groovyx.net.http.RESTClient.<init>(RESTClient.java:79)

at Groovy_Sample.run(Groovy_Sample.groovy:13)

Caused by: java.lang.ClassNotFoundException: net.sf.json.JSONObject

I cant trace out whats possibly going wrong, even with the jars in library, I have read that setting the right version in Maven dependency might help, but I dont use it, is there no way to do it without Maven? OR am i missing something with the Jar and libraries.

1 ACCEPTED SOLUTION

avatar
Master Guru

You can provide additional dependencies to the ExecuteScript processor by using the "Module Directory" property as described here:

http://funnifi.blogspot.com/2016/02/executescript-using-modules.html

You generally shouldn't put any jars into NiFi's lib directory because that can impact all other NARs.

View solution in original post

7 REPLIES 7

avatar

Can you please try putting your jars under <nifi_home>/lib dir.

avatar
Super Guru
@sam coderunner

According to following link, json-lib requires additional dependencies in your class path including groovy-all.jar. do you have these depndencies in your classpath?

http://json-lib.sourceforge.net/dependencies.html

avatar
Master Guru

You can provide additional dependencies to the ExecuteScript processor by using the "Module Directory" property as described here:

http://funnifi.blogspot.com/2016/02/executescript-using-modules.html

You generally shouldn't put any jars into NiFi's lib directory because that can impact all other NARs.

avatar
Master Guru

Absolutely correct! If you were to add any jars to lib/ it would be only the Apache Ivy JAR so you could use the @Grab annotation as described here: http://funnifi.blogspot.com/2016/05/using-groovy-grab-with-executescript.html. Otherwise, use Bryan's suggestion for best results.

avatar
Contributor

Hi Matt,

thanks for your comments, I followed what you said and downloaded the Apache Ivy Jar named : "ivy-2.4.0.jar" from http://ant.apache.org/ivy/download.cgi and put it under in $NIFI_HOME/lib folder and the restarted the NIFI service. As you highlighted, i should be able to use the grab annotation now.

@Grab(group='org.codehaus.groovy.modules.http-builder',

module='http-builder',

version='0.7.1')

So in the script i have un-commented the @Grab part and ran it from command line with groovysh. Now i'm getting the below error after executing the script. The error is in attached file. error.txt

Is some configuration still missing, i read your blog post to know that it has something to do with the Grape cache and we need to configure it correctly? I could see that there is no /grapes folder under the /groovy directory

avatar
Master Guru

Do you have Groovy installed on your machine? If so try:

grape install org.codehaus.groovy.modules.http-builder http-builder 0.7.1

If that doesn't work, then the @Grab won't work either (lots of folks seem to have trouble grabbing that module). In that case you should put the http-builder JAR (and its dependencies) into some folder and use Module Directory as Bryan suggested.

avatar
Contributor

@Matt Burgess It worked! I tried with grape install command from command line and it popped some messages which stated that the jars are found in library. Now i can see a .groovy/grapes folder in documents which has the appropriate jar files! I ran the scripts thereafter and it successfully updated the processor properties as expected. I guess its now resolving the missing jar file paths on its own since the install. However I also noticed that having the @Grab part active or not doesn't matter to the code anymore.

Much appreciated and thanks a ton to you and Bryan for the most valuable inputs!