rspec/rules/S3345/java/rule.adoc
Fred Tingaud 16f6c0aecf
Inline adoc when include has no additional value (#1940)
Inline adoc files when they are included exactly once.

Also fix language tags because this inlining gives us better information
on what language the code is written in.
2023-05-25 14:18:12 +02:00

99 lines
2.8 KiB
Plaintext

== Why is this an issue?
The creation of a ``++JAXBContext.newInstance++`` is a costly operation, and should only be performed once per context and stored - preferably in a ``++static++`` member - for reuse.
In fact, according to the JAXB 2.2 Specification:
____
To avoid the overhead involved in creating a JAXBContext instance, a JAXB application is encouraged to reuse a JAXBContext instance. An implementation of abstract class JAXBContext is required to be thread-safe, thus, multiple threads in an application can share the same JAXBContext instance.
____
This rule raises an issue when multiple instances are created for the same context path.
=== Noncompliant code example
[source,java]
----
public void doSomething(List<MyObj> inputs) {
for (String input : inputs) {
Marshaller m = JAXBContext.newInstance(MyObj.class).createMarshaller(); // Noncompliant; context created in loop
// ...
}
}
public List<JAXBContext> getContexts(List<Class> inputs) {
List<JAXBContext> result = new ArrayList<>();
for (Class input : inputs) {
result.add(JAXBContext.newInstance(input); // Compliant; context path varies
}
return result;
}
public void doSomething2(List<MyObj> inputs) {
Marshaller m = JAXBContext.newInstance(MyObj.class).createMarshaller(); // Noncompliant; context created each time method invoked
for (String input : inputs) {
// ...
}
}
----
=== Compliant solution
[source,java]
----
private static JAXBContext context;
static {
try {
context = JAXBContext.newInstance(MyObj.class);
} catch (JAXBException e) {
// handle exception...
}
}
public void doSomething(List<MyObj> inputs) {
Marshaller m = context.createMarshaller();
for (String input : inputs) {
// ...
}
}
public List<JAXBContext> getContexts(List<Class> inputs) {
List<JAXBContext> result = new ArrayList<>();
for (Class input : inputs) {
result.add(JAXBContext.newInstance(input);
}
return result;
}
----
ifdef::env-github,rspecator-view[]
'''
== Implementation Specification
(visible only on this page)
=== Message
Store this "JAXBContext" in a "static" member and reuse it.
'''
== Comments And Links
(visible only on this page)
=== on 17 Sep 2015, 09:27:10 Ann Campbell wrote:
source: \https://twitter.com/CyrilP_tweet/status/644432004340150272?cn=cmVwbHk%3D&refsrc=email
=== on 14 Sep 2016, 08:12:35 Ann Campbell wrote:
From \https://groups.google.com/forum/#!topic/sonarqube/YGMsyzSkeQk:
In the past we've used a PMD XPath rule that looks like this "//MethodDeclaration//PrimaryExpression/PrimaryPrefix/Name[@Image='JAXBContext.newInstance'][ancestor::ClassOrInterfaceBodyDeclaration/Annotation/descendant::Name[contains(@Image,'SCOPE_PROTOTYPE')] or not(ancestor::ClassOrInterfaceBodyDeclaration/Annotation/descendant::Name[@Image='Bean'])]"
endif::env-github,rspecator-view[]