3

I want to run a Netbeans 7.3 platform application (let's name it app A) from another Java application (app B). To do this, in B's code I'm invoking the Ant library as follows:

Path pathA = ... // where the A's sources are
Path fileBuild = pathA.resolve("build.xml");
Project p = new Project();
p.setUserProperty("ant.file", fileBuild.toFile().getAbsolutePath());
p.init();
ProjectHelper helper = ProjectHelper.getProjectHelper();
p.addReference("ant.projectHelper", helper);
helper.parse(p, buildFile);
p.setDefault("run");
p.executeTarget(p.getDefaultTarget());

Unfortunately, the error I'm getting is:

C:\Program Files\NetBeans 7.3\harness\suite.xml:184: The following error occurred while executing this line:
C:\Program Files\NetBeans 7.3\harness\common.xml:217: Unable to find a javac compiler;
com.sun.tools.javac.Main is not on the classpath.
Perhaps JAVA_HOME does not point to the JDK.
It is currently set to "C:\Program Files (x86)\Java\jdk1.7.0_45\jre"
    at org.apache.tools.ant.ProjectHelper.addLocationToBuildException(ProjectHelper.java:568)
    at org.apache.tools.ant.taskdefs.Ant.execute(Ant.java:443)
    at org.apache.tools.ant.taskdefs.SubAnt.execute(SubAnt.java:306)
    at org.apache.tools.ant.taskdefs.SubAnt.execute(SubAnt.java:221)
    at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:292)
    at sun.reflect.GeneratedMethodAccessor4.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
    at org.apache.tools.ant.Task.perform(Task.java:348)
    at org.apache.tools.ant.Target.execute(Target.java:435)
    at org.apache.tools.ant.Target.performTasks(Target.java:456)
    at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1393)
    at org.apache.tools.ant.Project.executeTarget(Project.java:1364)
...

The JAVA_HOME variable is set correctly both as system path variable and in netbeans config file and points to C:\Program Files (x86)\Java\jdk1.7.0_45.

The question is, what am I missing? When running the app A from Netbeans menu, everything runs fine, so what should I append to the build file/ant settings to achieve A runs from B's code execution?

Thanks in advance!


Edit: I managed to get a more precise error stack, maybe this can help.

Error on test cases execution.
C:\Program Files\NetBeans 7.3\harness\common.xml:217: Unable to find a javac compiler;
com.sun.tools.javac.Main is not on the classpath.
Perhaps JAVA_HOME does not point to the JDK.
It is currently set to "C:\Program Files (x86)\Java\jdk1.7.0_45\jre"
    at org.apache.tools.ant.taskdefs.compilers.CompilerAdapterFactory.getCompiler(CompilerAdapterFactory.java:130)
    at org.apache.tools.ant.taskdefs.Javac.findSupportedFileExtensions(Javac.java:984)
    at org.apache.tools.ant.taskdefs.Javac.scanDir(Javac.java:961)
    at org.apache.tools.ant.taskdefs.Javac.execute(Javac.java:932)
    at org.netbeans.nbbuild.CustomJavac.execute(CustomJavac.java:105)
    at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:292)
    at sun.reflect.GeneratedMethodAccessor4.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
    at org.apache.tools.ant.Task.perform(Task.java:348)
    at org.apache.tools.ant.Target.execute(Target.java:435)
    at org.apache.tools.ant.Target.performTasks(Target.java:456)
    at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1393)
    at org.apache.tools.ant.Project.executeTarget(Project.java:1364)
    at odoetest.server.ServerInvokerAnt.start(ServerInvokerAnt.java:48)
    at odoetest.EntryPoint.invokeTests(EntryPoint.java:58)
    at odoetest.EntryPoint.main(EntryPoint.java:38)

Edit-2: I don't have any separate ant installation and use the ant delivered with Netbeans. When I run ant -diagnostics, I get this info. When I invoke the build or run job from the command line like

ant -f /path/to/build.xml run

no errors are thrown, the program starts. I just can't do the exact same thing from java code from above.

hoefling
  • 59,418
  • 12
  • 147
  • 194

3 Answers3

5

Your Ant build.xml will still be referring to a JRE rather than the JDK.

Right-click on your project, select Libraries, check that Java Platform points to a JDK rather than a JRE. See here for details.

If this fails:

You can explicitly set properties for Project p as in manouti's answer above. This will ensure that Project p as well as Project A will be referring to a JDK rather than JRE. AFAIK, no need to fork.

You can set properties in your .properties file, though it is not always easy to debug whether this is being implemented for each project.

You can explicitly include folders/files on the classpath of your target using the <classpath> element - see the Apache Ant Manual for some not very clear documentation.

This would be:

<classpath>
  <pathelement path="${path.to.jdk}"/>
</classpath>

See also this answer.

Community
  • 1
  • 1
Lydia Ralph
  • 1,455
  • 1
  • 17
  • 33
  • Can you please explain this a bit further? :-) Unfortunately, I'm not an ant expert... I don't have any other java distributions installed, and I attached the output of ant diagnostic. The sttings seem to be fine. What do you mean by right-clicking the build file? In Netbeans, I don't have any "Run as" action to execute on right click. – hoefling Feb 24 '15 at 22:12
1

NetBeans has setting which java to use internally. It's part of the netbeans.conf file. You are able to set the Java version for every NetBeans project which might be different.

However your JAVA_HOME points to a JRE and not JDK. That's why it cannot find the compiler - javac.

Crazyjavahacking
  • 9,343
  • 2
  • 31
  • 40
  • The setting in netbeans.conf is correct and points to jdk dir. However, seems that on executing the run target, `jre` is appended to JAVA_HOME out of nowhere. – hoefling Feb 19 '15 at 17:22
  • It's not the same. Print the variable JAVA_HOME into console. What does it say? – Crazyjavahacking Feb 19 '15 at 17:24
  • It's `C:\Program Files (x86)\Java\jdk1.7.0_45`.But I don't think it's relevant because when building a Netbeans RCP app, the JAVA_HOME takes value in netbeans.conf, ignoring the system variable. I also updated the question. – hoefling Feb 19 '15 at 17:29
  • Are you sure? It does not make sense why would the /jre appeared. – Crazyjavahacking Feb 19 '15 at 17:37
  • 1
    Yes, I'm sure. I wouln't raise the question if the solution would be so obvious. My guess is that the Netbeans modifies the path in its build files, I just can't find the spot. Maybe some workaround the devs built in silently. I'm tending to this because the error is raised in nb's harness common.xml. Also, the fact that running the app from Netbeans succeeds, is already a prove enough for JAVA_HOME validity. – hoefling Feb 19 '15 at 17:43
0

The error is occurring when calling the Ant javac task. Try to locate the call to that task (it should be in common.xml at the line shown in the error message), and try adding fork="yes" to it so that it runs the JDK compiler in an external process. See http://ant.apache.org/manual/Tasks/javac.html:

<javac fork="yes" ...

Also try adding the following property in the project invocation:

Project p = new Project();
p.setUserProperty("ant.file", fileBuild.toFile().getAbsolutePath());
p.setProperty("java.home", "C:\\Program Files (x86)\\Java\\jdk1.7.0_45");
M A
  • 71,713
  • 13
  • 134
  • 174
  • Unfortunately, this doesn't help. Forking corrupts the netbeans so no build/run job can be started (I also wouln't want to adapt nb installation files anyway), and the java.home property is not used at all. Instead, ant grabs the `System.getProperty("java.home")`. – hoefling Feb 23 '15 at 20:04