/
jpinpoint-kotlin-rules.xml
165 lines (157 loc) · 8.37 KB
/
jpinpoint-kotlin-rules.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
<?xml version="1.0" encoding="UTF-8"?>
<ruleset name="jpinpoint-kotlin-rules"
xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 http://pmd.sourceforge.net/ruleset_2_0_0.xsd">
<description>
jPinpoint specific rules for performance aware Kotlin coding, sponsored by Rabobank.
</description>
<!-- IMPORTANT NOTICE: The content of this file is generated. Do not edit this file directly since changes may be lost when this file is regenerated! -->
<!-- BEGIN Included file 'common.xml' -->
<rule name="AvoidInMemoryStreamingDefaultConstructor"
since="7.0"
language="kotlin"
message="The default capacity or smaller is used for ByteArrayOutputStream or StringWriter, it usually needs expensive expansions."
class="net.sourceforge.pmd.lang.rule.XPathRule"
typeResolution="true"
externalInfoUrl="https://github.com/jborgers/PMD-jPinpoint-rules/tree/master/docs/JavaCodePerformance.md#isio01">
<description>
The default constructor of ByteArrayOutputStream creates a 32 bytes initial capacity and for StringWriter 16 chars. Problem: Such a small buffer as capacity usually needs several expensive expansions.
Solution: Presize the ByteArrayOutputStream or StringWriter with an initial capacity such that an expansion is not needed in most cases, typically much larger than 32, for instance 4096.
(jpinpoint-rules)
(jpinpoint-kotlin-rules)</description>
<priority>2</priority>
<properties>
<property name="tag" value="jpinpoint-rule" type="String" description="for-sonar"/>
<property name="version" value="3.1"/>
<property name="xpath">
<value><![CDATA[
//ImportHeader[.//T-Identifier[@Text='java'] and .//T-Identifier[@Text='io']]/ancestor::KotlinFile
//Expression//T-Identifier[(@Text='ByteArrayOutputStream' and ../../../
PostfixUnarySuffix//ValueArguments[not(ValueArgument) or ValueArgument//T-IntegerLiteral[number(@Text)<=32]])
or (@Text='StringWriter' and ../../../
PostfixUnarySuffix//ValueArguments[not(ValueArgument) or ValueArgument//T-IntegerLiteral[number(@Text)<=16]])]
]]>
</value>
</property>
</properties>
<example><![CDATA[
import java.io.ByteArrayOutputStream
import java.io.StringWriter
class AvoidInMemoryStreamingDefaultConstructor {
fun bad() {
var baos = ByteArrayOutputStream() //bad
val sw = StringWriter() //bad
baos = ByteArrayOutputStream(32) //bad - not larger than default
}
fun good() {
val baos = ByteArrayOutputStream(8192) // 8 kiB
val sw = StringWriter(2048)
}
}
]]>
</example>
</rule>
<rule name="AvoidStringBuffer" class="net.sourceforge.pmd.lang.rule.XPathRule"
since="7.0"
language="kotlin"
message="StringBuffer is used. It introduces locking overhead, use StringBuilder."
typeResolution="true"
externalInfoUrl="https://github.com/jborgers/PMD-jPinpoint-rules/tree/master/docs/JavaCodePerformance.md#isu01" >
<description>Problem: StringBuffer introduces locking overhead because it is thread safe. Its thread-safety is rarely needed.
Solution: Replace StringBuffer by StringBuilder. (jpinpoint-rules)</description>
<priority>3</priority>
<properties>
<property name="tag" value="jpinpoint-rule" type="String" description="for-sonar"/>
<property name="version" value="3.1"/>
<property name="xpath">
<value><![CDATA[
//VariableDeclaration/Type//T-Identifier[@Text='StringBuffer'],
//Declaration//PrimaryExpression//T-Identifier[@Text='StringBuffer']
]]>
</value>
</property>
</properties>
<example>
<![CDATA[
class AvoidStringBuffer {
var fieldSb: StringBuffer? = null // bad
fun bad() {
val sb = StringBuffer() // bad
}
fun good() {
val sb = StringBuilder()
}
]]>
</example>
</rule>
<!-- END Included file 'common.xml' -->
<!-- BEGIN Included file 'remoting.xml' -->
<rule name="AvoidDeprecatedHystrix"
since="7.0"
language="kotlin"
class="net.sourceforge.pmd.lang.rule.XPathRule"
message="Netflix Hystrix is deprecated. Use an alternative like resilience4j"
typeResolution="true"
externalInfoUrl="https://github.com/jborgers/PMD-jPinpoint-rules/tree/master/docs/JavaCodePerformance.md#ibi11">
<description>Problem: Hystrix is not actively maintained anymore.
Solution: Netflix recommends to use open source alternatives like resilience4j. (jpinpoint-rules)</description>
<priority>3</priority>
<properties>
<property name="tag" value="jpinpoint-rule" type="String" description="for-sonar"/>
<property name="version" value="3.1"/>
<property name="xpath">
<value><![CDATA[
//ImportHeader[starts-with(@joinTokenText, 'importcom.netflix.hystrix')]
]]>
</value>
</property>
</properties>
<example>
</example>
</rule>
<rule name="HttpClientBuilderWithoutDisableConnectionState"
since="7.0"
language="kotlin"
message="A HttpClient builder is used and disableConnectionState is not called. HTTP client tracks connection state while using TLS."
class="net.sourceforge.pmd.lang.rule.XPathRule"
typeResolution="true"
externalInfoUrl="https://github.com/jborgers/PMD-jPinpoint-rules/tree/master/docs/JavaCodePerformance.md#ibi07">
<description>
Problem: NTLM authenticated connections and SSL/TLS connections with client certificate authentication are stateful: they have a specific user identity/security context per session. If HttpClients have enabled connection state tracking which is the default, established TLS connections will not be reused because it is assumed that the user identity or security context may differ.
Then performance will suffer due to a full TLS handshake for each request.
Solution: HttpClients should disable connection state tracking in order to reuse TLS connections, since service calls for one pool have the same user identity/security context for all sessions. (jpinpoint-rules)
(jpinpoint-kotlin-rules)</description>
<priority>2</priority>
<properties>
<property name="tag" value="jpinpoint-rule" type="String" description="for-sonar"/>
<property name="version" value="3.1"/>
<property name="xpath">
<value><![CDATA[
(:locally created http client builder without disableConnectionState :)
//PostfixUnarySuffix//SimpleIdentifier/T-Identifier[@Text="custom"
and ancestor::PostfixUnaryExpression/PrimaryExpression/SimpleIdentifier/T-Identifier/@Text="HttpClients"
and not(ancestor::PostfixUnaryExpression/PostfixUnarySuffix/NavigationSuffix/SimpleIdentifier/T-Identifier/@Text="disableConnectionState")]
,
//PostfixUnarySuffix//SimpleIdentifier/T-Identifier[@Text="create"
and ancestor::PostfixUnaryExpression/PrimaryExpression/SimpleIdentifier/T-Identifier[(@Text="HttpClientBuilder" or @Text="HttpAsyncClientBuilder")
and not(ancestor::PostfixUnaryExpression/PostfixUnarySuffix/NavigationSuffix/SimpleIdentifier/T-Identifier/@Text="disableConnectionState")]]
,
(: method param http client builder without disableConnectionState :)
//FunctionValueParameter/Parameter/Type/TypeReference/UserType/SimpleUserType/SimpleIdentifier/T-Identifier[(@Text="HttpClients" or @Text="HttpClientBuilder" or @Text="HttpAsyncClientBuilder")
and not(ancestor::FunctionDeclaration//PostfixUnarySuffix/NavigationSuffix/SimpleIdentifier/T-Identifier/@Text="disableConnectionState")]
]]>
</value>
</property>
</properties>
<example><![CDATA[
private fun createHttpClientBuilder(properties: ConnectionProperties) =
HttpClients.custom()
.setDefaultRequestConfig(createRequestConfig(properties))
.setMaxConnTotal(properties.maxConnTotal)
.setMaxConnPerRoute(properties.maxConnPerRoute) // violation, no disableConnectionState() call
]]>
</example>
</rule>
<!-- END Included file 'remoting.xml' -->
</ruleset>