Apache Commons Exec – 有时一个线程无法在Linux中打开一个本地文件

警告 – 原因不是一个缺less的文件 – 所有的线程都调用相同的脚本文件

我正在启动5-6个线程,在Red Hat框中调用本地脚本。

我注意到有时,我得到以下错误信息

couldn't read file "/home/leo/myScript.exp": no such file or directory 

显然,所有的进程正在执行脚本,所以它似乎是与[1]操作系统有一定的限制,可以运行脚本或访问文件读取或[2] Java正试图执行一些操作一些没有准备好的stream(我假设公用高pipe会为我照顾这个)

这是代码

 ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); CommandLine commandline = CommandLine.parse("/home/leo/myScript.exp"); DefaultExecutor exec = new DefaultExecutor(); PumpStreamHandler streamHandler = new PumpStreamHandler(outputStream); exec.setStreamHandler(streamHandler); try { exec.execute(commandline); <<< error happens here }catch(IOException io) { throw new Exception(""); } 

如果错误是[1],那么我想知道如何放松在Linux操作系统的这个限制

如果错误是[2],那么我想知道如何告诉commons-exec等待资源准备好(在最坏的情况下,我只是添加一些重试,但我认为这不是很优雅)

如果错误是其他的东西,至less知道原因将足以让我find一些解决scheme。

更新 – 3月15日

那么,这是事情。

该脚本是一个期望脚本,它使用库来调用Java类。

有一件事我注意到,脚本运行良好,直到它调用一个创build数据库连接的java方法。

由于线程数量很less(3〜5),我不认为这是数据库中的问题。 相反,在我看来有些东西阻塞了在Java代码被调用时被调用的脚本和/或在Java代码正在创build数据库连接的时候。

我仍然试图得到确切的exception,但期望脚本看起来像这样(种)

 #!/opt/tclblend/bin/expect -f set edfDir "/usr/local/nssa/bin/edf"; set env(LD_LIBRARY_PATH) "/opt/tclblend/lib/tcljava1.4.1"; # for tclBlend ## always use absolute paths set env(TCL_CLASSPATH) "/home/leoks/EclipseIndigo/workspace2/xyzJavaWrapper/bin"; set env(CLASSPATH) {/home/leoks/EclipseIndigo/workspace2/xyzTomEE/lib/commons-logging-1.1.1.jar:/home/leoks/EclipseIndigo/workspace2/xyzConfiguration/lib/commons-configuration-1.9.jar:/home/leoks/EclipseIndigo/workspace2/xyzConfiguration/lib/commons-lang-2.4.jar:/home/leoks/EclipseIndigo/workspace2/xyz/3rdPartyJDBCJars/ojdbc6.jar:/home/leoks/EclipseIndigo/workspace2/xyzJavaWrapper/lib/commons-dbutils-1.5.jar:/home/leoks/EclipseIndigo/workspace2/xyzJavaWrapper/tcl/tcllib/xyzConfiguration.jar}; source $edfDir/lib/statics.tcl; source $edfDir/lib/acclib.tcl; package require java java::import com.abc.xyz.legacydriver.TCLDriverWrapper java::import com.abc.xyz.legacydriver.LegacyDriverTaskInputData java::import com.abc.xyz.legacydriver.LegacyDriverTaskEnum set ticket [ lindex $argv 0 ]; set inputData [ java::call com.abc.xyz.legacydriver.TCLDriverWrapper pullNextInputData $ticket ] 

其中pullNextInputData看起来像

 public static LegacyDriverTaskInputData pullNextInputData(String token) throws Exception { try { return pullNextInputDataImpl(token); } catch (Exception e) { e.printStackTrace(); throw e; } } private static LegacyDriverTaskInputData pullNextInputDataImpl(String token) throws Exception { Connection conn = null; try{ conn = new TCLDriverWrapper().getConnection(); QueryRunner run = new QueryRunner(); ResultSetHandler<LegacyDriverTaskInputData> rsh = new BeanHandler<LegacyDriverTaskInputData>(LegacyDriverTaskInputData.class); LegacyDriverTaskInputData inputData = run.query(conn,"select * from LegacyDriverTask where id = ?",rsh,Long.valueOf(token)); return inputData; } catch (ClassNotFoundException e) { e.printStackTrace(); throw e; } catch (SQLException e) { e.printStackTrace(); throw e; } finally { DbUtils.close(conn); } } 

和getConnection()只是一个普通的驱动程序实例化代码(它使用apache dbutils)

 private Connection getConnectionImpl() throws Exception{ Class.forName("driver name"); Properties props = new Properties(); props.put("user", UtilConf.getProperty("javawrapper.user")); props.put("password", UtilConf.getProperty("javawrapper.password")); return DriverManager.getConnection(UtilConf.getProperty("javawrapper.jdbc"), props); } 

只要我有一个堆栈跟踪,我会把它放在这里

更新 – 3月16日

堆栈跟踪不多说:-(

 2016-03-17 01:49:10,034 INFO [QProcessor] Threads started (ok=0 nok=0 wait=0) org.apache.commons.exec.ExecuteException: Process exited with an error: 1 (Exit value: 1) at org.apache.commons.exec.DefaultExecutor.executeInternal(DefaultExecutor.java:404) at org.apache.commons.exec.DefaultExecutor.execute(DefaultExecutor.java:166) at org.apache.commons.exec.DefaultExecutor.execute(DefaultExecutor.java:153) at com.ericsson.xyz.tomee.q.QWorker.onMessageImpl(QWorker.java:776) at com.ericsson.xyz.tomee.q.QWorker.onMessage(QWorker.java:303) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:606) at org.apache.openejb.core.interceptor.ReflectionInvocationContext$Invocation.invoke(ReflectionInvocationContext.java:182) at org.apache.openejb.core.interceptor.ReflectionInvocationContext.proceed(ReflectionInvocationContext.java:164) at org.apache.openejb.monitoring.StatsInterceptor.record(StatsInterceptor.java:180) at org.apache.openejb.monitoring.StatsInterceptor.invoke(StatsInterceptor.java:99) at sun.reflect.GeneratedMethodAccessor106.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:606) at org.apache.openejb.core.interceptor.ReflectionInvocationContext$Invocation.invoke(ReflectionInvocationContext.java:182) at org.apache.openejb.core.interceptor.ReflectionInvocationContext.proceed(ReflectionInvocationContext.java:164) at org.apache.openejb.core.interceptor.InterceptorStack.invoke(InterceptorStack.java:80) at org.apache.openejb.core.stateless.StatelessContainer._invoke(StatelessContainer.java:212) at org.apache.openejb.core.stateless.StatelessContainer.invoke(StatelessContainer.java:181) at org.apache.openejb.core.ivm.EjbObjectProxyHandler.synchronizedBusinessMethod(EjbObjectProxyHandler.java:268) at org.apache.openejb.core.ivm.EjbObjectProxyHandler$1.call(EjbObjectProxyHandler.java:253) at org.apache.openejb.async.AsynchronousPool$AsynchronousCall.call(AsynchronousPool.java:110) at java.util.concurrent.FutureTask.run(FutureTask.java:262) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) at java.lang.Thread.run(Thread.java:724) 

我要感谢所有帮助过这个案子的人。

我会删除这个问题,但是由于我已经给了它一个赏金,我不能。 (也许当赏金到期,如果SO允许我,那么我会做)

我终于找到了一个不存在这个问题的方法,它似乎与应用程序为线程分配资源的方式有关,所以给出了问题中提供的信息,我认为不可能找出根本原因。

无论如何,我会试着在这里描述发生了什么事。

在这里输入图像描述 (点击放大)

问题是我注意到在(5)(6)(7)中。 但是原因在(3)。

服务@Asynchronous方法的线程池的TomEE配置的线程少(我的应用程序没有使用默认值),因此似乎有些资源正在被饿死。

此外,错误消息似乎有一些错误,我还没有确定,所以即使错误消息可能是无效的在这种情况下。

因为这个问题并没有解决所有必要的变量,所以我在这里提供一个关于这个问题的完整解释。

由于这是一个客户端代码,我不能使代码可用,或提供所有的信息。 即使包名称也必须被模糊处理。

再次,我想感谢那些花时间在这里帮助的人,我想道歉不提供所有必要的数据。