Merge branch 'pr-2803' into master

[java] Improve DoNotCallSystemExit (Fixes #2157) #2803
This commit is contained in:
Andreas Dangel
2020-10-10 13:07:05 +02:00
4 changed files with 96 additions and 40 deletions

View File

@ -14,12 +14,23 @@ This is a {{ site.pmd.release_type }} release.
### New and noteworthy
#### Renamed Rules
* The Java rule {% rule "java/errorprone/DoNotCallSystemExit" %} has been renamed to
{% rule "java/errorprone/DoNotTerminateVM" %}, since it checks for all the following calls:
`System.exit(int)`, `Runtime.exit(int)`, `Runtime.halt(int)`. All these calls terminate
the Java VM, which is bad, if the VM runs an application server which many independent applications.
### Fixed Issues
* java-errorprone
* [#2157](https://github.com/pmd/pmd/issues/2157): \[java] Improve DoNotCallSystemExit: permit call in main(), flag System.halt
### API Changes
### External Contributions
* [#2803](https://github.com/pmd/pmd/pull/2803): \[java] Improve DoNotCallSystemExit (Fixes #2157) - [Vitaly Polonetsky](https://github.com/mvitaly)
* [#2809](https://github.com/pmd/pmd/pull/2809): \[java] Move test config from file to test class - [Stefan Birkner](https://github.com/stefanbirkner)
* [#2810](https://github.com/pmd/pmd/pull/2810): \[core] Move method "renderTempFile" to XMLRendererTest - [Stefan Birkner](https://github.com/stefanbirkner)

View File

@ -1296,42 +1296,7 @@ public class GCCall {
</example>
</rule>
<rule name="DoNotCallSystemExit"
language="java"
since="4.1"
message="System.exit() should not be used in J2EE/JEE apps"
class="net.sourceforge.pmd.lang.rule.XPathRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#donotcallsystemexit">
<description>
Web applications should not call System.exit(), since only the web container or the
application server should stop the JVM. This rule also checks for the equivalent call Runtime.getRuntime().exit().
</description>
<priority>3</priority>
<properties>
<property name="version" value="2.0"/>
<property name="xpath">
<value>
<![CDATA[
//Name[
starts-with(@Image,'System.exit')
or
(starts-with(@Image,'Runtime.getRuntime') and ../../PrimarySuffix[ends-with(@Image,'exit')])
]
]]>
</value>
</property>
</properties>
<example>
<![CDATA[
public void bar() {
System.exit(0); // never call this when running in an application server!
}
public void foo() {
Runtime.getRuntime().exit(0); // never stop the JVM manually, the container will do this.
}
]]>
</example>
</rule>
<rule name="DoNotCallSystemExit" ref="category/java/errorprone.xml/DoNotTerminateVM" deprecated="true" />
<rule name="DoNotExtendJavaLangThrowable"
language="java"
@ -1390,6 +1355,48 @@ public class MyActivity extends Activity {
</example>
</rule>
<rule name="DoNotTerminateVM"
language="java"
since="4.1"
message="System.exit() should not be used in J2EE/JEE apps"
class="net.sourceforge.pmd.lang.rule.XPathRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#donotterminatevm">
<description>
Web applications should not call `System.exit()`, since only the web container or the
application server should stop the JVM. Otherwise a web application would terminate all other applications
running on the same application server.
This rule also checks for the equivalent calls `Runtime.getRuntime().exit()` and `Runtime.getRuntime().halt()`.
This rule was called *DoNotCallSystemExit* until PMD 6.29.0.
</description>
<priority>3</priority>
<properties>
<property name="version" value="2.0"/>
<property name="xpath">
<value>
<![CDATA[
//Name[
starts-with(@Image,'System.exit')
or
(starts-with(@Image,'Runtime.getRuntime') and ../../PrimarySuffix[ends-with(@Image,'exit') or ends-with(@Image,'halt')])
][not(ancestor::MethodDeclaration[1][@Name="main" and @Static = true()])]
]]>
</value>
</property>
</properties>
<example>
<![CDATA[
public void bar() {
System.exit(0); // never call this when running in an application server!
}
public void foo() {
Runtime.getRuntime().exit(0); // never stop the JVM manually, the container will do this.
}
]]>
</example>
</rule>
<rule name="DoNotThrowExceptionInFinally"
language="java"
since="4.2"

View File

@ -1,4 +1,4 @@
/**
/*
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
@ -6,6 +6,6 @@ package net.sourceforge.pmd.lang.java.rule.errorprone;
import net.sourceforge.pmd.testframework.PmdRuleTst;
public class DoNotCallSystemExitTest extends PmdRuleTst {
public class DoNotTerminateVM extends PmdRuleTst {
// no additional unit tests
}

View File

@ -6,9 +6,15 @@
<test-code>
<description>basic violations</description>
<expected-problems>1</expected-problems>
<expected-problems>2</expected-problems>
<code><![CDATA[
public class Bar {
static {
// NEVER DO THIS IN A APP SERVER !!!
System.exit(0);
}
public void foo() {
// NEVER DO THIS IN A APP SERVER !!!
System.exit(0);
@ -32,14 +38,46 @@ public class SystemCall {
<test-code>
<description>basic violations with Runtime</description>
<expected-problems>1</expected-problems>
<expected-problems>2</expected-problems>
<code><![CDATA[
public class Bar {
public void foo() {
// NEVER DO THIS IN A APP SERVER !!!
Runtime.getRuntime().exit(0);
Runtime.getRuntime().halt(0);
}
}
]]></code>
</test-code>
<test-code>
<description>system exit in main</description>
<expected-problems>0</expected-problems>
<code><![CDATA[
public class SystemCall {
public static void main(String[] args) {
// OK in main()
System.exit(0);
}
}
]]></code>
</test-code>
<test-code>
<description>system exit in anonymous class inside main</description>
<expected-problems>1</expected-problems>
<code><![CDATA[
public class SystemCall {
public static void main(String[] args) {
new Runnable() {
public void run() {
// NEVER DO THIS IN A APP SERVER !!!
System.exit(0);
}
};
}
}
]]></code>
</test-code>
</test-data>