
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.
99 lines
2.8 KiB
Plaintext
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[]
|