You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ant.apache.org by Tim Fennell <tf...@rcn.com> on 2000/08/13 04:48:56 UTC

Errors with Java/CommandLineJava/ExecuteJava

Just got the latest source from CVS, and I noticed an issue. Specifically when I
run EjbJar with WebLogic generation now I get ClassNotFound errors. Now, I'm not
too familiar with ClassLoaders, but I think I know what's going on...

WebLogicDeploymentTool uses taskdefs.Java to setup the execution of
weblogic.ejbc so as to make use of everything it has to offer. This in turn uses
CommandLineJava, and on line 243-248 does the following:
        ExecuteJava exe = new ExecuteJava();
        exe.setJavaCommand(command.getJavaCommand());
        Path p = new Path(project);
        p.append(command.getClasspath());
        addReferencesToPath(classpathReferences, p);
        exe.setClasspath(p); // Problems start here!!!
        exe.execute(project);

So, some form of classpath always gets passed to ExecuteJava...which does the
following on lines 90-95:
        if (classpath == null) {
            target = Class.forName(classname);
        } else {
            AntClassLoader loader = new AntClassLoader(project, classpath);
            target = loader.forceLoadClass(classname);
        }

Now, since WebLogicDeploymentTool didn't set the classpath for Java, the
classpath that get's passed to ExecuteJava is a non-null, but zero length (I
checked with System.outs) classpath. This classpath then causes ExecuteJava to
use the AntClassLoader, and try to load this class with an empty classpath!!

It seems to me that this will be a problem for anyone using the Java task for a
non-forking call, which doesn't set it's own classpath - which I'm assuming is
the majority of uses.

Probably the correct approach to this is to have Java check to see if it's
Classpath and ClasspathReferences together contain anything. If they do, then
create and set the classpath, otherwise don't! While we could change ExecuteJava
to check for 'classpath == null || classpath.size() == 0', it would seem that a
zero length classpath is conceivable as normal in some instances.

Does this all make sense? If so, I'll submit a patch for Java.java.

My last question is this: what is the preferred way to programattically call
another java class with a public static void main()? Doing it directly seems
bad, because you lose all that the Ant infrastructure has to offer. But should
you construct a Java task? How about constructing a CommandLineJava yourself and
giving it to ExecuteJava?

-t