Skip to content

Conversation

pbludov
Copy link
Member

@pbludov pbludov commented Apr 22, 2018

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
@@ -17,8 +17,7 @@ if [ ! -f $ECJ_PATH ]; then
wget http://ftp-stud.fht-esslingen.de/pub/Mirrors/eclipse/eclipse/downloads/drops4/$ECJ_MAVEN_VERSION/$ECJ_JAR -O $ECJ_PATH
fi

mkdir -p target/classes
mkdir -p target/eclipse
mkdir -p target/classes target/test-classes target/eclipse
Copy link
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
Copy link

codecov-io commented Apr 22, 2018

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.

Copy link
Member

@romani romani left a comment

Choose a reason for hiding this comment

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

Items to improve:

@@ -609,6 +609,7 @@ private static Properties loadProperties(File file)
* @return a fresh new {@code AuditListener}
* @exception IOException when provided output location is not found
*/
@SuppressWarnings("resource")
Copy link
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
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.

Copy link
Member

@romani romani Apr 25, 2018

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) ?

@@ -69,6 +69,10 @@

private static final String ROOT_MODULE_NAME = "root";

/**
* Output stream to hold the test results.
* @noinspection resource
Copy link
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.

@@ -41,6 +41,10 @@
// -@cs[AbbreviationAsWordInName] Test should be named as its main class.
public class XMLLoggerTest extends AbstractXmlTestSupport {

/**
* Output stream to hold the test results.
* @noinspection resource
Copy link
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.

@@ -2151,6 +2153,9 @@ isolated classes and we cannot put them to separate package as it will affect us
<!-- XDocs UT is very long and complex -->
<option value="OverlyComplexBooleanExpression" />
<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
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
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
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.

Copy link
Member

@romani romani left a comment

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>
Copy link
Member

@romani romani Apr 25, 2018

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
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
Copy link
Member Author

pbludov commented Apr 26, 2018

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
Copy link
Member

romani commented May 2, 2018

@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
Copy link
Member Author

pbludov commented May 6, 2018

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
Copy link
Member Author

pbludov commented May 12, 2018

please use following config for IDEA

done.

Copy link
Member

@romani romani left a comment

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:

@@ -602,13 +602,15 @@ private static Properties loadProperties(File file)
}

/**
* 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
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
Member Author

Choose a reason for hiding this comment

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

done

<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
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
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
Copy link
Member

romani commented May 12, 2018

eclipse is not happy.

@pbludov
Copy link
Member Author

pbludov commented May 13, 2018

eclipse is not happy.

done

Copy link
Member

@romani romani left a comment

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
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
Member Author

Choose a reason for hiding this comment

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

done

Copy link
Member

@romani romani left a comment

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

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
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
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
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
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
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
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
Contributor

Choose a reason for hiding this comment

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

same.

Copy link
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
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
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
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
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
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
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
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
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
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
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
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.

@@ -176,7 +176,13 @@ public DefaultLogger(OutputStream infoStream,
OutputStream errorStream,
OutputStreamOptions errorStreamOptions,
AuditEventFormatter messageFormatter) {
if (infoStreamOptions == null) {
throw new IllegalArgumentException("Parameter infoStreamOptions can not be null");
Copy link
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
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
Copy link
Member

romani commented May 17, 2018

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

Copy link
Contributor

@rnveach rnveach left a comment

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
Copy link
Member

romani commented May 18, 2018

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