NoClassDefFoundError when running shell script
Here is the error:
Exception in thread "main" java.lang.NoClassDefFoundError: org/alicebot/server/net/AliceServer
Caused by: java.lang.ClassNotFoundException: org.alicebot.server.net.AliceServer
at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
This is the server.sh file:
#!/bin/sh
echo Starting Jarvis Program D.
cd "`dirname \"$0\"`"
export ALICE_HOME=.
export SERVLET_LIB=lib/servlet.jar
export ALICE_LIB=lib/aliceserver.jar
export JS_LIB=lib/js.jar
# Set SQL_LIB to the location of your database driver.
export SQL_LIB=lib/mysql_comp.jar
# These are for Jetty; you will want to change these if you are using a different http server.
export HTTP_SERVER_LIBS=lib/org.mortbay.jetty.jar
export PROGRAMD_CLASSPATH=$SERVLET_LIB:$ALICE_LIB:$JS_LIB:$SQL_LIB:$HTTP_SERVER_LIBS
exec java -classpath $PROGRAMD_CLASSPATH -Xms64m -Xmx128m org.alicebot.server.net.AliceServer $1
Here is the 开发者_如何学CNSTask code:
NSString *shstring = [NSString stringWithFormat:
@"%@ %@ %@",
@"source",
@"server.sh",
@"| /usr/bin/sed '/Jarvis>/q'"
];
NSTask *sh = [NSTask new];
NSPipe *outputPipe = [NSPipe new];
[sh setLaunchPath:@"/bin/sh"];
[sh setArguments:[NSArray arrayWithObjects: @"-c", shstring, nil ]];
[sh setCurrentDirectoryPath:@"/applications/jarvis/brain"];
[sh setStandardInput:[NSPipe new]];
[sh setStandardError:outputPipe];
[sh setStandardOutput:outputPipe];
[sh launch];
NSMutableString *outputString = [NSMutableString string];
while ([outputString rangeOfString:@"Jarvis>"].location == NSNotFound) {
[outputString appendString:[[[NSString alloc] initWithData:[[outputPipe fileHandleForReading] readDataToEndOfFile] encoding:NSUTF8StringEncoding] autorelease]];
NSRunAlertPanel(@"", outputString, @"", @"", @"");
}
When ever I run this script through NSTask and I check the error pipe, that error comes up and only prints the echo.
Any ideas?
Replace relative with absolute paths in server.sh, then run server.sh with complete path (do not source server.sh in your NSTask code if server.sh has the shebang line and always check the exit code of the cd command).
Here's my server.sh file:
#!/bin/sh
# cat ~/Desktop/charliebot/server.sh
# code from: http://sourceforge.net/projects/charliebot/
# also adapt the following files if necessary:
# ~/Desktop/charliebot/console.sh
# ~/Desktop/charliebot/targeting.sh
# ~/Desktop/charliebot/tester.sh
echo Starting Alicebot Program D.
ALICE_HOME="${HOME}/Desktop/charliebot"
cd "${ALICE_HOME}" || { echo "Could not cd to: ${ALICE_HOME}"; exit 1; }
SERVLET_LIB="${ALICE_HOME}/lib/servlet.jar"
ALICE_LIB="${ALICE_HOME}/lib/aliceserver.jar"
JS_LIB="${ALICE_HOME}/lib/js.jar"
# Set SQL_LIB to the location of your database driver.
SQL_LIB="${ALICE_HOME}/lib/mysql_comp.jar"
# These are for Jetty; you will want to change these if you are using a different http server.
HTTP_SERVER_LIBS="${ALICE_HOME}/lib/org.mortbay.jetty.jar"
PROGRAMD_CLASSPATH="${SERVLET_LIB}:${ALICE_LIB}:${JS_LIB}:${SQL_LIB}:${HTTP_SERVER_LIBS}"
export ALICE_HOME SERVLET_LIB ALICE_LIB JS_LIB HTTP_SERVER_LIBS PROGRAMD_CLASSPATH
#printf "\n\n\nPROGRAMD_CLASSPATH\n%s\n\n\n" "$PROGRAMD_CLASSPATH" | tr ':' '\n'
exec java -classpath "$PROGRAMD_CLASSPATH" -Xms64m -Xmx128m org.alicebot.server.net.AliceServer $1
This works for me without the slightest hiccup.
# in Terminal.app
~/Desktop/charliebot/server.sh
I don't think the argument $1 to server.sh is obligatory. If that were the case, server.sh (i.e. exec java -classpath ...$1) would complain about it. But yes, it would be nice to know what kind of argument could be passed as $1 to server.sh (... reading man 1 java ...)!
All this, of course, does not remove your Objective-C while loop deadlock (NSNotFound). You have to implement an asynchronous stdout pipe reading mechanism instead of a while loop. (See, for example, Apple's "Dashboard Programming Topics" on asynchronous operations for such an approach.)
It much look like that the working directory is not what you expect it is. You're defining relative paths in the classpath argument. They are relative to the current working directory. Likely the current working directory doesn't know about a lib/aliceserver.jar
file. Do a pwd
to learn about the current working directory.
精彩评论