【发布时间】:2014-10-06 12:34:38
【问题描述】:
我正在使用 Worklight 版本 6.2.0.01.20141002-2218(工作室、服务器、ant 任务)和 Tomcat 7.0.55 来托管 Worklight 服务器(一切都是在 Windows 8.1 上运行)。作为 CI 构建的一部分,我们使用 Ant(版本 1.8.4)构建最新的应用程序 (.wlapp) 和适配器 (.adapter),然后将它们部署到 Tomcat 实例。我们看到的问题是,对于大于大约 2 MB 的 .wlapp 文件,我们会收到以下错误(隐藏 IP 和端口):
[wladm] Oct 06, 2014 1:42:55 PM org.apache.http.impl.client.DefaultRequestDirector tryExecute
[wladm] INFO: I/O exception (java.net.SocketException) caught when processing request: Connection reset by peer: socket write error
[wladm] Oct 06, 2014 1:42:55 PM org.apache.http.impl.client.DefaultRequestDirector tryExecute
[wladm] INFO: Retrying request
[wladm] Oct 06, 2014 1:42:55 PM org.apache.http.impl.client.DefaultRequestDirector tryExecute
[wladm] INFO: I/O exception (java.net.SocketException) caught when processing request: Software caused connection abort: socket write error
[wladm] Oct 06, 2014 1:42:55 PM org.apache.http.impl.client.DefaultRequestDirector tryExecute
[wladm] INFO: Retrying request
[wladm] Oct 06, 2014 1:42:55 PM org.apache.http.impl.client.DefaultRequestDirector tryExecute
[wladm] INFO: I/O exception (java.net.SocketException) caught when processing request: Software caused connection abort: socket write error
[wladm] Oct 06, 2014 1:42:55 PM org.apache.http.impl.client.DefaultRequestDirector tryExecute
[wladm] INFO: Retrying request
[wladm] Error accessing http://XXX.XX.XX.XXX:XXXX/wladmin/management-apis/1.0/runtimes/MyApp/applications?locale=en_GB:
BUILD FAILED
D:\XXX\build.xml:200: com.ibm.worklight.admin.restclient.RESTException: Error accessing http://XXX.XX.XX.XXX:XXXX/wladmin/management-apis/1.0/runtimes/MyApp/applications?locale=en_GB: Software caused connection abort: socket write error
at com.ibm.worklight.admin.restclient.RESTClient.getResponse(RESTClient.java:1062)
at com.ibm.worklight.admin.restclient.RESTClient.getPOSTResponse(RESTClient.java:1207)
at com.ibm.worklight.admin.restclient.RESTClient.getPOSTFileResponse(RESTClient.java:1227)
at com.ibm.worklight.admin.commands.DeployApp.getResponse(DeployApp.java:41)
at com.ibm.worklight.admin.restclient.ActionClient.execute(ActionClient.java:85)
at com.ibm.worklight.admin.ant.types.AbstractActionElement.executeCommand(AbstractActionElement.java:76)
at com.ibm.worklight.admin.ant.types.ActionElement.executeCommands(ActionElement.java:43)
at com.ibm.worklight.admin.ant.WladmTask.executeCommands(WladmTask.java:441)
at com.ibm.worklight.admin.ant.WladmTask.execute(WladmTask.java:290)
at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:291)
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.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
at org.apache.tools.ant.Task.perform(Task.java:348)
at org.apache.tools.ant.Target.execute(Target.java:392)
at org.apache.tools.ant.Target.performTasks(Target.java:413)
at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1399)
at org.apache.tools.ant.Project.executeTarget(Project.java:1368)
at org.apache.tools.ant.helper.DefaultExecutor.executeTargets(DefaultExecutor.java:41)
at org.apache.tools.ant.Project.executeTargets(Project.java:1251)
at org.apache.tools.ant.Main.runBuild(Main.java:811)
at org.apache.tools.ant.Main.startAnt(Main.java:217)
at org.apache.tools.ant.launch.Launcher.run(Launcher.java:280)
at org.apache.tools.ant.launch.Launcher.main(Launcher.java:109)
Caused by: java.net.SocketException: Software caused connection abort: socket write error
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:113)
at java.net.SocketOutputStream.write(SocketOutputStream.java:159)
at org.apache.http.impl.io.AbstractSessionOutputBuffer.write(AbstractSessionOutputBuffer.java:153)
at org.apache.http.impl.io.ContentLengthOutputStream.write(ContentLengthOutputStream.java:114)
at org.apache.http.entity.mime.content.FileBody.writeTo(FileBody.java:105)
at org.apache.http.entity.mime.HttpMultipart.doWriteTo(HttpMultipart.java:206)
at org.apache.http.entity.mime.HttpMultipart.writeTo(HttpMultipart.java:224)
at org.apache.http.entity.mime.MultipartEntity.writeTo(MultipartEntity.java:183)
at org.apache.http.entity.HttpEntityWrapper.writeTo(HttpEntityWrapper.java:96)
at org.apache.http.impl.client.EntityEnclosingRequestWrapper$EntityWrapper.writeTo(EntityEnclosingRequestWrapper.java:108)
at org.apache.http.impl.entity.EntitySerializer.serialize(EntitySerializer.java:120)
at org.apache.http.impl.AbstractHttpClientConnection.sendRequestEntity(AbstractHttpClientConnection.java:263)
at org.apache.http.impl.conn.AbstractClientConnAdapter.sendRequestEntity(AbstractClientConnAdapter.java:227)
at org.apache.http.protocol.HttpRequestExecutor.doSendRequest(HttpRequestExecutor.java:255)
at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:123)
at org.apache.http.impl.client.DefaultRequestDirector.tryExecute(DefaultRequestDirector.java:645)
at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:464)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:820)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:754)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:732)
at com.ibm.worklight.admin.restclient.RESTClient.getResponse(RESTClient.java:951)
... 25 more
请注意,在服务器日志中没有任何错误的痕迹。 Ant 构建文件中与此相关的部分是:
<target name="setup-worklight-tasks">
<taskdef resource="com/worklight/ant/defaults.properties">
<classpath>
<pathelement location="${worklight_ant_builder_path}"/>
</classpath>
</taskdef>
<taskdef resource="com/worklight/ant/deployers/antlib.xml">
<classpath>
<pathelement location="${worklight_ant_deployer_path}"/>
</classpath>
</taskdef>
</target>
<target name="deploy" depends="setup-worklight-tasks">
<wladm url="${admin_services_url}" user="${admin_services_user}" password="${admin_services_pass}" secure="false">
<deploy-app runtime="${runtime_name}" file="bin/MyApp-all.wlapp"/>
</wladm>
</target>
使用较小的 .wlapp 文件进行测试不会造成任何问题,从而成功部署应用程序。考虑到 Tomcat 的默认最大 POST 大小限制为 2 MB,我最初认为问题出在连接器的配置上。但是,在针对可能与此相关的任何内容调整所有连接器之后,我继续收到错误消息。这是我在 Tomcat 的server.xml 中的连接器的配置:
...
<Connector port="9080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="9443" maxPostSize="-1" maxSavePostSize="-1" maxHttpHeaderSize="2097152" socketBuffer="-1" bufferSize="20480"/>
<Connector port="9443" protocol="HTTP/1.1" SSLEnabled="true"
maxThreads="150" scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS"
keystoreFile="D:/IBM/apache-tomcat-7.0.55/security/server2_withchain.p12"
keystoreType="PKCS12"
keyPass="myPass" maxPostSize="-1" maxSavePostSize="-1" maxHttpHeaderSize="2097152" socketBuffer="-1" bufferSize="20480"/>
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" maxPostSize="-1" maxSavePostSize="-1" maxHttpHeaderSize="2097152" socketBuffer="-1" bufferSize="20480"/>
...
我测试的另一件事是通过 Worklight 控制台 UI 进行部署,该 UI 对任何大小的 .wlapp 文件都可以正常工作。我发现与使用 Worklight 控制台相关的一个有趣点是(通过检查 Tomcat 的访问日志)相关 URL 是:
XXX.XX.XX.XXX - demo [06/Oct/2014:13:48:05 +0200] "POST /wladmin/management-apis/1.0/runtimes/MyApp/applications?async=true HTTP/1.1" 200 602
0:0:0:0:0:0:0:1 - demo [06/Oct/2014:13:48:05 +0200] "POST /worklightconsole/services/management-apis/1.0/runtimes/MyApp/applications?async=true HTTP/1.1" 200 602
有趣的是async=true 参数的存在。考虑到这一点并考虑到通常“对等方重置连接:套接字写入错误”通常表示客户端存在问题,我认为这可能是wladm 任务意外关闭连接的问题(由于async=true 参数,在通过 UI 部署时可以避免的步骤)。
在部署到 Tomcat 时,是否有人在使用 wladm 任务时遇到过类似的问题?
更新 1:
我自己完成了.wlapp 文件的 POST(使用 Chrome 的 POSTman),上传和部署工作正常。这肯定表明wladm ant 任务中存在问题。
更新 2:
我在我的 Ant CI 构建过程中将 wladm 的使用替换为对 cURL 的调用,以执行应用程序和适配器文件到 Worklight 服务器的 POST。我可以确认使用cURL 就像一个魅力,这意味着问题确实出在wladm(更可能是它使用的捆绑的Apache HTTP 客户端)。这是我的 Ant 构建文件的更新部分(我定义了一个布尔标志以使用 cURL 或 wladm):
...
<target name="deploy" unless="deploy_done" depends="build, setup-worklight-tasks" description="Deploy adapters and apps">
<if>
<available file="adapters" type="dir"/>
<then>
<echo message="Deploying adapters" level="info"/>
<foreach target="deploy-adapter" param="adapterPath" inheritall="true">
<path>
<dirset dir="adapters" casesensitive="yes">
<include name="*"/>
</dirset>
</path>
</foreach>
</then>
</if>
<echo message="Deploying applications" level="info"/>
<foreach target="deploy-app" param="appPath" inheritall="true">
<path>
<dirset dir="apps" casesensitive="yes">
<include name="*"/>
</dirset>
</path>
</foreach>
<property name="deploy_done" value="true"/>
</target>
<target name="post-curl">
<exec executable="curl" failonerror="true" outputproperty="curl-output" errorproperty="curl-output-error">
<arg value="-u"/>
<arg value="${admin_services_user}:${admin_services_pass}"/>
<arg value="-F"/>
<arg value="FILE=@${post-curl.file}"/>
<arg value="${admin_services_url}/management-apis/1.0/runtimes/${runtime_name}/${post-curl.urlPart}"/>
</exec>
<if>
<not><contains string="${curl-output}" substring="SUCCESS"/></not>
<then>
<echo level="error">${curl-output}</echo>
<echo level="error">${curl-output-error}</echo>
<fail message="cURL upload failed"/>
</then>
</if>
</target>
<target name="deploy-app">
<basename property="appName" file="${appPath}"/>
<if>
<equals arg1="${admin_deploy_curl}" arg2="true"/>
<then>
<echo message="Deploying app [${appName}] using cURL..." level="info"/>
<antcall target="post-curl" inheritAll="true">
<param name="post-curl.file" value="bin/${appName}-all.wlapp"/>
<param name="post-curl.urlPart" value="applications"/>
</antcall>
</then>
<else>
<echo message="Deploying app [${appName}] using wladm..." level="info"/>
<wladm url="${admin_services_url}" user="${admin_services_user}" password="${admin_services_pass}" secure="false">
<deploy-app runtime="${runtime_name}" file="bin/${appName}-all.wlapp"/>
</wladm>
</else>
</if>
<echo message="App [${appName}] deployed." level="info"/>
</target>
<target name="deploy-adapter">
<basename property="adapterName" file="${adapterPath}"/>
<if>
<equals arg1="${admin_deploy_curl}" arg2="true"/>
<then>
<echo message="Deploying adapter [${adapterName}] using cURL..." level="info"/>
<antcall target="post-curl" inheritAll="true">
<param name="post-curl.file" value="bin/${adapterName}.adapter"/>
<param name="post-curl.urlPart" value="adapters"/>
</antcall>
</then>
<else>
<echo message="Deploying adapter [${adapterName}] using wladm..." level="info"/>
<wladm url="${admin_services_url}" user="${admin_services_user}" password="${admin_services_pass}" secure="false">
<deploy-adapter runtime="${runtime_name}" file="bin/${adapterName}.adapter"/>
</wladm>
</else>
</if>
<echo message="Adapter [${adapterName}] deployed." level="info"/>
</target>
...
【问题讨论】:
-
如果您觉得您在 Worklight 中遇到了错误,那么您需要打开 PMR 以便对其进行调查并获得修复版本。
-
谢谢伊丹。我开始这个问题是因为我想象我的配置有问题。随着我的测试进展,越来越明显的是这很可能是一个错误。我确实会提交 PMR 并回答当前问题。
标签: ibm-mobilefirst worklight-server