Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor AbstractFileObject#getOutputStream() #151

Closed

Conversation

boris-petrov
Copy link
Contributor

@boris-petrov boris-petrov commented Dec 16, 2020

I'm not sure whether changing the visibility of AbstractFileObject::getOutputStream and marking it as final is not a breaking change. This change is not strictly needed but I did it to protect from someone accidentally calling it from the outside like was done in RamFileSystem. AbstractFileObject::getOutputStream is an "internal" method which users should not call because closing the stream returned from it doesn't call the needed hooks - like endOutput. That was why RamFileOutputStream::close did that explicitly (which is not nice because when creating a new file in the RAM provider, endOutput would be called twice).

See also #150.

@garydgregory
Copy link
Member

Hi @boris-petrov
Please rebase on git master to pick up the default Maven build for GitHub

@boris-petrov
Copy link
Contributor Author

@garydgregory - done.

@garydgregory
Copy link
Member

garydgregory commented Dec 16, 2020

Hi @boris-petrov
As you can now see in the build output, this PR breaks binary compatibility. We can't do that within a major version, in this case, within the 2.x.y line of releases.
So if you can please fix that, we can then look at the PR afresh.
Also, please rebase on git master to pick up simplified copy logic.

@boris-petrov boris-petrov force-pushed the refactor-get-output-stream branch 2 times, most recently from 53d884e to 8bc1acb Compare December 17, 2020 07:18
@boris-petrov
Copy link
Contributor Author

@garydgregory - I rebased and added TODOs instead of changing the methods so that we remember to do it for the next major version.

@@ -1232,6 +1233,7 @@ public FileName getName() {
return fileName;
}

// TODO: remove this method for the next major version as it is unused
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a public method, you do not know who uses it, so you can't say it's "unused". I think this comment can be dropped.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a public method, right. Note, however, that users of VFS always use FileObject which is an interface and it doesn't have this method. It's only available if one casts explicitly to AbstractFileObject (which no one should do) and to sub-classes (which should not call it at all). The only place this will be called is in DefaultFileContent (actually not this but the other overload). That's why I've written that this can be removed - so that in the future a conversation like this is not done. 😃

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @boris-petrov
It does not matter as AbstractFileObject is a public method.

if one casts explicitly to AbstractFileObject (which no one should do)

Again, i does not matter as the class is available for 3rd party providers to subclass. Remember that anyone can plugin their own provider(s) in the framework, it's designed to be extensible. There are two kinds of clients of the API: (1) Traditional consumers of the API, and (2) File System providers, like VFS itself.

For 3.0 we can consider breaking the APIs but we are not there yet.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are correct for the two usages. My point is that neither customers of the API, nor FS providers should be calling these methods. Hence they could be made final and package-private. But not before 3.0 as you said. And because we're not there, I've added the TODOs so this is not forgotten.

} catch (final Exception e) {
throw new FileSystemException(e);
}
this.closed = true;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a change in behavior that is likely to break some apps since endOutput() is no longer called. Needs more study...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

endOutput will be called because the only way to get a RamFileOutputStream is through DefaultFileContent which wraps the output stream and on close calls endOutput.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @rgoers,
Any thoughts as to whether or not this can break existing users?
TY!

... instead of `AbstractFileObject.getOutputStream`. This allows us to
not call `endOutput` explicitly from anywhere other than `DefaultFileContent`
@garydgregory garydgregory changed the title Refactor getOutputStream Refactor AbstractFileObject#getOutputStream Apr 20, 2022
@garydgregory garydgregory changed the title Refactor AbstractFileObject#getOutputStream Refactor AbstractFileObject#getOutputStream() Apr 20, 2022
asfgit pushed a commit that referenced this pull request Apr 20, 2022
Update patch to avoid some possible if unlikely NPEs.
@garydgregory
Copy link
Member

Hi @boris-petrov
I patched this PR locally and committed a slightly different version to avoid possible if unlikely NPEs.

@boris-petrov boris-petrov deleted the refactor-get-output-stream branch April 20, 2022 19:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants