Apache Commons Exec - 有时线程无法在 Linux 中打开本地文件
Apache Commons Exec - sometimes a Thread can't open a local file in Linux
警告 -- 原因不是缺少文件 -- 所有线程都在调用同一个脚本文件
我正在启动 5-6 个调用 Red Hat 框中的本地脚本的线程。
我注意到有时会收到以下错误消息
couldn't read file "/home/leo/myScript.exp": no such file or directory
显然,所有进程都在执行脚本,所以它似乎与 [1] 有关 OS 对可以 运行 脚本或访问文件的同时进程有一些限制阅读或 [2] Java 正在尝试在一些尚未准备好的流中执行某些操作(我假设 commons-exec 会为我处理这个)
这是代码
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],那么我想知道如何在linuxOS
中放宽这个限制
如果错误是 [2],那么我想知道如何告诉 commons-exec 等待资源准备好(在最坏的情况下我只会添加一些重试,但我觉得这不是很优雅)
如果错误是其他原因,至少知道原因足以让我找到一些解决方案。
更新 - 3 月 15 日
嗯,事情是这样的。
该脚本是使用库调用Javaclass的expect脚本。
我注意到的一件事是脚本运行良好,直到它调用创建数据库连接的 java 方法。
因为线程数少(3~5个)我觉得不是数据库的问题。相反,在我看来,在 java 代码被调用 and/or 而 java 代码正在创建数据库连接时,某些东西正在阻止脚本被调用。
我仍在尝试获取确切的异常,但 expect 脚本看起来像这样(有点)
#!/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.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)
我要感谢所有在这个案例中提供帮助的人。
我会删除这个问题,但因为我已经悬赏了,所以我不能。 (也许当赏金到期时,如果允许的话,我会这样做)
我终于找到了一个没有问题的方法,它似乎与应用程序为线程分配资源的方式有关,所以根据问题中提供的信息,我认为它不是可能找出根本原因。
无论如何,我会尝试在这里描述发生的事情。
(点击放大)
问题是我注意到在 (5) (6) (7) 中。但是原因在(3)中。
为@Asynchronous 方法提供服务的线程池的 TomEE 配置中的线程(我的应用程序未使用默认值)少于所需的线程数,因此似乎有些资源不足。
此外,错误消息似乎有一些我尚未确定的错误,因此在这种情况下即使错误消息也可能无效。
因为这个问题没有解决问题所需的所有变量,所以我在这里提供关于这个问题的完整解释。
由于这是客户端代码,我无法提供代码,也无法提供所有信息。甚至包名都必须混淆。
再次感谢所有花时间在这里提供帮助的人,对于没有提供所有必要的数据,我深表歉意。
警告 -- 原因不是缺少文件 -- 所有线程都在调用同一个脚本文件
我正在启动 5-6 个调用 Red Hat 框中的本地脚本的线程。
我注意到有时会收到以下错误消息
couldn't read file "/home/leo/myScript.exp": no such file or directory
显然,所有进程都在执行脚本,所以它似乎与 [1] 有关 OS 对可以 运行 脚本或访问文件的同时进程有一些限制阅读或 [2] Java 正在尝试在一些尚未准备好的流中执行某些操作(我假设 commons-exec 会为我处理这个)
这是代码
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],那么我想知道如何在linuxOS
中放宽这个限制如果错误是 [2],那么我想知道如何告诉 commons-exec 等待资源准备好(在最坏的情况下我只会添加一些重试,但我觉得这不是很优雅)
如果错误是其他原因,至少知道原因足以让我找到一些解决方案。
更新 - 3 月 15 日
嗯,事情是这样的。
该脚本是使用库调用Javaclass的expect脚本。
我注意到的一件事是脚本运行良好,直到它调用创建数据库连接的 java 方法。
因为线程数少(3~5个)我觉得不是数据库的问题。相反,在我看来,在 java 代码被调用 and/or 而 java 代码正在创建数据库连接时,某些东西正在阻止脚本被调用。
我仍在尝试获取确切的异常,但 expect 脚本看起来像这样(有点)
#!/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.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)
我要感谢所有在这个案例中提供帮助的人。
我会删除这个问题,但因为我已经悬赏了,所以我不能。 (也许当赏金到期时,如果允许的话,我会这样做)
我终于找到了一个没有问题的方法,它似乎与应用程序为线程分配资源的方式有关,所以根据问题中提供的信息,我认为它不是可能找出根本原因。
无论如何,我会尝试在这里描述发生的事情。
问题是我注意到在 (5) (6) (7) 中。但是原因在(3)中。
为@Asynchronous 方法提供服务的线程池的 TomEE 配置中的线程(我的应用程序未使用默认值)少于所需的线程数,因此似乎有些资源不足。
此外,错误消息似乎有一些我尚未确定的错误,因此在这种情况下即使错误消息也可能无效。
因为这个问题没有解决问题所需的所有变量,所以我在这里提供关于这个问题的完整解释。
由于这是客户端代码,我无法提供代码,也无法提供所有信息。甚至包名都必须混淆。
再次感谢所有花时间在这里提供帮助的人,对于没有提供所有必要的数据,我深表歉意。