Reputation: 9191
A small java program is throwing a java.lang.ClassNotFoundException: com.twilio.sdk.TwilioRestException
error when I try to call it from the CentOS 7 command line. I read other postings about this error in android apps being caused by the need for the twilio client jars instead of the twilio sdk jars, but this is not android. But this is a CentOS 7 server. The same java program works when called from within a webapp in a tomcat installation on the same server, which has the same jar files in its lib folder as this small program has in its dependencies folder shown below. So why am I getting a ClassNotFoundException
if the same jars are in the classpath? How can I resolve these ClassNotFoundException
s so that the small java program below can run properly?
Here is what the terminal says is located in the root directory of the small program:
[user@domain bin]$ cd /home/user/javacode/
[user@domain javacode]$ ls -al
total 12
drwxrwxr-x 4 user user 76 Aug 21 22:29 .
drwxr-xr-x. 6 user user 4096 Aug 21 21:20 ..
drwxrwxr-x 3 user user 24 Aug 21 22:32 bin
drwxrwxr-x 4 user user 87 Aug 22 02:36 dependencies
-rw-r--r-- 1 user user 1313 Aug 21 19:28 SendText.java
Similarly, the /bin
and /mainpackage
folders contain the following:
[user@domain javacode]$ cd /home/user/javacode/bin
[user@domain bin]$ ls -al
total 0
drwxrwxr-x 3 user user 24 Aug 21 22:32 .
drwxrwxr-x 4 user user 76 Aug 21 22:29 ..
drwxrwxr-x 2 user user 27 Aug 21 22:32 mainpackage
[user@domain bin]$ cd /home/user/javacode/bin/mainpackage
[user@domain mainpackage]$ ls -al
total 4
drwxrwxr-x 2 user user 27 Aug 21 22:32 .
drwxrwxr-x 3 user user 24 Aug 21 22:32 ..
-rw-rw-r-- 1 user user 1495 Aug 21 22:32 SendText.class
I compile the program as follows:
[user@domain javacode]$ javac -d bin -cp .:/home/user/javacode/dependencies/twilio-java-sdk-3.4.5.jar:/home/user/javacode/dependencies/httpcore-4.1.2.jar SendText.java
Note that the two jars in the javac
and java
commands above are the only two relevant ones in the tomcat installation in which this code works,
But when I run the program from the /bin
folder, it gives the following. (Note that xxxxxxxxxx
and HelloThere
are args
that go into String[] args
in the main method. xxxxxxxxxx
is a valid cell phone number to receive a text, and HelloThere
is the message.)
[user@domain mainpackage]$ cd /home/user/javacode/bin
[user@domain bin]$ java mainpackage.SendText xxxxxxxxxx HelloThere
Exception in thread "main" java.lang.NoClassDefFoundError: com/twilio/sdk/TwilioRestException
at java.lang.Class.getDeclaredMethods0(Native Method)
at java.lang.Class.privateGetDeclaredMethods(Class.java:2615)
at java.lang.Class.getMethod0(Class.java:2856)
at java.lang.Class.getMethod(Class.java:1668)
at sun.launcher.LauncherHelper.getMainMethod(LauncherHelper.java:494)
at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:486)
Caused by: java.lang.ClassNotFoundException: com.twilio.sdk.TwilioRestException
at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
... 6 more
I then double checked the list of jars in the dependencies folder and got the following (Note that I added extra jars below to rule out the possibility of missing jars, even though most of the below are not in the working tomcat installation):
[user@domain bin]$ cd /home/user/javacode/dependencies
[user@domain dependencies]$ ls -al
total 944
drwxrwxr-x 4 user user 4096 Aug 22 03:01 .
drwxrwxr-x 4 user user 76 Aug 21 22:29 ..
-rw-r--r-- 1 user user 433071 Aug 22 02:36 httpclient-4.2.3.jar
-rw-r--r-- 1 user user 40 Aug 22 02:36 httpclient-4.2.3.jar.sha1
-rw-r--r-- 1 user user 5911 Aug 22 02:36 httpclient-4.2.3.pom
-rw-r--r-- 1 user user 40 Aug 22 02:36 httpclient-4.2.3.pom.sha1
-rw-r--r-- 1 user user 181200 Aug 21 21:24 httpcore-4.1.2.jar
-rw-r--r-- 1 user user 98 Aug 22 02:31 m2e-lastUpdated.properties
-rw-r--r-- 1 user user 193 Aug 22 02:36 _remote.repositories
-rw-r--r-- 1 user user 165092 Aug 22 02:31 twilio-java-sdk-3.4.5.jar
-rw-r--r-- 1 user user 40 Aug 22 02:31 twilio-java-sdk-3.4.5.jar.sha1
-rw-r--r-- 1 user user 5113 Aug 22 02:31 twilio-java-sdk-3.4.5.pom
-rw-r--r-- 1 user user 40 Aug 22 02:31 twilio-java-sdk-3.4.5.pom.sha1
-rw-r--r-- 1 user user 129098 Aug 22 02:31 twilio-java-sdk-3.4.5-sources.jar
-rw-r--r-- 1 user user 40 Aug 22 02:31 twilio-java-sdk-3.4.5-sources.jar.sha1
For reference, the code of SendText.java
is:
package mainpackage;
import com.twilio.sdk.TwilioRestClient;
import com.twilio.sdk.TwilioRestException;
import com.twilio.sdk.resource.factory.MessageFactory;
import com.twilio.sdk.resource.instance.Message;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import java.util.ArrayList;
import java.util.List;
public class SendText {
public static final String ACCOUNT_SID = "arealsid";
public static final String AUTH_TOKEN = "arealtoken";
public static void main(String[] args) throws TwilioRestException {
TwilioRestClient client = new TwilioRestClient(ACCOUNT_SID, AUTH_TOKEN);
String to = args[0];
String body = args[1];
// Build a filter for the MessageList
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("Body", body));
params.add(new BasicNameValuePair("To", to));
params.add(new BasicNameValuePair("From", "+11234567654"));
MessageFactory messageFactory = client.getAccount().getMessageFactory();
Message message = messageFactory.create(params);
System.out.println(message.getSid());
}
}
Upvotes: 0
Views: 465
Reputation: 35018
In order for Java to use your dependencies, you have to specify the classpath:
[user@domain mainpackage]$ cd /home/user/javacode/bin
[user@domain bin]$ java -cp .:"../dependencies/*" mainpackage.SendText xxxxxxxxxx HelloThere
Note, Java allows you to use wild cards to avoid having to specify each jar manually...
When you run your code via tomcat it automatically adds the jars in /lib to the classpath.
Upvotes: 1