<!-- 
RSS generated by JIRA (9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66) at Thu Feb 08 08:52:20 UTC 2024

It is possible to restrict the fields that are returned in this document by specifying the 'field' parameter in your request.
For example, to request only the issue key and summary append 'field=key&field=summary' to the URL of your request.
-->
<rss version="0.92" >
<channel>
    <title>MongoDB Jira</title>
    <link>https://jira.mongodb.org</link>
    <description>This file is an XML representation of an issue</description>
    <language>en-us</language>    <build-info>
        <version>9.7.1</version>
        <build-number>970001</build-number>
        <build-date>13-04-2023</build-date>
    </build-info>


<item>
            <title>[JAVA-462] GridFSInputFile does not close input streams when constructed by the driver.</title>
                <link>https://jira.mongodb.org/browse/JAVA-462</link>
                <project id="10006" key="JAVA">Java Driver</project>
                    <description>&lt;p&gt;There is an issue here that the input stream is not being closed (when constructed by the driver).&lt;/p&gt;

&lt;p&gt;Since you can construct a GridFSInputFile with an InputStream, it is really the callers responsibility to close the intput stream object. It would be presumptuous for us to close that input stream.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/mongodb/mongo-java-driver/pull/50&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;https://github.com/mongodb/mongo-java-driver/pull/50&lt;/a&gt;&lt;/p&gt;</description>
                <environment></environment>
        <key id="24214">JAVA-462</key>
            <summary>GridFSInputFile does not close input streams when constructed by the driver.</summary>
                <type id="1" iconUrl="https://jira.mongodb.org/secure/viewavatar?size=xsmall&amp;avatarId=14703&amp;avatarType=issuetype">Bug</type>
                                            <priority id="3" iconUrl="https://jira.mongodb.org/images/icons/priorities/major.svg">Major - P3</priority>
                        <status id="6" iconUrl="https://jira.mongodb.org/images/icons/statuses/closed.png" description="The issue is considered finished, the resolution is correct. Issues which are closed can be reopened.">Closed</status>
                    <statusCategory id="3" key="done" colorName="success"/>
                                    <resolution id="9">Done</resolution>
                                        <assignee username="antoine">Antoine Girbal</assignee>
                                    <reporter username="rn@deftlabs.com">Ryan Nitz</reporter>
                        <labels>
                    </labels>
                <created>Fri, 28 Oct 2011 15:23:47 +0000</created>
                <updated>Mon, 31 Oct 2011 15:27:08 +0000</updated>
                            <resolved>Mon, 31 Oct 2011 15:18:25 +0000</resolved>
                                                    <fixVersion>2.7</fixVersion>
                                                        <votes>0</votes>
                                    <watches>0</watches>
                                                                                                                <comments>
                            <comment id="63698" author="rgnitz" created="Mon, 31 Oct 2011 15:18:25 +0000"  >&lt;p&gt;Merged into master. Thanks for the patch!&lt;/p&gt;</comment>
                            <comment id="63590" author="greenlaw110" created="Sun, 30 Oct 2011 19:28:51 +0000"  >&lt;p&gt;Fair enough. The new pull request with the suggested solution sent: &lt;a href=&quot;https://github.com/mongodb/mongo-java-driver/pull/51&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;https://github.com/mongodb/mongo-java-driver/pull/51&lt;/a&gt;&lt;/p&gt;</comment>
                            <comment id="63438" author="rgnitz" created="Fri, 28 Oct 2011 21:18:47 +0000"  >&lt;p&gt;If someone is modifying an input stream before calling save/operating on (or via another thread) then they are definitely going to have issues that are impossible to defend against.&lt;/p&gt;

&lt;p&gt;Under your scenario, are you proposing that the user leaves pointers to the InputStream objects open that are held in a session object? This is usually not a good idea as it will likely cause resource leaks.&lt;/p&gt;

&lt;p&gt;It might make sense to write the files uploaded immediately to a staging/temporary location and then move to the permanent location when they are committed by the user. This will allow you to easily cleanup files that have been abandoned.&lt;/p&gt;

&lt;p&gt;Your argument definitely has merit, but it is a bad practice by a driver to close streams you has not opened.&lt;/p&gt;

&lt;p&gt;Perhaps a solution that works for all is putting an optional flag in the constructor which tells the driver to close the input stream after persisting.&lt;/p&gt;</comment>
                            <comment id="63429" author="greenlaw110" created="Fri, 28 Oct 2011 20:47:15 +0000"  >&lt;p&gt;I see this is purely a design decision of API. the STL container by default will NOT clean up the data it points to when it is destroyed, while boost ptr_container does. It&apos;s all depend on how you communicate the contract of the API to application developers.&lt;/p&gt;

&lt;p&gt;As an application developer I 100 percent vote for GridFSInputFile to close the stream when my data is saved. As it&apos;s purely the purpose of the input stream object been created. If someone reuse the input stream object he is not doing a clean design. What if somebody close or rewind that input stream object when _readStream2Buffer method is reading data from it? You can&apos;t really prevent people from doing bad things. So stick to the design which do favor to good application developers is the correct decision to me.&lt;/p&gt;

&lt;p&gt;The coding block you showed above is just the simplest usage of resources. Here is one real case which couldn&apos;t fit into that pattern:&lt;/p&gt;

&lt;p&gt;1. User upload a photo in the html view&lt;br/&gt;
2. Controller create a temporary object &lt;span class=&quot;error&quot;&gt;&amp;#91;foo&amp;#93;&lt;/span&gt; which has a GridFSInputFile type property hold the file data&lt;br/&gt;
3. User upload other photos and other data&lt;br/&gt;
...&lt;br/&gt;
4. User click save to confirm the data&lt;br/&gt;
5. Controller all foo.save() to persist all data to the mongodb, where inside save method, all save method of GridFSInputFiles will be called.&lt;/p&gt;

&lt;p&gt;As you see the control flow is not able to be put into a single coding block as it&apos;s across processes. That&apos;s why I prefer that GridFSInputFile to close the inputstream. You could argue that user can construct the GridFSInputFile with the File instance, but theoretically people could pass in a input stream object, like someone might want to construct a bufferedinputstream and pass into the GridFS api.&lt;/p&gt;</comment>
                            <comment id="63424" author="rgnitz" created="Fri, 28 Oct 2011 20:30:39 +0000"  >&lt;p&gt;Related to the InputStream objects that the driver generates... you are absolutely right.&lt;/p&gt;</comment>
                            <comment id="63420" author="rgnitz" created="Fri, 28 Oct 2011 20:28:10 +0000"  >&lt;p&gt;Per my comments in the pull request:&lt;/p&gt;

&lt;p&gt;If you didn&apos;t open it, you shouldn&apos;t close it.&lt;/p&gt;

&lt;p&gt;There are use cases where people may want to perform additional operations on the input stream. It would be presumptuous to think that this is not the case.&lt;/p&gt;

&lt;p/&gt;
&lt;div id=&quot;syntaxplugin&quot; class=&quot;syntaxplugin&quot; style=&quot;border: 1px dashed #bbb; border-radius: 5px !important; overflow: auto; max-height: 30em;&quot;&gt;
&lt;table cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; border=&quot;0&quot; width=&quot;100%&quot; style=&quot;font-size: 1em; line-height: 1.4em !important; font-weight: normal; font-style: normal; color: black;&quot;&gt;
		&lt;tbody &gt;
				&lt;tr id=&quot;syntaxplugin_code_and_gutter&quot;&gt;
						&lt;td  style=&quot; line-height: 1.4em !important; padding: 0em; vertical-align: top;&quot;&gt;
					&lt;pre style=&quot;font-size: 1em; margin: 0 10px;  margin-top: 10px;   width: auto; padding: 0;&quot;&gt;&lt;span style=&quot;color: black; font-family: &apos;Consolas&apos;, &apos;Bitstream Vera Sans Mono&apos;, &apos;Courier New&apos;, Courier, monospace !important;&quot;&gt;InputStream is = null;&lt;/span&gt;&lt;/pre&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
				&lt;tr id=&quot;syntaxplugin_code_and_gutter&quot;&gt;
						&lt;td  style=&quot; line-height: 1.4em !important; padding: 0em; vertical-align: top;&quot;&gt;
					&lt;pre style=&quot;font-size: 1em; margin: 0 10px;   width: auto; padding: 0;&quot;&gt;&lt;span style=&quot;color: black; font-family: &apos;Consolas&apos;, &apos;Bitstream Vera Sans Mono&apos;, &apos;Courier New&apos;, Courier, monospace !important;&quot;&gt;try {&lt;/span&gt;&lt;/pre&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
				&lt;tr id=&quot;syntaxplugin_code_and_gutter&quot;&gt;
						&lt;td  style=&quot; line-height: 1.4em !important; padding: 0em; vertical-align: top;&quot;&gt;
					&lt;pre style=&quot;font-size: 1em; margin: 0 10px;   width: auto; padding: 0;&quot;&gt;&lt;span style=&quot;color: black; font-family: &apos;Consolas&apos;, &apos;Bitstream Vera Sans Mono&apos;, &apos;Courier New&apos;, Courier, monospace !important;&quot;&gt; is = LOAD FROM SOME SOURCE&lt;/span&gt;&lt;/pre&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
				&lt;tr id=&quot;syntaxplugin_code_and_gutter&quot;&gt;
						&lt;td  style=&quot; line-height: 1.4em !important; padding: 0em; vertical-align: top;&quot;&gt;
					&lt;pre style=&quot;font-size: 1em; margin: 0 10px;   width: auto; padding: 0;&quot;&gt;&amp;nbsp;&lt;/pre&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
				&lt;tr id=&quot;syntaxplugin_code_and_gutter&quot;&gt;
						&lt;td  style=&quot; line-height: 1.4em !important; padding: 0em; vertical-align: top;&quot;&gt;
					&lt;pre style=&quot;font-size: 1em; margin: 0 10px;   width: auto; padding: 0;&quot;&gt;&lt;span style=&quot;color: black; font-family: &apos;Consolas&apos;, &apos;Bitstream Vera Sans Mono&apos;, &apos;Courier New&apos;, Courier, monospace !important;&quot;&gt; // Perform some GridFS operation&lt;/span&gt;&lt;/pre&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
				&lt;tr id=&quot;syntaxplugin_code_and_gutter&quot;&gt;
						&lt;td  style=&quot; line-height: 1.4em !important; padding: 0em; vertical-align: top;&quot;&gt;
					&lt;pre style=&quot;font-size: 1em; margin: 0 10px;   width: auto; padding: 0;&quot;&gt;&amp;nbsp;&lt;/pre&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
				&lt;tr id=&quot;syntaxplugin_code_and_gutter&quot;&gt;
						&lt;td  style=&quot; line-height: 1.4em !important; padding: 0em; vertical-align: top;&quot;&gt;
					&lt;pre style=&quot;font-size: 1em; margin: 0 10px;   width: auto; padding: 0;&quot;&gt;&lt;span style=&quot;color: black; font-family: &apos;Consolas&apos;, &apos;Bitstream Vera Sans Mono&apos;, &apos;Courier New&apos;, Courier, monospace !important;&quot;&gt; // Rewind the input stream and then write to a another system&lt;/span&gt;&lt;/pre&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
				&lt;tr id=&quot;syntaxplugin_code_and_gutter&quot;&gt;
						&lt;td  style=&quot; line-height: 1.4em !important; padding: 0em; vertical-align: top;&quot;&gt;
					&lt;pre style=&quot;font-size: 1em; margin: 0 10px;   width: auto; padding: 0;&quot;&gt;&amp;nbsp;&lt;/pre&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
				&lt;tr id=&quot;syntaxplugin_code_and_gutter&quot;&gt;
						&lt;td  style=&quot; line-height: 1.4em !important; padding: 0em; vertical-align: top;&quot;&gt;
					&lt;pre style=&quot;font-size: 1em; margin: 0 10px;   width: auto; padding: 0;&quot;&gt;&lt;span style=&quot;color: black; font-family: &apos;Consolas&apos;, &apos;Bitstream Vera Sans Mono&apos;, &apos;Courier New&apos;, Courier, monospace !important;&quot;&gt;} finally {&lt;/span&gt;&lt;/pre&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
				&lt;tr id=&quot;syntaxplugin_code_and_gutter&quot;&gt;
						&lt;td  style=&quot; line-height: 1.4em !important; padding: 0em; vertical-align: top;&quot;&gt;
					&lt;pre style=&quot;font-size: 1em; margin: 0 10px;   width: auto; padding: 0;&quot;&gt;&lt;span style=&quot;color: black; font-family: &apos;Consolas&apos;, &apos;Bitstream Vera Sans Mono&apos;, &apos;Courier New&apos;, Courier, monospace !important;&quot;&gt;  if (is != null) is.close();&lt;/span&gt;&lt;/pre&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
				&lt;tr id=&quot;syntaxplugin_code_and_gutter&quot;&gt;
						&lt;td  style=&quot; line-height: 1.4em !important; padding: 0em; vertical-align: top;&quot;&gt;
					&lt;pre style=&quot;font-size: 1em; margin: 0 10px;   margin-bottom: 10px;  width: auto; padding: 0;&quot;&gt;&lt;span style=&quot;color: black; font-family: &apos;Consolas&apos;, &apos;Bitstream Vera Sans Mono&apos;, &apos;Courier New&apos;, Courier, monospace !important;&quot;&gt;}&lt;/span&gt;&lt;/pre&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
			&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p/&gt;</comment>
                            <comment id="63417" author="greenlaw110" created="Fri, 28 Oct 2011 20:22:54 +0000"  >&lt;p&gt;I think it&apos;s not an absolute rule that it&apos;s caller&apos;s responsibility to close the input stream object passed in. It&apos;s rather a good API design that indicates it&apos;s callee&apos;s responsibility to close the input stream in this case, as caller has no knowledge that when the input stream object has been used and could be dismissed.&lt;/p&gt;

&lt;p&gt;Here is the logic:&lt;/p&gt;

&lt;p&gt;1. Caller construct an input stream, say from Amazon S3.&lt;br/&gt;
2. Caller pass that input stream instance to GridFS and construct a GridFSInputFile object&lt;br/&gt;
3. After some log, the save method of the GridFSInputFile object has been called to persist the data coming from the input stream to mongodb. Note call to the save method might be very possible not in the components that construct the input stream object.&lt;br/&gt;
4. GridFSInputFile SHOULD close the input stream object as nobody is willing to dig out the original input stream instance and close it manually.&lt;/p&gt;</comment>
                            <comment id="63351" author="rgnitz" created="Fri, 28 Oct 2011 15:29:11 +0000"  >&lt;p&gt;This can be closed when the Java driver actually constructs the input.&lt;/p&gt;

&lt;p&gt;One possible solution is to make this closeable?&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://download.oracle.com/javase/6/docs/api/java/io/Closeable.html&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;http://download.oracle.com/javase/6/docs/api/java/io/Closeable.html&lt;/a&gt;&lt;/p&gt;</comment>
                    </comments>
                    <attachments>
                    </attachments>
                <subtasks>
                    </subtasks>
                <customfields>
                                                                                                                                                                                                                                                                                                                                                                    <customfield id="customfield_15850" key="com.atlassian.jira.plugins.jira-development-integration-plugin:devsummary">
                        <customfieldname>Development</customfieldname>
                        <customfieldvalues>
                            
                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    <customfield id="customfield_12550" key="com.pyxis.greenhopper.jira:gh-lexo-rank">
                        <customfieldname>Rank</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>2|hrhbkn:</customfieldvalue>

                        </customfieldvalues>
                    </customfield>
                                                                <customfield id="customfield_10558" key="com.pyxis.greenhopper.jira:gh-global-rank">
                        <customfieldname>Rank (Obsolete)</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>14675</customfieldvalue>
                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            </customfields>
    </item>
</channel>
</rss>