Merge branch 'pr-2803' into master
[java] Improve DoNotCallSystemExit (Fixes #2157) #2803
This commit is contained in:
@ -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)
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
}
|
@ -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>
|
Reference in New Issue
Block a user