Java 应用程序在 Mac OS X 上使用 Ant 执行其他 Java 应用程序
我正在开发一个客户端-服务器 Java 应用程序,该应用程序可以在 Mac OS X 以及 Windows 和 Linux 上运行。该应用程序有几个不同的客户端模块,应从启动器应用程序执行。 我看过 ProcessBuilder 类,但似乎不适合我。我在这里找到了一个线程 att stackoverflow,其中建议使用 Ant 的示例(此处)。 我实现了一个执行客户端模块的方法:
public void launchAnt(ApplicationData applicationData) {
Project project = new Project();
project.setBaseDir(new File(System.getProperty("user.dir")));
project.init();
DefaultLogger logger = new DefaultLogger();
project.addBuildListener(logger);
logger.setOutputPrintStream(System.out);
logger.setErrorPrintStream(System.err);
logger.setMessageOutputLevel(Project.MSG_INFO);
System.setOut(new PrintStream(new DemuxOutputStream(project, false)));
System.setErr(new PrintStream(new DemuxOutputStream(project, true)));
project.fireBuildStarted();
System.out.println("ApplicationLauncher.launch(): Running");
Throwable caught = null;
try {
/**
* Create Java task
*/
Java javaTask = new Java();
javaTask.setTaskName("Run " + applicationData.getApplication().name());
javaTask.setProject(project);
javaTask.setFork(false);
javaTask.setFailonerror(true);
javaTask.setClassname(applicationData.getClassName());
/**
* Working directory
*/
File workdir = new File(System.getProperty("user.dir"));
if(workdir.exists()) {
javaTask.setDir(workdir);
} else {
System.out.println("ApplicationLauncher.launch(): ERROR: Unable to set workdir, " + workdir.getAbsolutePath() + " does note exist.");
}
/**
* Classpath
*/
Path path = new Path(project);
Collection<String> classpaths = getClasspath();
for (String classpath : classpaths) {
Path currPath = new Path(project, new File(classpath).getAbsolutePath());
path.add(currPath);
}
System.out.println("ApplicationLauncher.launch(): Classpath: " + path.toString());
javaTask.setClasspath(path);
/**
* Arguments
*/
Argument arg = javaTask.createArg();
arg.setValue(applicationData.getArguments());
/**
* Initiate and execute
*/
javaTask.init();
int ret = javaTask.executeJava();
System.out.println("ApplicationLauncher.launch(): Java task return code: " + ret);
} catch (BuildException e) {
caught = e;
}
project.log("ApplicationLauncher.launch(): Finished");
project.fireBuildFinished(caught);
}
ApplicationData 是一个对象,其中包含有关要启动的应用程序的一些信息。此代码运行良好并且应用程序已启动。问题发生在启动的应用程序中,该行导致 ClassNotFoundException:
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
这是堆栈跟踪:
java.lang.ClassNotFoundException: apple.laf.AquaLookAndFeel
at org.apache.tools.ant.AntClassLoader.findClassInComponents(AntClassLoader.java:1361)
at org.apache.tools.ant.AntClassLoader.findClass(AntClassLoader.java:1311)
at org.apache.tools.ant.AntClassLoader.loadClass(AntClassLoader.java:1070)
at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:374)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:242)
at javax.swing.SwingUtilities.loadSystemClass(SwingUtilities.java:1788)
at javax.swing.UIManager.setLookAndFeel(UIManager.java:484)
如果我尝试独立运行应用程序,它工作正常。启动器应用程序包含失败的完全相同的行,并且在启动器中工作正常。启动应用程序的 ant 方式似乎有些不对劲。 我比较了从启动器执行应用程序和独立应用程序(有效)时的 System.properties 和类路径,没有区别。
我只是不明白为什么找不到这个课程。 还有其他人看到这个问题吗?任何建议表示赞赏!
谢谢!
I´m working on a client-server Java-application that is meant to work on Mac OS X as well as Windows and Linux. The application has several different client modules which should be executed from a launcher application.
I have looked at the ProcessBuilder class, but i doesn't seem to be right for me. I found a thread here att stackoverflow where an example using Ant was suggested (here).
I implemented a method that executes the client modules:
public void launchAnt(ApplicationData applicationData) {
Project project = new Project();
project.setBaseDir(new File(System.getProperty("user.dir")));
project.init();
DefaultLogger logger = new DefaultLogger();
project.addBuildListener(logger);
logger.setOutputPrintStream(System.out);
logger.setErrorPrintStream(System.err);
logger.setMessageOutputLevel(Project.MSG_INFO);
System.setOut(new PrintStream(new DemuxOutputStream(project, false)));
System.setErr(new PrintStream(new DemuxOutputStream(project, true)));
project.fireBuildStarted();
System.out.println("ApplicationLauncher.launch(): Running");
Throwable caught = null;
try {
/**
* Create Java task
*/
Java javaTask = new Java();
javaTask.setTaskName("Run " + applicationData.getApplication().name());
javaTask.setProject(project);
javaTask.setFork(false);
javaTask.setFailonerror(true);
javaTask.setClassname(applicationData.getClassName());
/**
* Working directory
*/
File workdir = new File(System.getProperty("user.dir"));
if(workdir.exists()) {
javaTask.setDir(workdir);
} else {
System.out.println("ApplicationLauncher.launch(): ERROR: Unable to set workdir, " + workdir.getAbsolutePath() + " does note exist.");
}
/**
* Classpath
*/
Path path = new Path(project);
Collection<String> classpaths = getClasspath();
for (String classpath : classpaths) {
Path currPath = new Path(project, new File(classpath).getAbsolutePath());
path.add(currPath);
}
System.out.println("ApplicationLauncher.launch(): Classpath: " + path.toString());
javaTask.setClasspath(path);
/**
* Arguments
*/
Argument arg = javaTask.createArg();
arg.setValue(applicationData.getArguments());
/**
* Initiate and execute
*/
javaTask.init();
int ret = javaTask.executeJava();
System.out.println("ApplicationLauncher.launch(): Java task return code: " + ret);
} catch (BuildException e) {
caught = e;
}
project.log("ApplicationLauncher.launch(): Finished");
project.fireBuildFinished(caught);
}
ApplicationData is an object that contains some information about the application to be launched. This code works well and the application is started. The problem occurs in the application that is launched where this row causes a ClassNotFoundException:
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
This is the stack trace:
java.lang.ClassNotFoundException: apple.laf.AquaLookAndFeel
at org.apache.tools.ant.AntClassLoader.findClassInComponents(AntClassLoader.java:1361)
at org.apache.tools.ant.AntClassLoader.findClass(AntClassLoader.java:1311)
at org.apache.tools.ant.AntClassLoader.loadClass(AntClassLoader.java:1070)
at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:374)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:242)
at javax.swing.SwingUtilities.loadSystemClass(SwingUtilities.java:1788)
at javax.swing.UIManager.setLookAndFeel(UIManager.java:484)
If I try to run the application standalone it works fine. The launcher application contains the exact same row that is failing, and that works fine in the launcher. It seems like there is something that is not right with the ant-way of launching the application.
I have compared the System.properties and the classpath when executing the application from the launcher and stand alone (which works) and there is no difference.
I just cannot see why this class can´t be found.
Has anyone else see this problem? Any suggestion is appreciated!
Thanx!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这些是一些最难调试的错误。这是一个好兆头,表明代码在 Ant 之外运行正常,这会留下类路径问题。检查项目的类路径,您的系统找不到“apple.laf.AquaLookAndFeel”。
These are some of the hardest errors to debug. It's a good sign that the code runs OK outside of Ant, which leaves a classpath issue. Check the classpath of your project, your system can't find "apple.laf.AquaLookAndFeel".