Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Runtime.exec freezes when invoking ant script that contain hbm2ddl task?

Tags:

java

process

ant

To launch an ant script I use the exec method of the class java.lang.Runtime as follows:

Process process = Runtime.getRuntime (). Exec (JAVA_HOME ANT_HOME -jar / lib / ant-launcher.jar-BuildFile file.xml);

This method, despite its apparent simplicity, but it poses several problems and is described in the javadoc as follows:

Because Some native platforms Provide only limited buffer size for standard input and output streams, failure to promptly write the input stream or read the output stream of the subprocess May cause the subprocess to block, and Even deadlock.

To solve this problem I referred to the following article: http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html?page=1 This method worked for unemachine (64-bit Windows 7, Core 2 Quad Q9400 @ 2,66 GHz 2.67 GHz, 4GB) But when I used another machine (XP SP3, Core 2 Duo 2.99 GHz @ 3 GHz, 3.21 GB memory), the process hangs at generating the data schema and the console remains desperately silent after posted the following message:

[hibernatetool] Executing Hibernate Tool with a JPA Configuration Warning: Reference not compilation.classpath.id HAS-been set at runtime, goal WAS DURING found build file parsing, Attempting to resolve. Future versions of Ant May support referencing ids Defined in non-executed targets.

[Hibernatetool] 1. Task: hbm2ddl (Generates database schema).

Are you faced with a problem like this? Do you have a solution for me? I am open to any solution. Note: my ant script looks like this:

<project>
..
  <target name="create-jpa-schema">
      <tstamp>
         <format property="timestamp.for.sql" pattern="yyyy-MM-dd_HH-mm-ss" />
      </ Tstamp>
      <hibernatetool destdir="${build.sql.dir}">
         <classpath>
            <path refid="classpath.id" />
            <pathelement path="${model.jar}" />
         </ Classpath>

         <jpaconfiguration persistenceunit="studio-pu" />
         <! - Export schema to SQL database and run it Against ->
         <Hbm2ddl drop = "false" update = "true" create = "true" export = "true" outputfilename = "$ {schema_ timestamp.for.sql}. Sql" delimiter = "" format = "true" haltOnError = "true "/>
      </ Hibernatetool>
   </ Target>
..
</ Project>

EDIT: Code that execute runtime.exec:

public static int executeCommand(
      String cmd,
      File directory) throws IOException, InterruptedException
   {
      Process process = Runtime.getRuntime().exec(cmd, null, directory);
      StreamReader outputStreamReader = new StreamReader(
         process.getInputStream(),
         "OUTPUT");
      StreamReader errorStreamReader = new StreamReader(process.getErrorStream(), "ERROR");
      final Thread outputThreadReader = new Thread(outputStreamReader);
      final Thread errorThreadReader = new Thread(errorStreamReader);

      outputThreadReader.start();
      errorThreadReader.start();

      int exitCode = process.waitFor();
      System.out.println("exit code:" + exitCode);
      return exitCode;

   }

StreamReader.java

public class StreamReader implements Runnable
{
   InputStream is;

   OutputStream os;

   String type;   

   StreamReader(InputStream is, String type)
   {
      this.is = is;
      this.type = type;
   }

   StreamReader(InputStream is, OutputStream os, String type)
   {
      this.is = is;
      this.os = os;
      this.type = type;
   }

   @Override
   public void run()
   {
      try
      {
         PrintWriter pw = null;

         if (os != null)
            pw = new PrintWriter(os);

            InputStreamReader isr = new InputStreamReader(is);

            BufferedReader br = new BufferedReader(isr);
            String line = null;
            while ((line = br.readLine()) != null)
            {
               if (pw != null)
               {
                  pw.println(line);
                  pw.flush();
               }
               else
                  System.out.println(type + ">" + line);
               if(progressListener!=null)
               progressListener.onUpdate(line);
            }

      }
      catch (IOException ioe)
      {
         ioe.printStackTrace();
      }

   }

}
like image 945
user405458 Avatar asked Aug 16 '11 16:08

user405458


1 Answers

I'm not sure whether this is a possibility but have you considered invoking ant programmatically, instead of launching a new process?

According to this article, you should be able to do the following in a new thread instead of spawing a process:

File buildFile = new File("build.xml");
Project p = new Project();
p.setUserProperty("ant.file", buildFile.getAbsolutePath());
p.init();
ProjectHelper helper = ProjectHelper.getProjectHelper();
p.addReference("ant.projectHelper", helper);
helper.parse(p, buildFile);
p.executeTarget(p.getDefaultTarget());
like image 164
beny23 Avatar answered Oct 27 '22 00:10

beny23