运行 shell 脚本时出现 NoClassDefFoundError
这是错误:
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)
这是 server.sh 文件:
#!/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
这是 NSTask 代码:
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, @"", @"", @"");
}
每当我通过 NSTask 运行此脚本并检查错误管道时,就会出现该错误并且仅打印回显。
有什么想法吗?
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 NSTask 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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
将 server.sh 中的相对路径替换为绝对路径,然后使用完整路径运行 server.sh(如果 server.sh 具有 shebang 行,则不要在 NSTask 代码中使用 source server.sh,并且始终检查 cd 命令的退出代码)。
这是我的 server.sh 文件:
这对我来说没有任何问题。
我认为 server.sh 的参数 $1 不是强制性的。如果是这种情况,server.sh(即 exec java -classpath ...$1)会抱怨它。但是,是的,很高兴知道什么样的参数可以作为 $1 传递给 server.sh(...阅读 man 1 java ...)!
当然,所有这些并不能消除 Objective-C while 循环死锁(NSNotFound)。您必须实现异步标准输出管道读取机制而不是 while 循环。 (例如,请参阅 Apple 的有关异步操作的“仪表板编程主题”以了解这种方法。)
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:
This works for me without the slightest hiccup.
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.)
看起来工作目录并不是您所期望的那样。您在类路径参数中定义相对路径。它们是相对于当前工作目录的。当前工作目录可能不知道
lib/aliceserver.jar
文件。执行pwd
来了解当前工作目录。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 apwd
to learn about the current working directory.