运行时.Exec在调用包含hbm2ddl任务的脚本时冻结



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

Process Process = Runtime。getRuntime()。执行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此方法适用于unemachine(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工具警告:引用没有被设置为编译。classpath.id运行时,目标是在发现构建文件解析,试图的决心。未来的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>
编辑:

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

我不确定这是否是一种可能性,但您是否考虑过以编程方式调用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());

在StreamReader中readLine()之前和之后添加System.out.println()。查看当控制台挂起时,它是否仍在积极地读取,或者线程是否过早退出。

您要导出的模式特别大吗?它会产生大量产出吗?

在ant任务hbm2ddl上有一个'console'属性,如果console="true"将ddl复制到System.out.println(),这可能会导致您的问题。它可能会搞乱XP系统的缓冲。

默认是console="true"。试试console="false"

<Hbm2ddl console="false" drop = "false" update = "true" create = "true" export = "true" outputfilename = "$ {schema_ timestamp.for.sql}. Sql" delimiter = "" format = "true" haltOnError = "true "/>

有关更多信息,请参见Hbm2ddl Ant任务代码

相关内容

  • 没有找到相关文章

最新更新