Sure; that seems reasonable. The InputStream is used just to load the XMLBean, and I don't believe that the InputStream needs to remain open after the bean's document is constructed.

But, given the late date, I don't mind erring on the side of caution...this will get cleaned up in trunk/ soon-ish.

Diff below -- this is uglier because I moved the null check on wsdl up and nested the rest of the method in try / finally.

Eddie

::::: diff.txt
Index: src/webservice/org/apache/beehive/controls/system/webservice/jaxrpc/ServiceControlImpl.jcs
===================================================================
--- src/webservice/org/apache/beehive/controls/system/webservice/jaxrpc/ServiceControlImpl.jcs (rev
ision 179055)
+++ src/webservice/org/apache/beehive/controls/system/webservice/jaxrpc/ServiceControlImpl.jcs (wor
king copy)
@@ -447,47 +447,51 @@
        private synchronized void initialize() throws Exception {
                if (initialized)
                        return;
-               XmlBeanWSDLProcessor wsdlProcessor;
-
                ServiceControl.WSDL wsdl = (ServiceControl.WSDL) cbContext

.getControlPropertySet(ServiceControl.WSDL.class);

-               if (wsdl != null) {
-                       logger.debug("read wsdl from: " + wsdl.path());
-                       InputStream wsdlStream = getWSDLStream(wsdl.path());
+        if(wsdl == null)
+ throw new RuntimeException("No WSDL annotation found.");
+
+        logger.debug("read wsdl from: " + wsdl.path());
+        InputStream wsdlStream = null;
+        try {
+            wsdlStream = getWSDLStream(wsdl.path());

-                       if (wsdlStream != null) {
- wsdlProcessor = new XmlBeanWSDLProcessor(wsdlStream);
-                       } else {
-                               throw new RuntimeException(
- "No WSDL found at the provided path: " + wsdl.path()
);
+                   XmlBeanWSDLProcessor wsdlProcessor;
+            if (wsdlStream != null) {
+                wsdlProcessor = new XmlBeanWSDLProcessor(wsdlStream);
+            } else {
+                throw new RuntimeException(
+                    "No WSDL found at the provided path: " + wsdl.path());
                        }
-               } else {
- throw new RuntimeException("No WSDL annotation found.");
-               }

-               ServiceFactory factory = ServiceFactory.newInstance();
+            ServiceFactory factory = ServiceFactory.newInstance();

- service = factory.createService(wsdlProcessor.getServiceName()); + service = factory.createService(wsdlProcessor.getServiceName());

-               HandlerInfo hInfo = new HandlerInfo();
-               hInfo.setHandlerClass(HeaderHandler.class);
+                   HandlerInfo hInfo = new HandlerInfo();
+                   hInfo.setHandlerClass(HeaderHandler.class);

-               TypeMapping tm = service.getTypeMappingRegistry()
-                               .getDefaultTypeMapping();
-               lookupService = new SystemTypeLookupService();
-               registrar = new AxisTypeRegistrar(
- (org.apache.axis.encoding.TypeMapping) tm, lookupService);
-               configureEndPoint();
+                   TypeMapping tm = service.getTypeMappingRegistry()
+                                   .getDefaultTypeMapping();
+                   lookupService = new SystemTypeLookupService();
+                   registrar = new AxisTypeRegistrar(
+ (org.apache.axis.encoding.TypeMapping) tm, lookupService);
+                   configureEndPoint();

-               mWSTM = wsdlProcessor.getObjectModel(lookupService);
+                   mWSTM = wsdlProcessor.getObjectModel(lookupService);

- portType = new QName(mWSTM.getWsTargetNamespace(), mWSTM.getWsName()); // porttype
-               // name
- service.getHandlerRegistry().getHandlerChain(portType).add(hInfo); + portType = new QName(mWSTM.getWsTargetNamespace(), mWSTM.getWsName()); // portty
pe
+                   // name
+ service.getHandlerRegistry().getHandlerChain(portType).add(hInfo);

-               initialized = true;
-
+                   initialized = true;
+        }
+        finally {
+            if(wsdlStream != null)
+                wsdlStream.close();
+        }
        }

        private String getAlternateOperationName(Method method) {
:::::

Richard Feit wrote:
One question: could the finally block be moved to the end of the method? It looks like XmlBeanWSDLProcessor only uses the stream in methods called from its constructor, but it does seem like it would be safer to avoid closing the stream before XmlBeanWSDLProcessor could *possibly* access it.


Eddie O'Neil wrote:


Yeah, I agree that it'd be good to fix...leaking streams doesn't tend to scale well.

  :)

I've pasted the diff below; please give this a review -- wouldn't be good to break something at this late date.

Eddie



::::: diff.txt
Index: src/webservice/org/apache/beehive/controls/system/webservice/jaxrpc/ServiceControlImpl.jcs
===================================================================
--- src/webservice/org/apache/beehive/controls/system/webservice/jaxrpc/ServiceControlImpl.jcs (rev
ision 179055)
+++ src/webservice/org/apache/beehive/controls/system/webservice/jaxrpc/ServiceControlImpl.jcs (wor
king copy)
@@ -454,14 +454,21 @@

                if (wsdl != null) {
                        logger.debug("read wsdl from: " + wsdl.path());
- InputStream wsdlStream = getWSDLStream(wsdl.path());
+            InputStream wsdlStream = null;
+            try {
+                           wsdlStream = getWSDLStream(wsdl.path());

-                       if (wsdlStream != null) {
- wsdlProcessor = new XmlBeanWSDLProcessor(wsdlStream);
-                       } else {
-                               throw new RuntimeException(
+                if (wsdlStream != null) {
+ wsdlProcessor = new XmlBeanWSDLProcessor(wsdlStream);
+                } else {
+                    throw new RuntimeException(
"No WSDL found at the provided path: " + wsdl.path()
);
-                       }
+                           }
+            }
+            finally {
+                if(wsdlStream != null)
+                    wsdlStream.close();
+            }
                } else {
throw new RuntimeException("No WSDL annotation found.");
                }
:::::

Richard Feit wrote:

I think that leaking streams is bad enough that the fix should go into the branch. The fix (minus the code cleanup in the same checkin) looks straightforward...

Eddie O'Neil (JIRA) wrote:

    [ http://issues.apache.org/jira/browse/BEEHIVE-772?page=all ]
    Eddie O'Neil resolved BEEHIVE-772:
----------------------------------

    Assign To:     (was: Eddie O'Neil)
   Resolution: Fixed

Fixed in trunk/; I've not made this change to 1.0m1. If anyone believes it should go up there (I sort of feel that way), let me know and I'll be happy to integ it.

service control leaks an InputStream
------------------------------------

        Key: BEEHIVE-772
        URL: http://issues.apache.org/jira/browse/BEEHIVE-772
    Project: Beehive
       Type: Bug
 Components: Controls
   Versions: V1Alpha, V1Beta, V1
   Reporter: Eddie O'Neil
   Priority: Critical
    Fix For: TBD




The current ServiceControlImpl.jcs loads a WSDL InputStream but never closes that stream. Thus, we're leaking streams.
Fix coming shortly.









Reply via email to