调用包含hbm2ddl任务的ant脚本时,Runtime.exec会冻结吗?

use*_*458 6 java ant process

要启动ant脚本,我使用exec类的方法java.lang.Runtime如下:

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

这种方法虽然简单明了,但它带来了一些问题,并在javadoc中描述如下:

因为某些本机平台仅为标准输入和输出流提供有限的缓冲区大小,所以无法及时写入输入流或读取子进程的输出流可能导致子进程阻塞,甚至死锁.

为了解决这个问题,我参考了以下文章:http: //www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html? page = 1此方法适用于非机器(64位Windows) 7,Core 2 Quad Q9400 @ 2,66 GHz 2.67 GHz,4GB)但是当我使用另一台机器(XP SP3,Core 2 Duo 2.99 GHz @ 3 GHz,3.21 GB内存)时,该过程在生成数据模式和在发布以下消息后,控制台仍然绝望地保持沉默:

[hibernatetool]使用JPA配置执行Hibernate工具警告:引用不是compilation.classpath.id已在运行时设置,目标WAS DURING发现构建文件解析,尝试解决.Ant的未来版本可支持引用ID在非执行目标中定义.

[Hibernatetool] 1.任务:hbm2ddl(生成数据库模式).

你是否遇到过这样的问题?你有解决方案吗?我愿意接受任何解决方案.注意:我的ant脚本如下所示:

<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>
Run Code Online (Sandbox Code Playgroud)

编辑: 执行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;

   }
Run Code Online (Sandbox Code Playgroud)

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();
      }

   }

}
Run Code Online (Sandbox Code Playgroud)

ben*_*y23 1

我不确定这是否可能,但您是否考虑过以编程方式调用 ant,而不是启动新进程?

根据这篇文章,您应该能够在新线程中执行以下操作,而不是生成进程:

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());
Run Code Online (Sandbox Code Playgroud)