运行 shell 脚本时出现 NoClassDefFoundError

发布于 2024-09-15 23:10:51 字数 2373 浏览 10 评论 0原文

这是错误:

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

浮光之海 2024-09-22 23:10:51

将 server.sh 中的相对路径替换为绝对路径,然后使用完整路径运行 server.sh(如果 server.sh 具有 shebang 行,则不要在 NSTask 代码中使用 source server.sh,并且始终检查 cd 命令的退出代码)。

这是我的 server.sh 文件:

#!/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

这对我来说没有任何问题。

# in Terminal.app
~/Desktop/charliebot/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:

#!/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.)

温折酒 2024-09-22 23:10:51

看起来工作目录并不是您所期望的那样。您在类路径参数中定义相对路径。它们是相对于当前工作目录的。当前工作目录可能不知道 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 a pwd to learn about the current working directory.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文