Alex Z
Alex Z

Reputation: 1877

Java Ant task uses wrong interpreter (java.exe instead of javaw.exe)

I'd like to switch my Ant build to use javaw.exe instead of java.exe. I managed to do it by setting _JAVACMD environment variable.

However when java task is invoked with fork = "true" java.exe is launched anyway (I already checked - there are no explicit specifications in my build file).

I have already tried to update ant.bat replacing java.exe to javaw.exe, that didn't help either.

Java 1.7.0.4 x64 Windows 7 x64

Upvotes: 1

Views: 900

Answers (2)

ewh
ewh

Reputation: 1034

This builds on the answer provided by @Teetoo: I think it is better if the jvm attribute of the java task is set to the full pathname of the executable, mainly the executable that would be associated with the version of Java that Ant runs under. If you have multiple versions of Java installed on your system, you may use a version you do not expected depending on how your system's search path is set.

Also, if you want the script to work on non-Windows OSs, you do not want to hardcode the use of javaw.exe since it is only available on Windows platforms.

The following Ant target will set the javaw.exe property accordingly:

<!-- Utility target to set javaw.exe property to pathname of JVM
     binary that can execute with no associated console -->
<target name="set-javaw-exe">
  <condition property="javaw.exe.basename"
             value="javaw.exe"
             else="java.exe">
    <os family="windows"/>
  </condition>
  <property name="javaw.exe.candidate"
            location="${java.home}/bin/${javaw.exe.basename}"/>
  <!-- If full pathname does not exist, fallback to just basename and hope it works -->
  <condition property="javaw.exe"
             value="${javaw.exe.candidate}"
             else="javaw.exe.basename">
    <resourceexists>
      <file file="${javaw.exe.candidate}"/>
    </resourceexists>
  </condition>
</target>

You can add the target to the depends list of any target that needs to use the property, or you can place the property setting code outside of the target at the project level so the property is always set.

With the property set, you can do:

<java jvm="${javaw.exe}" ...>

I know the solution does not address your concern of having to change all the uses of the java task in your build scripts, but I think that is unavoidable unless you modify the Ant source itself. Even if you decide to create a custom Ant task, maybe subclassed from Ant's java task implementation, you will still have to modify all calls to use your custom task.

IMO, Ant's java task should use javaw.exe by default, but restricted to using it if OS is Windows and the spawn attribute is true. I have recently discovered with later JRE versions that even with spawn set to true, the spawned process does not fully detach from the console. I have a script that starts Tomcat by calling Tomcat's bootstrap class directly, but if I close the console window it causes Tomcat to terminate. I employed the technique above to fix that problem.

Upvotes: 0

tofcoder
tofcoder

Reputation: 2392

You can use the jvm attribute of the Java ant task to specify the JVM to use.

<java jvm="javaw.exe" fork="true" ... >
    ...
</java>

Upvotes: 2

Related Questions