Skip to content

issue #5752: Activate checks related to java.io.Closeable#5753

Merged
romani merged 1 commit into
checkstyle:masterfrom
Softus:issue-5752
May 18, 2018
Merged

issue #5752: Activate checks related to java.io.Closeable#5753
romani merged 1 commit into
checkstyle:masterfrom
Softus:issue-5752

Conversation

@pbludov

@pbludov pbludov commented Apr 22, 2018

Copy link
Copy Markdown
Member

Issue #5752

Force use of try-with-resources

@pbludov pbludov changed the title Issue #5291: fixed xdoc lines of 100 characters or more Issue #5752: Activate checks related to java.io.Closeable Apr 22, 2018

mkdir -p target/classes
mkdir -p target/eclipse
mkdir -p target/classes target/test-classes target/eclipse

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

To solve warning incorrect classpath: src/checkstyle/target/test-classes on clean environment

@codecov-io

codecov-io commented Apr 22, 2018

Copy link
Copy Markdown

Codecov Report

Merging #5753 into master will not change coverage.
The diff coverage is 100%.

Impacted file tree graph

@@           Coverage Diff            @@
##             master   #5753   +/-   ##
========================================
  Coverage       100%    100%           
- Complexity     7381    7386    +5     
========================================
  Files           296     296           
  Lines         16123   16138   +15     
  Branches       3254    3255    +1     
========================================
+ Hits          16123   16138   +15
Impacted Files Coverage Δ Complexity Δ
...ain/java/com/puppycrawl/tools/checkstyle/Main.java 100% <100%> (ø) 78 <4> (+2) ⬆️
...com/puppycrawl/tools/checkstyle/DefaultLogger.java 100% <100%> (ø) 23 <0> (+2) ⬆️
...ava/com/puppycrawl/tools/checkstyle/XMLLogger.java 100% <100%> (ø) 44 <0> (+1) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 4209baa...3cc1f00. Read the comment docs.

@romani romani left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Items to improve:

* @return a fresh new {@code AuditListener}
* @exception IOException when provided output location is not found
*/
@SuppressWarnings("resource")

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Please explain suppress reason in javadoc.
Why IDEA does not have there suppression ? Is it a hug in Eclipse analyser?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I do not think this is a bug. The algorithms that use IDEA and Eclipse are different. And they can behave differently.

@romani romani Apr 25, 2018

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

ok, call it new feature request, enhancement, any type of ticket against Eclipse to be better.
If IDEA found way to make less false positives, why Eclipse should be behind ?

If Eclipse is less configurable/smart ... why we should activate it ? Does it make sense to activate only IDEA ?
Do we get some benefit from Eclipse only(not detected by IDEA) ?


/**
* Output stream to hold the test results.
* @noinspection resource

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Please explain suppress reason in javadoc.


/**
* Output stream to hold the test results.
* @noinspection resource

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Please explain suppress reason in javadoc.

<option value="ReuseOfLocalVariable" />
<!-- The output stream created by Main.createListener will be closed later. This is
by design. A warning issued by Eclipse JDT need to be suppressed. -->
<option value="resource" />

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Please make comment more general. As we sometime postpone close for resource by design, not only for this particular case - Main.createListener

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

all done

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

sorry to enforce bureaucracy, but it is proven by practice, principle to do "done" for each point.
It is just final recheck that all items from numerous are done.

@romani romani left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I need to review this further:

<!-- we are ok to use auto-unboxing as we use modern java -->
<inspection_tool class="AutoCloseableResource" enabled="true" level="ERROR" enabled_by_default="true" >
<option name="ignoreFromMethodCall" value="true" />
</inspection_tool>

@romani romani Apr 25, 2018

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

comment for myself.
from IDEA:

Reports AutoCloseable instances which are not used in a try-with-resources statement, also known as Automatic
Resource Management. This means that the open resource before/in try, close in finally style which was used
before try-with-resources was available is also reported. This inspection is meant to replace all opened but not
safely closed inspections when developing in Java 7 and higher.
Use the first table below to specify which AutoCloseable subclasses should be ignored by this inspection. Specify
AutoCloseable subclasses here which do not need to be closed.
Use the second table below to specify which methods returning AutoCloseable will be ignored when called.
Use the first checkbox below to ignore an AutoCloseable if it the result of a method call. When enabled, the results
of factory methods will also be ignored.
Use the second checkbox below to specify that the inspection should not warn if an AutoCloseable instance is
passed as a method call argument. If enabled the inspection assumes the resource is closed in the called method. Method calls inside a finally block with close in the name and an AutoCloseable argument will not be ignored.

Config for proposed xml looks like this in IDEA:
screensho-idea-autoclosable-20180425

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Yes, it is related to the ignoreFromMethodCall option.
By turning it off the IDEA reports the line

            out = Files.newOutputStream(Paths.get(outputLocation));

as violation in the same way as Eclipse does. One more: the suppression

    @SuppressWarnings("resource")

Works for IDEA in the same way as for Eclipse. So it is possible to set ignoreFromMethodCall to false.

@pbludov

pbludov commented Apr 26, 2018

Copy link
Copy Markdown
Member Author

After setting ignoreFromMethodCall to false, IDEA found 11 more violations. All of them are in the folder src/test/java. The Eclipse compiler does not issue any warnings for test classes.

This is unexpected and should be investigated.

@pbludov pbludov changed the title Issue #5752: Activate checks related to java.io.Closeable [WIP] Issue #5752: Activate checks related to java.io.Closeable Apr 26, 2018
@romani

romani commented May 2, 2018

Copy link
Copy Markdown
Member

@pbludov ,

ignoreFromMethodCall to false .. should be investigated.

ignoreFromMethodCall=true allow too much.
please use following config for IDEA:

  <inspection_tool class="AutoCloseableResource" enabled="true" level="ERROR" enabled_by_default="true">
    <option name="ignoredTypes" value="java.util.stream.Stream,java.util.stream.IntStream,java.util.stream.LongStream,java.util.stream.DoubleStream,com.puppycrawl.tools.checkstyle.internal.utils.CloseAndFlushTestByteArrayOutputStream" />
    <option name="METHOD_MATCHER_CONFIG" value="java.util.Formatter,format,java.io.Writer,append,com.google.common.base.Preconditions,checkNotNull,org.hibernate.Session,close,java.io.PrintWriter,printf,org.mockito.Mockito,mock|verify,org.mockito.stubbing.Stubber,when" />
  </inspection_tool>

idea-close-resources

Please merge my draft branch https://github.com/checkstyle/checkstyle/tree/i5752-close-resources to your code, together update will be good to merge I think.

@pbludov

pbludov commented May 6, 2018

Copy link
Copy Markdown
Member Author

I'm afk till 14 may, sorry.

@pbludov pbludov changed the title [WIP] Issue #5752: Activate checks related to java.io.Closeable issue #5752: Activate checks related to java.io.Closeable May 12, 2018
@pbludov

pbludov commented May 12, 2018

Copy link
Copy Markdown
Member Author

please use following config for IDEA

done.

@romani romani left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

items to improve and confirm:

/**
* Creates the audit listener.
* Creates the audit listener. The JDT compiler issues the warning explicitlyClosedAutoCloseable
* for {@code Files.newOutputStream}, so it need to be suppressed.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

this javadoc is public, let be more accurate here.

please remove "The JDT compiler issues the warning explicitlyClosedAutoCloseable ...." and make it like This method create in AuditListener open stream for validation data, it must be closed by {@link RootModule} (default implementation is {@link Checker}) by launching {@link AuditListener#auditFinished(AuditEvent)}

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

done

Comment thread config/intellij-idea-inspections.xml Outdated
<option name="ignoredTypes" value="java.io.ByteArrayOutputStream,java.util.stream.Stream,java.util.stream.IntStream,java.util.stream.LongStream,java.util.stream.DoubleStream,com.puppycrawl.tools.checkstyle.internal.utils.CloseAndFlushTestByteArrayOutputStream" />
<!-- False positives for the Closable returned from a builder method (which return "this").
Mock stubs shouldn't be closed. -->
<option name="METHOD_MATCHER_CONFIG" value="java.util.Formatter,format,java.io.Writer,append,com.google.common.base.Preconditions,checkNotNull,org.hibernate.Session,close,java.io.PrintWriter,printf,org.mockito.ArgumentCaptor,getValue,org.mockito.Mockito,mock|verify,org.mockito.stubbing.Stubber,when" />

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

getValue

it is not ok. We can resolve this bad code.

please review commits, sorry if they are messy, I can not squash in main repo:
2b0ac1b
9c6aa47
I refactored createListener to create streams when required getOutputStream(outputLocation) and getOutputStreamOptions(String outputLocation).

If it still messy, I will recreate branch.
If you have some concerns with such implementation, we can merge this PR, but discuss update in separate issue.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

done. Your code has been squashed to the PR.

@romani

romani commented May 12, 2018

Copy link
Copy Markdown
Member

eclipse is not happy.

@pbludov

pbludov commented May 13, 2018

Copy link
Copy Markdown
Member Author

eclipse is not happy.

done

@romani romani left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Last minor:

*
* This method creates in AuditListener an open stream for validation data, it must be closed by
* {@link RootModule} (default implementation is {@link Checker}) by calling
* {@link AuditListener#auditFinished(AuditEvent)}.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Please move explanation on why stream is not closed to getOutputStream(String outputLocation) .
Unfortunately there is no way to keep reason of suppression in same annotation, so javadoc is only place to keep reason of suppression

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

done

@romani romani left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@rnveach , please do final review

Comment thread config/intellij-idea-inspections.xml Outdated
Mock stubs shouldn't be closed. -->
<option name="METHOD_MATCHER_CONFIG" value="java.util.Formatter,format,java.io.Writer,append,com.google.common.base.Preconditions,checkNotNull,org.hibernate.Session,close,java.io.PrintWriter,printf,org.mockito.Mockito,mock|verify,org.mockito.stubbing.Stubber,when" />
</inspection_tool>
<!-- we are ok to use auto-unboxing as we use modern java -->

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

incorrect indentation, -1 space

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

done

<!-- we are ok to use auto-unboxing as we use modern java -->
<inspection_tool class="AutoCloseableResource" enabled="true" level="ERROR" enabled_by_default="true">
<!-- These classes do not contain any resources that need to be closed. -->
<option name="ignoredTypes" value="java.io.ByteArrayOutputStream,java.util.stream.Stream,java.util.stream.IntStream,java.util.stream.LongStream,java.util.stream.DoubleStream,com.puppycrawl.tools.checkstyle.internal.utils.CloseAndFlushTestByteArrayOutputStream" />

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

can we split all new lines so they are less than 100 characters where possible?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

if this is not obvious how to make, we can postpone it for later.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

done. If the CI fails, i'll revert this.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

<option name="ignoredTypes" value="java.io.ByteArrayOutputStream,java.util.stream.Stream,java.util.stream.IntStream,java.util.stream.LongStream,java.util.stream.DoubleStream,com.puppycrawl.tools.checkstyle.internal.utils.CloseAndFlushTestByteArrayOutputStream" />
<!-- False positives for the Closable returned from a builder method (which return "this").
Mock stubs shouldn't be closed. -->
<option name="METHOD_MATCHER_CONFIG" value="java.util.Formatter,format,java.io.Writer,append,com.google.common.base.Preconditions,checkNotNull,org.hibernate.Session,close,java.io.PrintWriter,printf,org.mockito.Mockito,mock|verify,org.mockito.stubbing.Stubber,when" />

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

same.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

if this is not obvious how to make, we can postpone it for later.

public void testNullInfoStreamOptions() {
try {
final DefaultLogger logger = new DefaultLogger(new ByteArrayOutputStream(), null);
assertNotNull("Null instance", logger);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

isn't this assertion unnecessary since eventually we will hit fail below? Also when can a new instance return null?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Without this assertion, the warning "The allocated object is never used" appears. See
https://travis-ci.org/checkstyle/checkstyle/jobs/378234050#L761
We need to use the logger somehow to make the eclipse compiler happy.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

This won't work:

    @Test
    public void testNullOutputStreamOptions() {
        try {
            new XMLLogger(outStream, null);
            fail("Exception was expected");
        }
        catch (IllegalArgumentException exception) {
            assertEquals("Invalid error message", "Parameter outputStreamOptions can not be null",
                    exception.getMessage());
        }
    }

If you have any idea how to do it right, let us know.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

happiness for all - is tough.
This nuance nobody will remember, it far from obvious.
What if we will put in assert message "Null instance; assert required to calm down eclipse's 'The allocated object is never used' violation" or just make single line comment above assert ?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

What if we will put in assert message "Null instance; assert required to calm down eclipse's 'The allocated object is never used' violation" or just make single line comment above assert ?

done

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This sounds familiar which we had to do with other tests.

try {
final DefaultLogger logger = new DefaultLogger(new ByteArrayOutputStream(),
AutomaticBean.OutputStreamOptions.CLOSE, new ByteArrayOutputStream(), null);
assertNotNull("Null instance", logger);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

same.

public void testNullOutputStreamOptions() {
try {
final XMLLogger logger = new XMLLogger(outStream, null);
assertNotNull("Null instance", logger);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

same

* @param messageFileName message file name.
* @param expected an array of expected messages.
* @throws Exception might happen
*/

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why is this documentation needed when no code was changed? This is a test area.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

yes, looks strange.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I believe that there was a suppression. Later, the code was refactored. The comment is removed now.

OutputStreamOptions errorStreamOptions,
AuditEventFormatter messageFormatter) {
if (infoStreamOptions == null) {
throw new IllegalArgumentException("Parameter infoStreamOptions can not be null");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Just curious, why are we adding these IAEs and do we need them in other areas?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Pitest. It says "the result may be replaced with null here

    private static AutomaticBean.OutputStreamOptions getOutputStreamOptions(String outputLocation) {
        final AutomaticBean.OutputStreamOptions result;
        if (outputLocation == null) {
            result = AutomaticBean.OutputStreamOptions.NONE;  // THIS line was red
        }
        else {
            result = AutomaticBean.OutputStreamOptions.CLOSE;
        }
        return result;
    }

The expression

closeStream = outputStreamOptions == OutputStreamOptions.CLOSE;

work just fine when the parameter outputStreamOptions is null.
It turns out that we can use an enumeration with just one value! The second value will be null.
This is logical, but wrong. I explicitly forbid null for these parameters.

@romani

romani commented May 17, 2018

Copy link
Copy Markdown
Member

@pbludov , please take a look at items to improve and confim. If smth is not clear let us know.

@rnveach rnveach left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can be merged when CI passes.

@romani romani merged commit effba27 into checkstyle:master May 18, 2018
@romani

romani commented May 18, 2018

Copy link
Copy Markdown
Member

Merged, thanks a lot to all

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.

4 participants