# Java - 1 Source: https://docs.codeant.ai/antipattern-rules/Java/java1 Learn about Java Anti-Patterns and How they help you write better code, and avoid common pitfalls.

Any extensible class might have subclasses located in a different package. When that happens, the use of \`this.getClass().getResource with a relative path would mean that the resource isn’t found for the child class.

Instead, use an absolute path or make the class final\`.

```java Bad theme={"system"} public class MyClass { private URL url = null; public MyClass(){ this.url = this.getClass().getResource("file.txt"); // Noncompliant } ``` ```java Fix theme={"system"} ```

Method or constructor references are more readable than lambda expressions in many situations, and may therefore be preferred.

However, method references are sometimes less concise than lambdas. In such cases, it might be preferrable to keep the lambda expression for better readability. Therefore, this rule only raises issues on lambda expressions where the replacement method reference is shorter.

This rule is automatically disabled when the project’s sonar.java.source is lower than 8, as lambda expressions were introduced in Java 8.

```java Bad theme={"system"} class A { void process(List list) { list.stream() .filter(myListValue -> myListValue instanceof B) // Noncompliant .map(listValueToMap -> (B) listValueToMap) // Noncompliant .map(bValueToMap -> bValueToMap.getObject()) // Noncompliant .forEach(o -> System.out.println(o)); // Noncompliant } } class B extends A { T getObject() { return null; } } ``` ```java Fix theme={"system"} class A { void process(List list) { list.stream() .filter(B.class::isInstance) // Compliant .map(B.class::cast) // Compliant .map(B::getObject) // Compliant .forEach(System.out::println); // Compliant } } class B extends A { T getObject() { return null; } } ```

The semantics of Thread and Runnable are different, and while it is technically correct to use Thread where a Runnable is expected, it is a bad practice to do so.

The crux of the issue is that Thread is a larger concept than Runnable. A Runnable represents a task. A Thread represents a task and its execution management (ie: how it should behave when started, stopped, resumed, …​). It is both a task and a lifecycle management.

```java Bad theme={"system"} public static void main(String[] args) { Thread runnable = new Thread() { @Override public void run() { /* ... */ } }; new Thread(runnable).start(); // Noncompliant } ``` ```java Fix theme={"system"} public static void main(String[] args) { Runnable runnable = new Runnable() { @Override public void run() { /* ... */ } }; new Thread(runnable).start(); } ```

There are two types of stream operations: intermediate operations, which return another stream, and terminal operations, which return something other than a stream. Intermediate operations are lazy, meaning they aren’t actually executed until and unless a terminal stream operation is performed on their results. Consequently, if the result of an intermediate stream operation is not fed to a terminal operation, it serves no purpose, which is almost certainly an error.

```java Bad theme={"system"} widgets.stream().filter(b -> b.getColor() == RED); // Noncompliant ``` ```java Fix theme={"system"} int sum = widgets.stream() .filter(b -> b.getColor() == RED) .mapToInt(b -> b.getWeight()) .sum(); Stream pipeline = widgets.stream() .filter(b -> b.getColor() == GREEN) .mapToInt(b -> b.getWeight()); sum = pipeline.sum(); ```

When directly subclassing \`java.io.InputStream or java.io.FilterInputStream, the only requirement is that you implement the method read(). However most uses for such streams don’t read a single byte at a time and the default implementation for read(byte\[],int,int) will call read(int) for every single byte in the array which can create a lot of overhead and is utterly inefficient. It is therefore strongly recommended that subclasses provide an efficient implementation of read(byte\[],int,int).

This rule raises an issue when a direct subclass of java.io.InputStream or java.io.FilterInputStream doesn’t provide an override of read(byte\[],int,int)\`.

```java Bad theme={"system"} public class MyInputStream extends java.io.InputStream { private FileInputStream fin; public MyInputStream(File file) throws IOException { fin = new FileInputStream(file); } @Override public int read() throws IOException { return fin.read(); } } ``` ```java Fix theme={"system"} public class MyInputStream extends java.io.InputStream { private FileInputStream fin; public MyInputStream(File file) throws IOException { fin = new FileInputStream(file); } @Override public int read() throws IOException { return fin.read(); } @Override public int read(byte[] b, int off, int len) throws IOException { return fin.read(b, off, len); } } ```

It’s slightly more efficient to append single characters to StringBuffer and StringBuilder instances as chars, than as Strings. That is, it’s more efficient to put a single char in single quotes, rather than double quotes.

```java Bad theme={"system"} StringBuilder sb = new StringBuilder(); sb.append("a"); // Noncompliant ``` ```java Fix theme={"system"} StringBuilder sb = new StringBuilder(); sb.append('a'); // Noncompliant ```

Early classes of the Java API, such as Vector, Hashtable and StringBuffer, were synchronized to make them thread-safe. However, synchronization has a significant negative impact on performance, even when using these collections from a single thread.

It is often best to use their non-synchronized counterparts:

  • ArrayList or LinkedList instead of Vector

  • Deque instead of Stack

  • HashMap instead of Hashtable

  • StringBuilder instead of StringBuffer

Even when used in synchronized contexts, you should think twice before using their synchronized counterparts, since their usage can be costly. If you are confident the usage is legitimate, you can safely ignore this warning.

```java Bad theme={"system"} Vector cats = new Vector<>(); ``` ```java Fix theme={"system"} ArrayList cats = new ArrayList<>(); ```

When java.io.File#delete fails, this boolean method simply returns false with no indication of the cause. On the other hand, when java.nio.file.Files#delete fails, this void method returns one of a series of exception types to better indicate the cause of the failure. And since more information is generally better in a debugging situation, java.nio.file.Files#delete is the preferred option.

```java Bad theme={"system"} public void cleanUp(Path path) { File file = new File(path); if (!file.delete()) { // Noncompliant //... } } ``` ```java Fix theme={"system"} public void cleanUp(Path path) throws NoSuchFileException, DirectoryNotEmptyException, IOException { Files.delete(path); } ```

This rule raises an issue when one of the method (with all similar methods):

  • \`as

  • describedAs

  • withFailMessage

  • overridingErrorMessage

  • usingComparator

  • usingElementComparator

  • extracting

  • filteredOn\`

is called without calling an AssertJ assertion afterward.

```java Bad theme={"system"} assertThat(actual).isEqualTo(expected).as("Description"); // Noncompliant assertThat(actual).isEqualTo(expected).withFailMessage("Fail message"); // Noncompliant assertThat(actual).isEqualTo(expected).usingComparator(new CustomComparator()); // Noncompliant ``` ```java Fix theme={"system"} assertThat(actual).as("Description").isEqualTo(expected); assertThat(actual).withFailMessage("Fail message").isEqualTo(expected); assertThat(actual).usingComparator(new CustomComparator()).isEqualTo(expected); ```

There is potential for confusion if an octal or hexadecimal escape sequence is immediately followed by other characters. Instead, such sequences should be terminated by either:

  • The start of another escape sequence.

  • The end of the string.

```java Bad theme={"system"} String hasHex = "\x41g"; // Noncompliant String hasOct = '\141t'; // Noncompliant ``` ```java Fix theme={"system"} String hasHex = "\x41" + "g"; // Compliant - terminated by end of literal String hasOct = "\x41\x67"; // Compliant - terminated by another escape ```

Placing the array designators \[] after the type helps maintain backward compatibility with older versions of the Java SE platform. This syntax contributes to better readability as it becomes easier to distinguish between array types and non-array types. It helps convey the intention of the method to both the developer implementing it and the developer using it.

```java Bad theme={"system"} public class Cube { private int magicNumbers[] = { 42 }; // Noncompliant public int getVector()[] { /* ... */ } // Noncompliant public int[] getMatrix()[] { /* ... */ } // Noncompliant } ``` ```java Fix theme={"system"} public class Cube { private int[] magicNumbers = { 42 }; // Compliant public int[] getVector() { /* ... */ } // Compliant public int[][] getMatrix() { /* ... */ } // Compliant } ```

Clear and communicative error messages help people understand what went wrong and how to correct the problem. However, care must be taken with \`Servlet error messages because they could expose sensitive information to an attacker. Even sending the user’s own data back to him in an error message could be risky; you never know who might catch a glimpse of the screen.

This rule checks that the strings used in servlet responses made from catch blocks don’t change from call to call. Ideally, such strings would be private static final\`, but that is not enforced by this rule. Logging messages are ignored by this rule.

```java Bad theme={"system"} public class MyServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String login = null; String pword try { login = login = request.getParameter("login"); pword = request.getParameter("password"); // ... } catch (LoginFailureException ex) { LOGGER.log(Level.INFO, "Login failure for " + login + ", " + pword); // Compliant, but not a good idea request.setAttribute("error", "Login failed for " + login + // Noncompliant; attacker now knows valid or nearly-valid login " with password " + pword); // Noncompliant; attacker now knows valid or nearly-valid password request.setAttribute("message", ex.getMessage()); // Noncompliant; could contain sensitive data getServletContext().getRequestDispatcher("/ErrorPage.jsp") .forward(request, response); ``` ```java Fix theme={"system"} public class MyServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String login = null; String pword try { login = login = request.getParameter("login"); pword = request.getParameter("password"); // ... } catch (LoginFailureException ex) { LOGGER.log(Level.INFO, "Login failure for " + login); // Much better request.setAttribute("error", "Login failed"); getServletContext().getRequestDispatcher("/ErrorPage.jsp") .forward(request, response); ```

Regular expressions are powerful but tricky, and even those long used to using them can make mistakes.

The following should not be used as regular expressions:

  • \`. - matches any single character. Used in replaceAll, it matches everything

  • | - normally used as an option delimiter. Used stand-alone, it matches the space between characters

  • File.separator\` - matches the platform-specific file path delimiter. On Windows, this will be taken as an escape character

```java Bad theme={"system"} String str = "/File|Name.txt"; String clean = str.replaceAll(".",""); // Noncompliant; probably meant to remove only dot chars, but returns an empty string String clean2 = str.replaceAll("|","_"); // Noncompliant; yields _/_F_i_l_e_|_N_a_m_e_._t_x_t_ String clean3 = str.replaceAll(File.separator,""); // Noncompliant; exception on Windows String clean4 = str.replaceFirst(".",""); // Noncompliant; String clean5 = str.replaceFirst("|","_"); // Noncompliant; String clean6 = str.replaceFirst(File.separator,""); // Noncompliant; ``` ```java Fix theme={"system"} ```

Spring \`@Controller, @Service, and @Repository classes are singletons by default, meaning only one instance of the class is ever instantiated in the application. Typically such a class might have a few static members, such as a logger, but all non-static members should be managed by Spring and supplied via constructor injection rather than by field injection.

This rule raise an issue when any non-static\` member of a Spring component has an injection annotation.

```java Bad theme={"system"} @Controller public class HelloWorld { @Autowired private String name = null; // Noncompliant } ``` ```java Fix theme={"system"} @Controller public class HelloWorld { private String name = null; HelloWorld(String name) { this.name = name; } } ```

\`Object.finalize() is called by the Garbage Collector at some point after the object becomes unreferenced.

In general, overloading Object.finalize() is a bad idea because:

  • The overload may not be called by the Garbage Collector.

  • Users are not expected to call Object.finalize() and will get confused.

But beyond that it’s a terrible idea to name a method "finalize" if it doesn’t actually override Object.finalize()\`.

```java Bad theme={"system"} public int finalize(int someParameter) { // Noncompliant /* ... */ } ``` ```java Fix theme={"system"} public int someBetterName(int someParameter) { // Compliant /* ... */ } ```

The ThreadGroup class contains many deprecated methods like allowThreadSuspension, resume, stop, and suspend. Also, some of the non-deprecated methods are obsolete or not thread-safe, and still others are insecure (activeCount, enumerate). For these reasons, any use of ThreadGroup is suspicious and should be avoided.

```java Bad theme={"system"} class NetworkHandler { void startThreadInGroup(ThreadGroup tg) { // Noncompliant, use an ExecutorService instead, which is more secure Thread thread = new Thread(tg, "controller"); thread.start(); } } ``` ```java Fix theme={"system"} class NetworkHandler { void handleThreadsProperly() { ThreadFactory threadFactory = Executors.defaultThreadFactory(); ThreadPoolExecutor executorPool = new ThreadPoolExecutor(3, 10, 5, TimeUnit.SECONDS, new ArrayBlockingQueue(2), threadFactory); for (int i = 0; i < 10; i++) { executorPool.execute(new Thread("Job: " + i)); } executorPool.shutdown(); } } ```

The default implementation of java.lang.Thread 's run will only perform a task passed as a Runnable. If no Runnable has been provided at construction time, then the thread will not perform any action.

When extending java.lang.Thread, you should override the run method or pass a Runnable target to the constructor of java.lang.Thread.

```java Bad theme={"system"} public class MyThread extends Thread { // Noncompliant public void doSomething() { System.out.println("Hello, World!"); } } ``` ```java Fix theme={"system"} public class MyThread extends Thread { @Override public void run() { System.out.println("Hello, World!"); } } ```

Perhaps counter-intuitively, a compareTo method is expected to throw a NullPointerException if passed a null argument, and a ClassCastException if the argument is of the wrong type. So there’s no need to null-test or type-test the argument.

```java Bad theme={"system"} public int compareTo(Object obj) { if (obj == null) { // Noncompliant return -1; } if (! obj instanceof MyClass.class) { // Noncompliant return -1; } MyObject myObj = (MyObject) obj; // ... } ``` ```java Fix theme={"system"} public int compareTo(Object obj) { MyObject myObj = (MyObject) obj; // ... } ```

Looking for a given substring starting from a specified offset can be achieved by such code: \`str.substring(beginIndex).indexOf(char1). This works well, but it creates a new String for each call to the substring method. When this is done in a loop, a lot of Strings are created for nothing, which can lead to performance problems if str is large.

To avoid performance problems, String.substring(beginIndex) should not be chained with the following methods:

  • indexOf(int ch)

  • indexOf(String str)

  • lastIndexOf(int ch)

  • lastIndexOf(String str)

  • startsWith(String prefix)

For each of these methods, another method with an additional parameter is available to specify an offset.

Using these methods will avoid the creation of additional String\` instances. For indexOf methods, adjust the returned value by subtracting the substring index parameter to obtain the same result.

```java Bad theme={"system"} str.substring(beginIndex).indexOf(char1); // Noncompliant; a new String is going to be created by "substring" ``` ```java Fix theme={"system"} str.indexOf(char1, beginIndex) - beginIndex; // index for char1 not found is (-1-beginIndex) ```

Stream operations are divided into intermediate and terminal operations, and are combined to form stream pipelines. After the terminal operation is performed, the stream pipeline is considered consumed, and cannot be used again. Such a reuse will yield unexpected results.

```java Bad theme={"system"} Stream pipeline = widgets.stream().filter(b -> b.getColor() == RED); int sum1 = pipeline.sum(); int sum2 = pipeline.mapToInt(b -> b.getWeight()).sum(); // Noncompliant ``` ```java Fix theme={"system"} ```

Adding messages to JUnit, FEST and AssertJ assertions is an investment in your future productivity. Spend a few seconds writing them now, and you’ll save a lot of time on the other end when either the tests fail and you need to quickly diagnose the problem, or when you need to maintain the tests and the assertion messages work as a sort of documentation.

```java Bad theme={"system"} assertEquals(4, list.size()); // Noncompliant try { fail(); // Noncompliant } catch (Exception e) { assertThat(list.get(0)).isEqualTo("pear"); // Noncompliant } ``` ```java Fix theme={"system"} assertEquals("There should have been 4 Fruits in the list", 4, list.size()); try { fail("And exception is expected here"); } catch (Exception e) { assertThat(list.get(0)).as("check first element").overridingErrorMessage("The first element should be a pear, not a %s", list.get(0)).isEqualTo("pear"); } ```

\`@ComponentScan is used to find which Spring @Component beans (@Service or @Repository or Controller) are available in the classpath so they can be used in the application context. This is a convenient feature especially when you begin a new project but it comes with the drawback of slowing down the application start-up time especially when the application becomes bigger (ie: it references a large JAR file, or it references a significant number of JAR files, or the base-package refers to a large amount of .class files).

@ComponentScan should be replaced by an explicit list of Spring beans loaded by @Import.

The interface @SpringBootApplication is also considered by this rule because it is annotated with @ComponentScan\`.

```java Bad theme={"system"} @ComponentScan public class MyApplication { ... } @SpringBootApplication public class MyApplication { ... } ``` ```java Fix theme={"system"} @Configuration @Import({ DispatcherServletAutoConfiguration.class, ErrorMvcAutoConfiguration.class, HttpEncodingAutoConfiguration.class, HttpMessageConvertersAutoConfiguration.class, MultipartAutoConfiguration.class, ServerPropertiesAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class, WebMvcAutoConfiguration.class }) public class MyApplication { ... } ```

When you need to perform a complicated initialization of a static member, it should be done in a static initializer block. That’s because such blocks are only executed when the class is loaded into the JVM. That is, they run only once, and that happens before any instances are created. Non-static blocks, on the other hand, run once for each instance that’s created, so any static members "initialized" in such a block will be re-set for each new instance.

```java Bad theme={"system"} public class MyClass { private static List names = new ArrayList<>(); { names.add("foo"); // Noncompliant } ``` ```java Fix theme={"system"} public class MyClass { private static List names = new ArrayList<>(); static { names.add("foo"); } ```

In Java 15 Text Blocks are now official and can be used. The most common pattern for multiline strings in Java \< 15 was to write String concatenation. Now it’s possible to do it in a more natural way using Text Blocks.

```java Bad theme={"system"} String textBlock = "\n" + " \n" + " \n" + " \n" + " \n" + ""; ``` ```java Fix theme={"system"} String textBlock = """ """; ```

When testing exception via org.junit.rules.ExpectedException any code after the raised exception will not be executed, so adding subsequent assertions is wrong and misleading. This rule raises an issue when an assertion is done after the "expect(…​)" invocation, only the code throwing the expected exception should be after "expect(…​)".

You should consider using org.junit.Assert.assertThrows instead, it’s available since JUnit 4.13 and it allows additional subsequent assertions.

```java Bad theme={"system"} @Rule public ExpectedException thrown = ExpectedException.none(); @Test public void test() throws IndexOutOfBoundsException { thrown.expect(IndexOutOfBoundsException.class); // Noncompliant Object o = get(); // This test pass since execution will never get past this line. Assert.assertEquals(0, 1); } private Object get() { throw new IndexOutOfBoundsException(); } ``` ```java Fix theme={"system"} Assert.assertThrows(IndexOutOfBoundsException.class, () -> get()); // This test correctly fails. Assert.assertEquals(0, 1); ```

Spring provides two options to mark a REST parameter as optional:

  1. Use required = false in the @PathVariable or @RequestParam annotation of the respective method parameter or

  2. Use type java.util.Optional\ for the method parameter

When using 1., the absence of the parameter, when the REST function is called, is encoded by null, which can only be used for object types. If required = false is used for a parameter with a primitive and the REST function is called without the parameter, a runtime exception occurs because the Spring data mapper cannot map the null value to the parameter.

```java Bad theme={"system"} @RequestMapping(value = {"/article", "/article/{id}"}) public Article getArticle(@PathVariable(required = false) int articleId) { // Noncompliant, null cannot be mapped to int //... } ``` ```java Fix theme={"system"} @RequestMapping(value = {"/article", "/article/{id}"}) public Article getArticle(@PathVariable(required = false) Integer articleId) { // Compliant //... } ```

Assertion methods are throwing a "`java.lang.AssertionError`". If this call is done within the try block of a try-catch cathing a similar error, you should make sure to test some properties of the exception. Otherwise, the assertion will never fail.

```java Bad theme={"system"} @Test public void should_throw_assertion_error() { try { throwAssertionError(); Assert.fail("Expected an AssertionError!"); // Noncompliant, the AssertionError will be caught and the test will never fail. } catch (AssertionError e) {} } private void throwAssertionError() { throw new AssertionError("My assertion error"); } ``` ```java Fix theme={"system"} assertThrows(AssertionError.class, () -> throwAssertionError()); ```

If the credentials provider is not specified when creating a new AwsClient with an AwsClientBuilder, the AWS SDK will execute some logic to identify it automatically.

While it will probably identify the correct one, this extra logic will slow down startup time, already known to be a hotspot.

You should therefore always define the logic to set the credentials provider yourself. This is typically done by retrieving it from the Lambda provided environment variable.

This will make the code more explicit and spare initialization time.

This rule reports an issue when the credentials provider is not set when creating an AwsClient.

```java Bad theme={"system"} S3Client.builder() .region(Region.of(System.getenv(SdkSystemSetting.AWS_REGION.environmentVariable()))) .build(); ``` ```java Fix theme={"system"} S3Client.builder() .region(Region.of(System.getenv(SdkSystemSetting.AWS_REGION.environmentVariable())) .credentialsProvider(EnvironmentVariableCredentialsProvider.create()) .build(); ```

Standard applications don’t require a display refresh rate above 60Hz, hence it is advisable to avoid higher frequencies to avoid unnecessary energy consumption.

The rule flags an issue when setFrameRate() is invoked with a frameRate higher than 60Hz for android.view\.Surface and android.view\.SurfaceControl.Transaction.

It’s important to note that the scheduler considers several factors when determining the display refresh rate. Therefore, using setFrameRate() doesn’t guarantee your app will achieve the requested frame rate.

```java Bad theme={"system"} public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); SurfaceView surfaceView = findViewById(R.id.my_surface_view); Surface surface = surfaceView.getHolder().getSurface(); surface.setFrameRate(90.0f, Surface.FRAME_RATE_COMPATIBILITY_FIXED_SOURCE); // Noncompliant } } ``` ```java Fix theme={"system"} public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); SurfaceView surfaceView = findViewById(R.id.my_surface_view); Surface surface = surfaceView.getHolder().getSurface(); surface.setFrameRate(60.0f, Surface.FRAME_RATE_COMPATIBILITY_FIXED_SOURCE); // Compliant } } ```

Once set, the value of a Hibernate @Entity's @Id field/column should never be updated. Therefore, setters for such fields should always be private.

```java Bad theme={"system"} public class Book { @Id @GeneratedValue private int id; public void setId(int id) { // Noncompliant this.id = id; } ``` ```java Fix theme={"system"} public class Book { @Id @GeneratedValue private int id; private void setId(int id) { this.id = id; } ```

According to the API documentation of the HttpServletRequest.getRequestedSessionId() method:

Returns the session ID specified by the client. This may not be the same as the ID of the current valid session for this request. If the client did not specify a session ID, this method returns null.

The session ID it returns is either transmitted through a cookie or a URL parameter. This allows an end user to manually update the value of this session ID in an HTTP request.

Due to the ability of the end-user to manually change the value, the session ID in the request should only be used by a servlet container (e.g. Tomcat or Jetty) to see if the value matches the ID of an existing session. If it does not, the user should be considered unauthenticated.

```java Bad theme={"system"} if (isActiveSession(request.getRequestedSessionId())) { // Noncompliant // ... } ``` ```java Fix theme={"system"} if (isActiveSession(request.getSession().getId())) { // ... } ```

The use of a "RESOURCE\_LOCAL" persistence-unit makes you responsible for your own entity management, which involves a lot of extra boilerplate code to get right. Instead, set this to "JPA" in a JavaSE environment or omit it altogether in a JavaEE environment, where "JPA" is the default.

```java Bad theme={"system"} ``` ```java Fix theme={"system"} ```

The PreparedStatement is frequently used in loops because it allows to conveniently set parameters. A small optimization is possible by setting constant parameters outside the loop or hard-coding them in the query whenever possible.

```java Bad theme={"system"} public class DatabaseExample { public record Order(String id, BigDecimal price) {} public void updateTodayOrders(Connection connection, List orders) { Date today = java.sql.Date.valueOf(LocalDate.now()); String insertQuery = "INSERT INTO Order (id, price, executionDate) VALUES (?, ?, ?)"; PreparedStatement preparedStatement = connection.prepareStatement(SQL_INSERT); for(Order order: orders) { preparedStatement.setString(1, order.id()); preparedStatement.setString(2, order.price()); preparedStatement.setDate(3, today); // Noncompliant preparedStatement.executeUpdate(); } } } ``` ```java Fix theme={"system"} public class DatabaseExample { public record Order(String id, BigDecimal price) {} public void updateTodayOrders(Connection connection, List orders) { Date today = java.sql.Date.valueOf(LocalDate.now()); String insertQuery = "INSERT INTO Order (id, price, executionDate) VALUES (?, ?, ?)"; preparedStatement.setDate(3, today); // Compliant PreparedStatement preparedStatement = connection.prepareStatement(SQL_INSERT); for(Order order: orders) { preparedStatement.setString(1, order.id()); preparedStatement.setString(2, order.price()); preparedStatement.executeUpdate(); } } } ```

Operations performed on a string with predictable outcomes should be avoided. For example:

  • checking if a string contains itself

  • comparing a string with itself

  • matching a string against itself

  • creating a substring from 0 to the end of the string

  • creating a substring from the end of the string

  • replacing a string with itself

  • replacing a substring with the exact substring

```java Bad theme={"system"} String speech = "SonarQube is the best static code analysis tool." String s1 = speech.substring(0); // Noncompliant - yields the whole string String s2 = speech.substring(speech.length()); // Noncompliant - yields ""; String s3 = speech.substring(5, speech.length()); // Noncompliant - use the 1-arg version instead if (speech.contains(speech)) { // Noncompliant - always true // ... } ``` ```java Fix theme={"system"} String speech = "SonarQube is the best static code analysis tool." String s1 = speech; String s2 = ""; String s3 = speech.substring(5); // ... ```

The fields in an HTTP request are putty in the hands of an attacker, and you cannot rely on them to tell you the truth about anything. While it may be safe to store such values after they have been neutralized, decisions should never be made based on their contents.

This rule flags uses of the referer header field.

```java Bad theme={"system"} public class MyServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String referer = request.getHeader("referer"); // Noncompliant if(isTrustedReferer(referer)){ //.. } //... } } ``` ```java Fix theme={"system"} ```

In java 7 to 9, FileInputStream and FileOutputStream rely on finalization to perform final closes if the stream is not already closed. Whether or not the stream is already closed, the finalizer will be called, resulting in extra work for the garbage collector. This can easily be avoided using the Files API.

```java Bad theme={"system"} try(FileInputStream fis = new FileInputStream(...)) { // Noncompliant } finally { } ``` ```java Fix theme={"system"} try(InputStream is = Files.newInputStream(...)) { } finally { } ```

Two classes can have the same simple name if they are in two different packages.

```java Bad theme={"system"} package org.foo.domain; public class User { // .. } ``` ```java Fix theme={"system"} package org.foo.presentation; public class User { // .. } ```

The Comparable.compareTo method returns a negative integer, zero, or a positive integer to indicate whether the object is less than, equal to, or greater than the parameter. The sign of the return value or whether it is zero is what matters, not its magnitude.

Returning a positive or negative constant value other than the basic ones (-1, 0, or 1) provides no additional information to the caller. Moreover, it could potentially confuse code readers who are trying to understand its purpose.

```java Bad theme={"system"} public int compareTo(Name name) { if (condition) { return Integer.MIN_VALUE; // Noncompliant } } ``` ```java Fix theme={"system"} public int compareTo(Name name) { if (condition) { return -1; // Compliant } } ```

There is no good reason to declare a field "public" and "static" without also declaring it "final". Most of the time this is a kludge to share a state among several objects. But with this approach, any object can do whatever it wants with the shared state, such as setting it to null.

```java Bad theme={"system"} public class Greeter { public static Foo foo = new Foo(); ... } ``` ```java Fix theme={"system"} public class Greeter { public static final Foo FOO = new Foo(); ... } ```

A try-catch block is used to handle exceptions or errors that may occur during the execution of a block of code. It allows you to catch and handle exceptions gracefully, preventing your program from terminating abruptly.

The code that may throw an exception is enclosed within the try block, while each catch block specifies the type of exception it can handle. The corresponding catch block is executed if the exception matches the type specified in any catch block. It is unnecessary to manually check the types using instanceof because Java automatically matches the exception type to the appropriate catch block based on the declared exception type in the catch clauses.

```java Bad theme={"system"} try { /* ... */ } catch (Exception e) { if(e instanceof IOException) { /* ... */ } // Noncompliant if(e instanceof NullPointerException{ /* ... */ } // Noncompliant } ``` ```java Fix theme={"system"} try { /* ... */ } catch (IOException e) { /* ... */ } // Compliant } catch (NullPointerException e) { /* ... */ } // Compliant ```

For optimal code readability, annotation arguments should be specified in the same order that they were declared in the annotation definition.

```java Bad theme={"system"} @interface Pet { String name(); String surname(); } @Pet(surname ="", name="") // Noncompliant ``` ```java Fix theme={"system"} @interface Pet { String name(); String surname(); } @Pet(name ="", surname="") // Compliant ```

Assertions comparing incompatible types always fail, and negative assertions always pass. At best, negative assertions are useless. At worst, the developer loses time trying to fix his code logic before noticing wrong assertions.

Dissimilar types are:

  • comparing a primitive with null

  • comparing an object with an unrelated primitive (E.G. a string with an int)

  • comparing unrelated classes

  • comparing an array to a non-array

  • comparing two arrays of dissimilar types

This rule also raises issues for unrelated class and interface or unrelated interface types in negative assertions. Because except in some corner cases, those types are more likely to be dissimilar. And inside a negative assertion, there is no test failure to inform the developer about this unusual comparison.

Supported test frameworks:

  • JUnit4

  • JUnit5

  • AssertJ

```java Bad theme={"system"} interface KitchenTool {} interface Plant {} class Spatula implements KitchenTool {} class Tree implements Plant {} void assertValues(int size, Spatula spatula, KitchenTool tool, KitchenTool[] tools, Tree tree, Plant plant, Tree[] trees) { // Whatever the given values, those negative assertions will always pass due to dissimilar types: assertThat(size).isNotNull(); // Noncompliant; primitives can not be null assertThat(spatula).isNotEqualTo(tree); // Noncompliant; unrelated classes assertThat(tool).isNotSameAs(tools); // Noncompliant; array & non-array assertThat(trees).isNotEqualTo(tools); // Noncompliant; incompatible arrays // Those assertions will always fail assertThat(size).isNull(); // Noncompliant assertThat(spatula).isEqualTo(tree); // Noncompliant // Those negative assertions are more likely to always pass assertThat(spatula).isNotEqualTo(plant); // Noncompliant; unrelated class and interface assertThat(tool).isNotEqualTo(plant); // Noncompliant; unrelated interfaces } ``` ```java Fix theme={"system"} ```

The location awareness feature can significantly drain the device’s battery.

The recommended way to maximize the battery life is to use the fused location provider which combines signals from GPS, Wi-Fi, and cell networks, as well as accelerometer, gyroscope, magnetometer and other sensors. The FusedLocationProviderClient automatically chooses the best method to retrieve a device’s location based on the device’s context.

The rule flags an issue when android.location.LocationManager or com.google.android.gms.location.LocationClient is used instead of com.google.android.gms.location.FusedLocationProviderClient.

```java Bad theme={"system"} public class LocationsActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { // ... LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE); // Noncompliant LocationListener locationListener = new LocationListener() { public void onLocationChanged(Location location) { // Use the location object as needed } }; locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener); } } ``` ```java Fix theme={"system"} public class LocationsActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { // ... FusedLocationProviderClient fusedLocationClient = LocationServices.getFusedLocationProviderClient(this); // Compliant fusedLocationClient.getLastLocation() .addOnSuccessListener(this, location -> { // Use the location object as needed }); } } ```

Creating temporary primitive wrapper objects only for String conversion or the use of the compareTo() method is inefficient.

Instead, the static toString() or compare() method of the primitive wrapper class should be used.

```java Bad theme={"system"} private int isZero(int value){ return Integer.valueOf(value).compareTo(0); // Noncompliant } private String convert(int value){ return Integer.valueOf(value).toString(); // Noncompliant } ``` ```java Fix theme={"system"} private int isZero(int value){ return Integer.compare(value, 0); // Compliant } private String convert(int value){ return Integer.toString(value); // Compliant } ```

Referencing a static member of a subclass from its parent during class initialization, makes the code more fragile and prone to future bugs. The execution of the program will rely heavily on the order of initialization of classes and their static members.

```java Bad theme={"system"} class Parent { static int field1 = Child.method(); // Noncompliant static int field2 = 42; public static void main(String[] args) { System.out.println(Parent.field1); // will display "0" instead of "42" } } class Child extends Parent { static int method() { return Parent.field2; } } ``` ```java Fix theme={"system"} ```

An indexOf or lastIndexOf call with a single letter String can be made more performant by switching to a call with a char argument.

```java Bad theme={"system"} String myStr = "Hello World"; // ... int pos = myStr.indexOf("W"); // Noncompliant // ... int otherPos = myStr.lastIndexOf("r"); // Noncompliant // ... ``` ```java Fix theme={"system"} String myStr = "Hello World"; // ... int pos = myStr.indexOf('W'); // ... int otherPos = myStr.lastIndexOf('r'); // ... ```

This rule allows you to track the use of the PMD suppression comment mechanism.

```java Bad theme={"system"} // NOPMD ``` ```java Fix theme={"system"} ```

s keys will be valid until you manually revoke them. This makes them highly sensitive as any exposure can have serious consequences and should be used with care.

This rule will trigger when encountering an instantiation of com.amazonaws.auth.BasicAWSCredentials.

```java Bad theme={"system"} BasicSessionCredentials sessionCredentials = new BasicSessionCredentials( session_creds.getAccessKeyId(), session_creds.getSecretAccessKey(), session_creds.getSessionToken()); ``` ```java Fix theme={"system"} ```

Using boxed type suggests that null is a possible value for the variable. Use of the primitive type should be preferred if this is not the case to avoid any confusion about possible values variable can contain.

```java Bad theme={"system"} Integer x = 5; ``` ```java Fix theme={"system"} int x = 5; ```

Appending String.valueOf() to a String decreases the code readability.

The argument passed to String.valueOf() should be directly appended instead.

```java Bad theme={"system"} String message = "Output is " + String.valueOf(12); ``` ```java Fix theme={"system"} String message = "Output is " + 12; ```

Programming languages evolve over time, and new versions of Java introduce additional keywords. If future keywords are used in the current code, it can create compatibility issues when transitioning to newer versions of Java. The code may fail to compile or behave unexpectedly due to conflicts with newly introduced keywords.

The following keywords are marked as invalid identifiers:

Keyword Added in version

\_

9

enum

5.0

assert and strictfp are another example of valid identifiers which became keywords in later versions, but are not supported by this rule.

```java Bad theme={"system"} public class MyClass { int enum = 42; // Noncompliant String _ = ""; // Noncompliant } ``` ```java Fix theme={"system"} public class MyClass { int magic = 42; // Noncompliant String s = ""; // Noncompliant } ```

Boxing is the process of putting a primitive value into a wrapper object, such as creating an Integer to hold an int value. Unboxing is the process of retrieving the primitive value from such an object. Since the original value is unchanged during boxing and unboxing, there is no point in doing either when not needed.

Instead, you should rely on Java’s implicit boxing/unboxing to convert from the primitive type to the wrapper type and vice versa, for better readability.

```java Bad theme={"system"} public void examinePrimitiveInt(int a) { //... } public void examineBoxedInteger(Integer a) { // ... } public void func() { int primitiveInt = 0; Integer boxedInt = Integer.valueOf(0); double d = 1.0; int dIntValue = Double.valueOf(d).intValue(); // Noncompliant; should be replaced with a simple cast examinePrimitiveInt(boxedInt.intValue()); // Noncompliant; unnecessary unboxing examinePrimitiveInt(Integer.valueOf(primitiveInt)); // Noncompliant; boxed int will be auto-unboxed examineBoxedInteger(Integer.valueOf(primitiveInt)); // Noncompliant; unnecessary boxing examineBoxedInteger(boxedInt.intValue()); // Noncompliant; unboxed int will be autoboxed } ``` ```java Fix theme={"system"} public void examinePrimitiveInt(int a) { //... } public void examineBoxedInteger(Integer a) { // ... } public void func() { int primitiveInt = 0; Integer boxedInt = Integer.valueOf(0); double d = 1.0; int dIntValue = (int) d; examinePrimitiveInt(primitiveInt); examinePrimitiveInt(boxedInt); examineBoxedInteger(primitiveInt); examineBoxedInteger(boxedInt); } ```

As stated per effective java :

Varargs methods are a convenient way to define methods that require a variable number of arguments, but they should not be overused. They can produce confusing results if used inappropriately.

```java Bad theme={"system"} void fun ( String... strings ) // Noncompliant { // ... } ``` ```java Fix theme={"system"} ```

According to the Java Language Specification, there is a contract between \`equals(Object) and hashCode():

If two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce the same integer result.

It is not required that if two objects are unequal according to the equals(java.lang.Object) method, then calling the hashCode\` method on each of the two objects must produce distinct integer results.

However, the programmer should be aware that producing distinct integer results for unequal objects may improve the performance of hashtables.

In order to comply with this contract, those methods should be either both inherited, or both overridden.

```java Bad theme={"system"} class MyClass { // Noncompliant - should also override "hashCode()" @Override public boolean equals(Object obj) { /* ... */ } } ``` ```java Fix theme={"system"} class MyClass { // Compliant @Override public boolean equals(Object obj) { /* ... */ } @Override public int hashCode() { /* ... */ } } ```

Each constructor must first invoke a parent class constructor, but it doesn’t always have to be done explicitly. If the parent class has a reachable, no-args constructor, a call to it will be inserted automatically by the compiler. Thus, calls to super() can be omitted.

```java Bad theme={"system"} public class MyClass { private Foo foo; public MyClass (Foo foo) { super(); // Noncompliant this.foo = foo; } ``` ```java Fix theme={"system"} public class MyClass { private Foo foo; public MyClass (Foo foo) { this.foo = foo; } ```

The \`setUp() and tearDown() methods (initially introduced with JUnit3 to execute a block of code before and after each test) need to be correctly annotated with the equivalent annotation in order to preserve the same behavior when migrating from JUnit3 to JUnit4 or JUnit5.

This rule consequently raise issues on setUp() and tearDown()\` methods which are not annotated in test classes.

```java Bad theme={"system"} public void setUp() { ... } // Noncompliant; should be annotated with @Before public void tearDown() { ... } // Noncompliant; should be annotated with @After ``` ```java Fix theme={"system"} public void setUp() { ... } // Noncompliant; should be annotated with @BeforeEach public void tearDown() { ... } // Noncompliant; should be annotated with @AfterEach ```

A cleanly coded web application will have a clear separation of concerns, with business logic in the \`@Service layer, and communication with other systems in the data access layer.

To help enforce such a separation of concerns, this rule raises an issue when a @Service class has RestTemplate, JmsTemplate, WebServiceTemplate, JdbcTemplate, or DataSource\` member.

```java Bad theme={"system"} @Service ("greetingmanager") public class GreetingManagerImpl implements GreetingManager { @Autowired DataSource ds; // Noncompliant ``` ```java Fix theme={"system"} @Service ("greetingmanager") public class GreetingManagerImpl implements GreetingManager { @Autowired GreetingDao gdao; // DataSource and its use have been moved here ```

The equals and hashCode methods of java.net.URL may trigger a name service lookup (typically DNS) to resolve the hostname or IP address. Depending on the configuration, and network status, this lookup can be time-consuming.

On the other hand, the URI class does not perform such lookups and is a better choice unless you specifically require the functionality provided by URL.

In general, it is better to use the URI class until access to the resource is actually needed, at which point you can convert the URI to a URL using URI.toURL().

This rule checks for uses of URL 's in Map and Set , and for explicit calls to the equals and hashCode methods. It suggests reconsidering the use of URL in such scenarios to avoid potential performance issues related to name service lookups.

```java Bad theme={"system"} public void checkUrl(URL url) { Set sites = new HashSet(); // Noncompliant URL homepage = new URL("http://sonarsource.com"); // Compliant if (homepage.equals(url)) { // Noncompliant // ... } } ``` ```java Fix theme={"system"} public void checkUrl(URL url) { Set sites = new HashSet(); // Compliant URI homepage = new URI("http://sonarsource.com"); // Compliant URI uri = url.toURI(); if (homepage.equals(uri)) { // Compliant // ... } } ```

It is preferable to place string literals on the left-hand side of an equals() or equalsIgnoreCase() method call.

This prevents null pointer exceptions from being raised, as a string literal can never be null by definition.

```java Bad theme={"system"} String myString = null; System.out.println("Equal? " + myString.equals("foo")); // Noncompliant; will raise a NPE System.out.println("Equal? " + (myString != null && myString.equals("foo"))); // Noncompliant; null check could be removed ``` ```java Fix theme={"system"} System.out.println("Equal?" + "foo".equals(myString)); // properly deals with the null case ```

It is convention to name each class’s logger for the class itself. Doing so allows you to set up clear, communicative logger configuration. Naming loggers by some other convention confuses configuration, and using the same class name for multiple class loggers prevents the granular configuration of each class' logger. Some libraries, such as SLF4J warn about this, but not all do.

This rule raises an issue when a logger is not named for its enclosing class.

```java Bad theme={"system"} public class MyClass { private final static Logger LOG = LoggerFactory.getLogger(WrongClass.class); // Noncompliant; multiple classes using same logger } ``` ```java Fix theme={"system"} public class MyClass { private final static Logger LOG = LoggerFactory.getLogger(MyClass.class); } ```

If an InterruptedException or a ThreadDeath error is not handled properly, the information that the thread was interrupted will be lost. Handling this exception means either to re-throw it or manually re-interrupt the current thread by calling Thread.interrupt(). Simply logging the exception is not sufficient and counts as ignoring it. Between the moment the exception is caught and handled, is the right time to perform cleanup operations on the method’s state, if needed.

```java Bad theme={"system"} public void run () { try { /*...*/ } catch (InterruptedException e) { // Noncompliant; logging is not enough LOGGER.log(Level.WARN, "Interrupted!", e); } } ``` ```java Fix theme={"system"} public void run () { try { /* ... */ } catch (InterruptedException e) { // Compliant; the interrupted state is restored LOGGER.log(Level.WARN, "Interrupted!", e); /* Clean up whatever needs to be handled before interrupting */ Thread.currentThread().interrupt(); } } public void run () { try { /* ... */ } catch (ThreadDeath e) { // Compliant; the error is being re-thrown LOGGER.log(Level.WARN, "Interrupted!", e); /* Clean up whatever needs to be handled before re-throwing */ throw e; } } ```

Using a \`type="timestamp" column as the primary key of a table is slightly risky. Two threads could create new objects in the table close enough in sequence for them to both have the same timestamp. Alternately, this could happen during a daylight savings time change. Instead, use a numeric value as the @Id.

This rule raises an issue when a time or date-related class is annotated with @Id\`.

```java Bad theme={"system"} public class Person { @Id @Type(type="timestamp") private Date birthDate; // Noncompliant private String lastName; // ... } ``` ```java Fix theme={"system"} public class Person { @Id @GeneratedValue int id; @Type(type="timestamp") private Date birthDate; private String lastName; // ... } ```

The class \`java.util.zip.GZIPInputStream is already buffering its input while reading. Thus passing a java.io.BufferedInputStream to a java.util.zip.GZIPInputStream is redundant. It is more efficient to directly pass the original input stream to java.util.zip.GZIPInputStream.

Note that the default buffer size of GZIPInputStream is not the same as the one in BufferedInputStream. Configure it if need be.

This rule raises an issue when a java.util.zip.GZIPInputStream reads from a java.io.BufferedInputStream\`.

```java Bad theme={"system"} import java.io.*; import java.util.zip.GZIPInputStream; public class Noncompliant { void deflateFile(final File file) throws IOException { try ( FileInputStream fileStream = new FileInputStream(file); BufferedInputStream bufferedStream = new BufferedInputStream(fileStream); InputStream input = new GZIPInputStream(bufferedStream); // Noncompliant ) { // process the input } } } ``` ```java Fix theme={"system"} import java.io.*; import java.util.zip.GZIPInputStream; public class Compliant { void deflateFile(final File file) throws IOException { try ( FileInputStream fileStream = new FileInputStream(file); InputStream input = new GZIPInputStream(fileStream); ) { // process the input } } } ```

The JDK provides a set of built-in methods to copy the contents of an array into another array. Using a loop to perform the same operation is less clear, more verbose and should be avoided.

```java Bad theme={"system"} public void copyArray(String[] source){ String[] array = new String[source.length]; for (int i = 0; i < source.length; i++) { array[i] = source[i]; // Noncompliant } } public void copyList(List source) { List list = new ArrayList<>(); for (String s : source) { list.add(s); // Noncompliant } } ``` ```java Fix theme={"system"} public void copyArray(String[] source){ String[] array = Arrays.copyOf(source, source.length); } public void copyList(List source) { List list = new ArrayList<>(); Collections.addAll(list, source); } ```

There are several reasons to avoid using this method:

  1. It is optionally available only for result sets of type ResultSet.TYPE\_FORWARD\_ONLY. Database drivers will throw an exception if not supported.

  2. The method can be expensive to execute as the database driver may need to fetch ahead one row to determine whether the current row is the last in the result set. The documentation of the method explicitly mentions this fact.

  3. What "the cursor is on the last row" means for an empty ResultSet is unclear. Database drivers may return true or false in this case .

ResultSet.next() is a good alternative to ResultSet.isLast() as it does not have the mentioned issues. It is always supported and, as per specification, returns false for empty result sets.

```java Bad theme={"system"} ResultSet results = stmt.executeQuery("SELECT name, address FROM PERSON"); StringBuilder sb = new StringBuilder(); while (results.next() && !results.isLast()) { // Noncompliant sb.append(results.getString("name") + ", "); } sb.append(results.getString("name")); String formattedNames = sb.toString(); ``` ```java Fix theme={"system"} ResultSet results = stmt.executeQuery("SELECT name, address FROM PERSON"); List names = new ArrayList<>(); while (results.next()) { // Compliant, and program logic refactored names.add(results.getString("name")); } String formattedNames = names.stream().collect(Collectors.joining(", ")); ```

A return type containing wildcards cannot be narrowed down in any context. This indicates that the developer’s intention was likely something else.

The core problem lies in type variance. Expressions at an input position, such as arguments passed to a method, can have a more specific type than the type expected by the method, which is called covariance. Expressions at an output position, such as a variable that receives the return result from a method, can have a more general type than the method’s return type, which is called contravariance. This can be traced back to the Liskov substitution principle.

In Java, type parameters of a generic type are invariant by default due to their potential occurrence in both input and output positions at the same time. A classic example of this is the methods T get() (output position) and add(T element) (input position) in interface java.util.List. We could construct cases with invalid typing in List if T were not invariant.

Wildcards can be employed to achieve covariance or contravariance in situations where the type parameter appears in one position only:

  • \ for covariance (input positions)

  • \ for contravariance (output positions)

However, covariance is ineffective for the return type of a method since it is not an input position. Making it contravariant also has no effect since it is the receiver of the return value which must be contravariant (use-site variance in Java). Consequently, a return type containing wildcards is generally a mistake.

```java Bad theme={"system"} List getAnimals() { ... } // Noncompliant, wildcard with no use List getLifeforms() { ... } // Noncompliant, wildcard with no use ``` ```java Fix theme={"system"} List getAnimals() { ... } // Compliant, using invariant type instead List getLifeforms() { ... } // Compliant, using invariant type instead ```

It’s almost always a mistake to compare two instances of java.lang.String or boxed types like java.lang.Integer using reference equality == or !=, because it is not comparing actual value but locations in memory.

```java Bad theme={"system"} String firstName = getFirstName(); // String overrides equals String lastName = getLastName(); if (firstName == lastName) { ... }; // Non-compliant; false even if the strings have the same value ``` ```java Fix theme={"system"} String firstName = getFirstName(); String lastName = getLastName(); if (firstName != null && firstName.equals(lastName)) { ... }; ```

When verifying that code raises an exception, a good practice is to avoid having multiple method calls inside the tested code, to be explicit about what is exactly tested.

When two of the methods can raise the same checked exception, not respecting this good practice is a bug, since it is not possible to know what is really tested.

You should make sure that only one method can raise the expected checked exception in the tested code.

```java Bad theme={"system"} @Test public void testG() { // Do you expect g() or f() throwing the exception? assertThrows(IOException.class, () -> g(f(1)) ); // Noncompliant } @Test public void testGTryCatchIdiom() { try { // Noncompliant g(f(1)); Assert.fail("Expected an IOException to be thrown"); } catch (IOException e) { // Test exception message... } } int f(int x) throws IOException { // ... } int g(int x) throws IOException { // ... } ``` ```java Fix theme={"system"} @Test public void testG() { int y = f(1); // It is explicit that we expect an exception from g() and not f() assertThrows(IOException.class, () -> g(y) ); } @Test public void testGTryCatchIdiom() { int y = f(1); try { g(y); Assert.fail("Expected an IOException to be thrown"); } catch (IOException e) { // Test exception message... } } ``` ```java Bad theme={"system"} try { /* some work which end up throwing an exception */ throw new IllegalArgumentException(); } finally { /* clean up */ throw new RuntimeException(); // Noncompliant; masks the IllegalArgumentException } ``` ```java Fix theme={"system"} try { /* some work which end up throwing an exception */ throw new IllegalArgumentException(); } finally { /* clean up */ } ```

Map is an object that maps keys to values. A map cannot contain duplicate keys, which means each key can map to at most one value.

When both the key and the value are needed, it is more efficient to iterate the entrySet(), which will give access to both instead of iterating over the keySet() and then getting the value.

If the entrySet() method is not iterated when both the key and value are needed, it can lead to unnecessary lookups. This is because each lookup requires two operations: one to retrieve the key and another to retrieve the value. By iterating the entrySet() method, the key-value pair can be retrieved in a single operation, which can improve performance.

```java Bad theme={"system"} public void doSomethingWithMap(Map map) { for (String key : map.keySet()) { // Noncompliant; for each key the value is retrieved Object value = map.get(key); // ... } } ``` ```java Fix theme={"system"} public void doSomethingWithMap(Map map) { for (Map.Entry entry : map.entrySet()) { String key = entry.getKey(); Object value = entry.getValue(); // ... } } ```

The use of exact alarms triggers the device to wake up at precise times that can lead several wake-ups in a short period of time. The wake-up mechanism is a significant battery drain because it requires powering up the main processor and pulling it out of a low-power state.

It’s highly recommended to create an inexact alarm whenever possible.

It is also recommended for normal timing operations, such as ticks and timeouts, using the Handler, and for long-running operations, such as network downloads, using WorkManager or JobScheduler.

```java Bad theme={"system"} public class AlarmScheduler { private Context context; public AlarmScheduler(Context context) { this.context = context; } public void scheduleAlarm(long triggerTime) { AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); Intent intent = new Intent(context, AlarmReceiver.class); PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0); alarmManager.setExact(AlarmManager.RTC_WAKEUP, triggerTime, pendingIntent); // Noncompliant, avoid using exact alarms unless necessary alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, triggerTime, pendingIntent); // Noncompliant, avoid using exact alarms unless necessary long windowLengthMillis = 5 * 60 * 1000; // 5 minutes in milliseconds alarmManager.setWindow(AlarmManager.RTC_WAKEUP, triggerTime, windowLengthMillis, pendingIntent); // Noncompliant, don't use windows below 10 minutes } } ``` ```java Fix theme={"system"} public class AlarmScheduler { private Context context; public AlarmScheduler(Context context) { this.context = context; } public void scheduleAlarm(long triggerTime) { AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); Intent intent = new Intent(context, AlarmReceiver.class); PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0); alarmManager.set(AlarmManager.RTC_WAKEUP, triggerTime, pendingIntent); // Compliant alarmManager.setAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, triggerTime, pendingIntent); // Compliant long windowLengthMillis = 10 * 60 * 1000; // 10 minutes in milliseconds alarmManager.setWindow(AlarmManager.RTC_WAKEUP, triggerTime, windowLengthMillis, pendingIntent); // Compliant } } ```

\`Bean Validation as per defined by JSR 380 can be triggered programmatically or also executed by the Bean Validation providers. However something should tell the Bean Validation provider that a variable must be validated otherwise no validation will happen. This can be achieved by annotating a variable with javax.validation.Valid and unfortunally it’s easy to forget to add this annotation on complex Beans.

Not annotating a variable with @Valid means Bean Validation will not be triggered for this variable, but readers may overlook this omission and assume the variable will be validated.

This rule will run by default on all Class'es and therefore can generate a lot of noise. This rule should be restricted to run only on certain layers. For this reason, the "Restrict Scope of Coding Rules" feature should be used to check for missing @Valid\` annotations only on some packages of the application.

```java Bad theme={"system"} import javax.validation.Valid; import javax.validation.constraints.NotNull; public class User { @NotNull private String name; } public class Group { @NotNull private List users; // Noncompliant; User instances are not validated } public class MyService { public void login(User user) { // Noncompliant; parameter "user" is not validated } } ``` ```java Fix theme={"system"} import javax.validation.Valid; import javax.validation.constraints.NotNull; public class User { @NotNull private String name; } public class Group { @Valid @NotNull private List users; // Compliant; User instances are validated @NotNull // preferred style as of Bean Validation 2.0 private List<@Valid User> users2; // Compliant; User instances are validated } public class MyService { public void login(@Valid User user) { // Compliant } } ```

Using FetchType.EAGER can lead to inefficient data loading and potential performance issues. Eager Loading initializes associated data on the spot, potentially fetching more data than needed.

```java Bad theme={"system"} @OneToMany(mappedBy = "parent", fetch = FetchType.EAGER) // Noncompliant private List children; @OneToMany(mappedBy = "child", fetch = FetchType.EAGER) // Noncompliant private List parents; ``` ```java Fix theme={"system"} @OneToMany(mappedBy = "parent", fetch = FetchType.LAZY) // Compliant private List children; @OneToMany(mappedBy = "child") // Compliant private List parents; ```

Synchronizing on a class field synchronizes not on the field itself, but on the object assigned to it. So synchronizing on a non-final field makes it possible for the field’s value to change while a thread is in a block synchronized on the old value. That would allow a second thread, synchronized on the new value, to enter the block at the same time.

The story is very similar for synchronizing on parameters; two different threads running the method in parallel could pass two different object instances in to the method as parameters, completely undermining the synchronization.

```java Bad theme={"system"} private String color = "red"; private void doSomething(){ synchronized(color) { // Noncompliant; lock is actually on object instance "red" referred to by the color variable //... color = "green"; // other threads now allowed into this block // ... } synchronized(new Object()) { // Noncompliant this is a no-op. // ... } } ``` ```java Fix theme={"system"} private String color = "red"; private final Object lockObj = new Object(); private void doSomething(){ synchronized(lockObj) { //... color = "green"; // ... } } ```

According to the JDBC specification:

Blob, Clob, and NClob Java objects remain valid for at least the duration of the transaction in which they are created. This could potentially result in an application running out of resources during a long running transaction.

```java Bad theme={"system"} PreparedStatement ps = conn.prepareStatement("SELECT text, img from photos where author=?"); ps.setString(1,author); ResultSet rs = ps.executeQuery(); while (rs.next()) { Image image = saveImg(rs.getBlob("img").getBinaryStream()); // Noncompliant; blob is never freed image.addCaption(rs.getClob("text").getCharacterStream()); // Noncompliant } ``` ```java Fix theme={"system"} PreparedStatement ps = conn.prepareStatement("SELECT text, img from photos where author=?"); ps.setString(1,author); ResultSet rs = ps.executeQuery(); while (rs.next()) { Blob blob = rs.getBlob("img"); Image image = saveImg(blob.getBinaryStream()); blob.free(); Clob clob = rs.getClob("text"); image.addCaption(clob.getCharacterStream()); clob.free(); } ```

Without OAEP in RSA encryption, it takes less work for an attacker to decrypt the data or infer patterns from the ciphertext. This rule logs an issue as soon as a literal value starts with RSA/NONE.

```java Bad theme={"system"} Cipher rsa = javax.crypto.Cipher.getInstance("RSA/NONE/NoPadding"); ``` ```java Fix theme={"system"} Cipher rsa = javax.crypto.Cipher.getInstance("RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING"); ```

Java 21 introduces a new SequencedCollection interface that provides a uniform API for accessing its first and last elements. The new getFirst() and getLast() methods offer a consistent way to access elements across SortedSet, NavigableSet, LinkedHashSet, List and Deque collections. Because those methods are more concise and readable, they should be used instead of more complex workarounds that recreate the same behavior.

For example, list.get(list.size() - 1) can be replaced by list.getLast().

This rule identifies code that can be simplified by using the new getFirst() and getLast() methods.

```java Bad theme={"system"} public String concatenateFirstAndLast(List list) { return list.get(0) + // Noncompliant list.get(list.size() - 1); // Noncompliant } ``` ```java Fix theme={"system"} public String concatenateFirstAndLast(List list) { return list.getFirst() + // Compliant list.getLast(); // Compliant } ```

Proper synchronization and thread management can be tricky under the best of circumstances, but it’s particularly difficult in JEE application, and is even forbidden under some circumstances by the JEE standard.

This rule raises an issue for each Runnable, and use of the synchronized keyword.

```java Bad theme={"system"} public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // ... Runnable r = new Runnable() { // Noncompliant public void run() { // ... } }; new Thread(r).start(); ``` ```java Fix theme={"system"} ```

NullPointerException should be avoided, not caught. Any situation in which NullPointerException is explicitly caught can easily be converted to a null test, and any behavior being carried out in the catch block can easily be moved to the "is null" branch of the conditional.

```java Bad theme={"system"} public int lengthPlus(String str) { int len = 2; try { len += str.length(); } catch (NullPointerException e) { log.info("argument was null"); } return len; } ``` ```java Fix theme={"system"} public int lengthPlus(String str) { int len = 2; if (str != null) { len += str.length(); } else { log.info("argument was null"); } return len; } ```

Testing equality of an enum value with \`equals is perfectly valid because an enum is an Object and every Java developer knows "==" should not be used to compare the content of an Object. At the same time, using "==" on enums:

  • provides the same expected comparison (content) as equals

  • is more null-safe than equals()

  • provides compile-time (static) checking rather than runtime checking

For these reasons, use of "==" should be preferred to equals\`.

```java Bad theme={"system"} public enum Fruit { APPLE, BANANA, GRAPE } public enum Cake { LEMON_TART, CHEESE_CAKE } public boolean isFruitGrape(Fruit candidateFruit) { return candidateFruit.equals(Fruit.GRAPE); // Noncompliant; this will raise an NPE if candidateFruit is NULL } public boolean isFruitGrape(Cake candidateFruit) { return candidateFruit.equals(Fruit.GRAPE); // Noncompliant; always returns false } ``` ```java Fix theme={"system"} public boolean isFruitGrape(Fruit candidateFruit) { return candidateFruit == Fruit.GRAPE; // Compliant; there is only one instance of Fruit.GRAPE - if candidateFruit is a GRAPE it will have the same reference as Fruit.GRAPE } public boolean isFruitGrape(Cake candidateFruit) { return candidateFruit == Fruit.GRAPE; // Compliant; compilation time failure } ```

The difference between \`private and protected visibility is that child classes can see and use protected members, but they cannot see private ones. Since a final class will have no children, marking the members of a final class protected is confusingly pointless.

Note that the protected\` members of a class can also be seen and used by other classes that are placed within the same package, this could lead to accidental, unintended access to otherwise private members.

```java Bad theme={"system"} public final class MyFinalClass { protected String name = "Fred"; // Noncompliant protected void setName(String name) { // Noncompliant // ... } ``` ```java Fix theme={"system"} public final class MyFinalClass { private String name = "Fred"; public void setName(String name) { // ... } ```

Shared coding conventions allow teams to collaborate effectively. While types for lambda arguments are optional, specifying them anyway makes the code clearer and easier to read.

```java Bad theme={"system"} Arrays.sort(rosterAsArray, (a, b) -> { // Noncompliant return a.getBirthday().compareTo(b.getBirthday()); } ); ``` ```java Fix theme={"system"} Arrays.sort(rosterAsArray, (Person a, Person b) -> { return a.getBirthday().compareTo(b.getBirthday()); } ); ```

An ObjectOutputStream writes primitive data types and graphs of Java objects to an OutputStream. The objects can be read (reconstituted) using an ObjectInputStream.

When ObjectOutputStream is used with files opened in append mode, it can cause data corruption and unexpected behavior. This is because when ObjectOutputStream is created, it writes metadata to the output stream, which can conflict with the existing metadata when the file is opened in append mode. This can lead to errors and data loss.

When used with serialization, an ObjectOutputStream first writes the serialization stream header. This header should appear once per file at the beginning. When you’re trying to read your object(s) back from the file, only the first one will be read successfully, and a StreamCorruptedException will be thrown after that.

```java Bad theme={"system"} FileOutputStream fos = new FileOutputStream(fileName , true); // fos opened in append mode ObjectOutputStream out = new ObjectOutputStream(fos); // Noncompliant ``` ```java Fix theme={"system"} FileOutputStream fos = new FileOutputStream(fileName); ObjectOutputStream out = new ObjectOutputStream(fos); ```

There is no good reason to have a mutable object as the \`public (by default), static member of an interface. Such variables should be moved into classes and their visibility lowered.

Similarly, mutable static members of classes and enumerations which are accessed directly, rather than through getters and setters, should be protected to the degree possible. That can be done by reducing visibility or making the field final if appropriate.

Note that making a mutable field, such as an array, final will keep the variable from being reassigned, but doing so has no effect on the mutability of the internal state of the array (i.e. it doesn’t accomplish the goal).

This rule raises issues for public static array, Collection, Date, and awt.Point\` members.

```java Bad theme={"system"} public interface MyInterface { public static String [] strings; // Noncompliant } public class A { public static String [] strings1 = {"first","second"}; // Noncompliant public static String [] strings2 = {"first","second"}; // Noncompliant public static List strings3 = new ArrayList<>(); // Noncompliant // ... } ``` ```java Fix theme={"system"} ```

The order in which you `close database-releated resources is crucial. Close a Connection first, and depending on the database pooling in use, you may no longer be able to truly reach its Statements and ResultSet`s to close them, even though the calls are made and execute without error.

```java Bad theme={"system"} Connection conn = null; PreparedStatement ps = null; ResultSet rs = null; try { conn = DriverManager.getConnection(connectionString); ps = conn.prepareStatement(query); rs = ps.executeQuery(); // ... } finally { try { if (conn != null) { conn.close(); // Noncompliant; close this last } } catch (Exception e) {}; try { if (ps != null) { ps.close(); } } catch (Exception e) {}; try { if (rs != null) { rs.close(); } } catch (Exception e) {}; } ``` ```java Fix theme={"system"} Connection conn = null; PreparedStatement ps = null; ResultSet rs = null; try { conn = DriverManager.getConnection(connectionString); ps = conn.prepareStatement(query); rs = ps.executeQuery(); // ... } finally { try { if (rs != null) { rs.close(); } } catch (Exception e) {}; try { if (ps != null) { ps.close(); } } catch (Exception e) {}; try { if (conn != null) { conn.close(); } } catch (Exception e) {}; } ```

When an SWT \`Image accesses a file directly, it holds the file handle for the life of the image. Do this many times, and the OS may run out of available file handles. At minimum, SWT Images which directly access files should not be static. At best, they should access their files through ImageDescriptors, which do not hold open file handles.

This rule looks for org.eclipse.swt.graphics.Images which both directly access a file on the file path and are static\`.

```java Bad theme={"system"} import org.eclipse.swt.graphics.Image; public class MyView { static Image myImage = new Image("path/to/file.png"); // Noncompliant ``` ```java Fix theme={"system"} import org.eclipse.swt.graphics.Image; import org.eclipse.jface.resource.ImageDescriptor; public class MyView { static ImageDescription myDescriptor = ImageDescriptor.createFromFile("path/to/file.png"); // Doesn't hold file handle open Image myImage = myDescriptor.getImage(); ```

ialization of objects from LDAP directories, which can lead to remote code execution.

This rule raises an issue when an LDAP search query is executed with SearchControls configured to allow deserialization.

```java Bad theme={"system"} DirContext ctx = new InitialDirContext(); // ... ctx.search(query, filter, new SearchControls(scope, countLimit, timeLimit, attributes, false, // Compliant deref)); ``` ```java Fix theme={"system"} ```

Transactional methods have a propagation type parameter in the @Transaction annotation that specifies the requirements about the transactional context in which the method can be called and how it creates, appends, or suspends an ongoing transaction.

When an instance that contains transactional methods is injected, Spring uses proxy objects to wrap these methods with the actual transaction code.

However, if a transactional method is called from another method in the same class, the this argument is used as the receiver instance instead of the injected proxy object, which bypasses the wrapper code. This results in specific transitions from one transactional method to another, which are not allowed:

From To

non-\`@Transactional

MANDATORY, NESTED, REQUIRED, REQUIRES\_NEW

MANDATORY

NESTED, NEVER, NOT\_SUPPORTED, REQUIRES\_NEW

NESTED

NESTED, NEVER, NOT\_SUPPORTED, REQUIRES\_NEW

NEVER

MANDATORY, NESTED, REQUIRED, REQUIRES\_NEW

NOT\_SUPPORTED

MANDATORY, NESTED, REQUIRED, REQUIRES\_NEW

REQUIRED or @Transactional\`

NESTED, NEVER, NOT\_SUPPORTED, REQUIRES\_NEW

REQUIRES\_NEW

NESTED, NEVER, NOT\_SUPPORTED, REQUIRES\_NEW

SUPPORTS

MANDATORY, NESTED, NEVER, NOT\_SUPPORTED, REQUIRED, REQUIRES\_NEW

```java Bad theme={"system"} public void doTheThing() { // ... actuallyDoTheThing(); // Noncompliant, call from non-transactional to transactional } @Transactional public void actuallyDoTheThing() { // ... } ``` ```java Fix theme={"system"} @Transactional public void doTheThing() { // ... actuallyDoTheThing(); // Compliant } @Transactional public void actuallyDoTheThing() { // ... } ```

The equals method in AtomicInteger and AtomicLong returns true only if two instances are identical, not if they represent the same number value.

This is because equals is not part of the API contract of these classes, and they do not override the method inherited from java.lang.Object. Although both classes implement the Number interface, assertions about equals comparing number values are not part of that interface either. Only the API contract of implementing classes like Integer, Long, Float, BigInteger, etc., provides such assertions.

```java Bad theme={"system"} Boolean isSameNumberValue(AtomicLong a, AtomicLong b) { return a.equals(b); // Noncompliant, this is true only if a == b } Boolean isSameReference(AtomicLong a, AtomicLong b) { return a.equals(b); // Noncompliant, because misleading } ``` ```java Fix theme={"system"} Boolean isSameNumberValue(AtomicLong a, AtomicLong b) { return a.get() == b.get(); // Compliant } Boolean isSameReference(AtomicLong a, AtomicLong b) { return a == b; // Compliant } ```

A method with a \`@RequestMapping annotation part of a class annotated with @Controller (directly or indirectly through a meta annotation - @RestController from Spring Boot is a good example) will be called to handle matching web requests. That will happen even if the method is private, because Spring invokes such methods via reflection, without checking visibility.

So marking a sensitive method private may seem like a good way to control how such code is called. Unfortunately, not all Spring frameworks ignore visibility in this way. For instance, if you’ve tried to control web access to your sensitive, private, @RequestMapping method by marking it @Secured …​ it will still be called, whether or not the user is authorized to access it. That’s because AOP proxies are not applied to private methods.

In addition to @RequestMapping, this rule also considers the annotations introduced in Spring Framework 4.3: @GetMapping, @PostMapping, @PutMapping, @DeleteMapping, @PatchMapping\`.

```java Bad theme={"system"} @RequestMapping("/greet", method = GET) private String greet(String greetee) { // Noncompliant ``` ```java Fix theme={"system"} @RequestMapping("/greet", method = GET) public String greet(String greetee) { ```

Java 21 enhances Pattern Matching, introduced in Java 16, with a record pattern that decomposes records into local variables. This form should be used when all fields of a record are accessed within a block for improved readability. Nested record patterns are also allowed and should be used when a record field is another record, and all its fields are accessed.

```java Bad theme={"system"} record Point(Float x, Float y, Float z) {} void print(Object obj) { if (obj instanceof Point p) { // Noncompliant, because all three fields x, y, z are accessed Float x = p.x; Float y = p.y(); System.out.println(x + y + p.z); } } ``` ```java Fix theme={"system"} record Point(Float x, Float y, Float z) {} void print(Object obj) { if (obj instanceof Point(Float x, Float y, Float z)) { // Compliant System.out.println(x + y + z); } } ```

A loop with at most one iteration is equivalent to an if statement. This can confuse developers and make the code less readable since loops are not meant to replace if statements.

If the intention was to conditionally execute the block only once, an if statement should be used instead. Otherwise, the loop should be fixed so the loop block can be executed multiple times.

A loop statement with at most one iteration can happen when a statement that unconditionally transfers control, such as a jump or throw statement, is misplaced inside the loop block.

This rule arises when the following statements are misplaced:

  • break

  • return

  • throw

```java Bad theme={"system"} int i = 0; while(i < 10) { // Noncompliant; loop only executes once System.out.println("i is " + i); i++; break; } ``` ```java Fix theme={"system"} for (int i = 0; i < 10; i++) { // Noncompliant; loop only executes once if (i == x) { break; } else { System.out.println("i is " + i); return; } } ```

With Java 8, there’s no need to write \`Comparators that compare primitive values or other Comparables; they can be generated for you using the Comparator.comparing\* functions: comparing, comparingDouble, comparingInt, comparingLong.

Note that this rule is automatically disabled when the project’s sonar.java.source is lower than 8\`.

```java Bad theme={"system"} unparsedFiles.stream() .sorted((f1, f2) -> f1.lines - f2.lines) // Noncompliant .limit(30); ``` ```java Fix theme={"system"} unparsedFiles.stream() .sorted(Comparator.comparingInt(UnparsedFile::getLines())) .limit(30); ```

Monster Classes become monolithic entities, with numerous responsibilities and functionalities packed into a single class. This is problematic because it violates the Single Responsibility Principle, which states that a class should have only one reason to change.

When a class has too many responsibilities and functionalities, it becomes difficult to maintain. Changes to one part of the class can unintentionally affect other parts, leading to bugs. Additionally, it can be difficult to test the class, as there may be many different interactions between different parts of the class that need to be considered.

```java Bad theme={"system"} class Foo { // class Foo depends on too many classes: T1, T2, T3, T4, T5, T6 and T7 T1 t1; T2 t2; T3 t3; public T4 compute(T5 a, T6 b) { T7 result = a.getResult(b); return (T4) result; } } ``` ```java Fix theme={"system"} public class Bar { T8 a8; T9 a9; } ```

Needing to cast from an interface to a concrete type indicates that something is wrong with the abstractions in use, likely that something is missing from the interface. Instead of casting to a discrete type, the missing functionality should be added to the interface. Otherwise there is the risk of runtime exceptions.

```java Bad theme={"system"} public interface MyInterface { void doStuff(); } public class MyClass1 implements MyInterface { int data; public void DoStuff() { // TODO... } } public static class DowncastExampleProgram { static void EntryPoint(MyInterface interfaceRef) { MyClass1 class1 = (MyClass1)interfaceRef; // Noncompliant int privateData = class1.data; } } ``` ```java Fix theme={"system"} static void EntryPoint(IMyInterface interfaceRef) { Object o = (Object)interfaceRef; ... } ```

Optimizing resource usage and preventing unnecessary battery drain are critical considerations in Android development. Failing to release sensor resources when they are no longer needed can lead to prolonged device activity, negatively impacting battery life. Common Android sensors, such as cameras, GPS, and microphones, provide a method to release resources after they are not in use anymore.

This rule identifies situations where a sensor is not released after being utilized, helping developers maintain efficient and battery-friendly applications.

  • Missing call to release() method:

    • android.os.PowerManager.WakeLock

    • android.net.wifi.WifiManager\$MulticastLock

    • android.hardware.Camera

    • android.media.MediaPlayer

    • android.media.MediaRecorder

    • android.media.SoundPool

    • android.media.audiofx.Visualizer

    • android.hardware.display.VirtualDisplay

  • Missing call to close() method

    • android.hardware.camera2.CameraDevice

  • Missing call to removeUpdates() method:

    • android.location.LocationManager

  • Missing call to unregisterListener() method:

    • android.hardware.SensorManager

```java Bad theme={"system"} public void method() { PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE); PowerManager.WakeLock wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "My Wake Lock"); wakeLock.acquire(); // Noncompliant // do some work... } ``` ```java Fix theme={"system"} public void method() { PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE); PowerManager.WakeLock wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "My Wake Lock"); wakeLock.acquire(); // Compliant // do some work... wakeLock.release(); } ```

enums are generally thought of as constant, but an enum with a public field or public setter is non-constant. Ideally fields in an enum are private and set in the constructor, but if that’s not possible, their visibility should be reduced as much as possible.

```java Bad theme={"system"} public enum Continent { NORTH_AMERICA (23, 24709000), // ... EUROPE (50, 39310000); public int countryCount; // Noncompliant private int landMass; Continent(int countryCount, int landMass) { // ... } public void setLandMass(int landMass) { // Noncompliant this.landMass = landMass; } ``` ```java Fix theme={"system"} public enum Continent { NORTH_AMERICA (23, 24709000), // ... EUROPE (50, 39310000); private int countryCount; private int landMass; Continent(int countryCount, int landMass) { // ... } ```

When all the elements in a Set are values from the same enum, the Set can be replaced with an EnumSet, which can be much more efficient than other sets because the underlying data structure is a simple bitmap.

```java Bad theme={"system"} public class MyClass { public enum COLOR { RED, GREEN, BLUE, ORANGE; } public void doSomething() { Set warm = new HashSet(); warm.add(COLOR.RED); warm.add(COLOR.ORANGE); } } ``` ```java Fix theme={"system"} public class MyClass { public enum COLOR { RED, GREEN, BLUE, ORANGE; } public void doSomething() { Set warm = EnumSet.of(COLOR.RED, COLOR.ORANGE); } } ```

Returning null when something goes wrong instead of throwing an exception leaves callers with no understanding of what went wrong. Instead, an exception should be thrown.

```java Bad theme={"system"} public MyClass readFile(String fileName) { MyClass mc; try { // read object from file } catch (IOException e) { // do cleanup return null; // Noncompliant; why did this fail? } return mc; } ``` ```java Fix theme={"system"} public MyClass readFile(String fileName) throws IOException{ MyClass mc; try { // read object from file } catch (IOException e) { // do cleanup throw e; } return mc; } ```

The JEE standard forbids the direct management of connections in JEE applications. The application code should not directly create, manage, or close database connections. Instead, the application code should use the connection pool managed by the container via DataSource objects.

The container is responsible for creating and managing the connection pool, as well as monitoring the usage of connections and releasing them when they are no longer needed. By delegating connection management to the container, JEE applications can avoid connection leaks and resource exhaustion and ensure that database connections are used efficiently and securely.

When an application manages connections directly, connection leaks may arise. These leaks occur when an application fails to release a database connection after it has finished using it. Another risk is vulnerability to SQL injection attacks, which occur when an attacker is able to inject malicious SQL code into an application’s database queries, allowing them to access or modify sensitive data. Finally, these applications have difficulty managing and monitoring database connections. Without a centralized connection pool, tracking the usage of database connections and ensuring they are used efficiently and securely can be challenging.

This rule raises an issue for using a DriverManager in a servlet class.

```java Bad theme={"system"} private static final String CONNECT_STRING = "jdbc:mysql://localhost:3306/mysqldb"; public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { Connection conn = null; try { conn = DriverManager.getConnection(CONNECT_STRING); // Noncompliant // ... } catch (SQLException ex) {...} //... } } ``` ```java Fix theme={"system"} private static final String DB_LOOKUP = "jdbc/mainDb"; public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { Connection conn = null; try { InitialContext ctx = new InitialContext(); DataSource datasource = (DataSource) ctx.lookup(DB_LOOKUP); conn = datasource.getConnection(); // ... } catch (SQLException ex) {...} //... } } ```

\`sealed classes were introduced in Java 17. This feature is very useful if there is a need to define a strict hierarchy and restrict the possibility of extending classes. In order to mention all the allowed subclasses, there is a keyword permits, which should be followed by subclasses' names.

This notation is quite useful if subclasses of a given sealed class can be found in different files, packages, or even modules. In case when all subclasses are declared in the same file there is no need to mention the explicitly and permits part of a declaration can be omitted.

This rule reports an issue if all subclasses of a sealed\` class are declared in the same file as their superclass.

```java Bad theme={"system"} sealed class A permits B, C, D, E {} // Noncompliant final class B extends A {} final class C extends A {} final class D extends A {} final class E extends A {} ``` ```java Fix theme={"system"} sealed class A {} // Compliant final class B extends A {} final class C extends A {} final class D extends A {} final class E extends A {} ```

Mockito provides argument matchers for flexibly stubbing or verifying method calls.

\`Mockito.verify(), Mockito.when(), Stubber.when() and BDDMockito.given() each have overloads with and without argument matchers.

However, the default matching behavior (i.e. without argument matchers) uses equals(). If only the matcher org.mockito.ArgumentMatchers.eq() is used, the call is equivalent to the call without matchers, i.e. the eq()\` is not necessary and can be omitted. The resulting code is shorter and easier to read.

```java Bad theme={"system"} @Test public void myTest() { given(foo.bar(eq(v1), eq(v2), eq(v3))).willReturn(null); // Noncompliant when(foo.baz(eq(v4), eq(v5))).thenReturn("foo"); // Noncompliant doThrow(new RuntimeException()).when(foo).quux(eq(42)); // Noncompliant verify(foo).bar(eq(v1), eq(v2), eq(v3)); // Noncompliant } ``` ```java Fix theme={"system"} @Test public void myTest() { given(foo.bar(v1, v2, v3)).willReturn(null); when(foo.baz(v4, v5)).thenReturn("foo"); doThrow(new RuntimeException()).when(foo).quux(42); verify(foo).bar(v1, v2, v3); } ```

Marking a non-public method @Async or @Transactional is misleading because Spring does not recognize non-public methods, and so makes no provision for their proper invocation. Nor does Spring make provision for the methods invoked by the method it called.

Therefore marking a private method, for instance, @Transactional can only result in a runtime error or exception if the method is annotated as @Transactional.

```java Bad theme={"system"} @Async private Future asyncMethodWithReturnType() { // Noncompliant, no proxy generated and return "Hellow, world!"; // can only be invoked from same class } ``` ```java Fix theme={"system"} @Async public Future asyncMethodWithReturnType() { // Compliant return "Hellow, world!"; } ```

Under the reasoning that cleaner code is better code, the semicolon at the end of a try-with-resources construct should be omitted because it can be omitted.

```java Bad theme={"system"} try (ByteArrayInputStream b = new ByteArrayInputStream(new byte[10]); // ignored; this one's required Reader r = new InputStreamReader(b);) // Noncompliant { //do stuff } ``` ```java Fix theme={"system"} try (ByteArrayInputStream b = new ByteArrayInputStream(new byte[10]); Reader r = new InputStreamReader(b)) { //do stuff } ```

The java.util.concurrent.locks.Condition interface provides an alternative to the Object monitor methods (wait, notify and notifyAll). Hence, the purpose of implementing said interface is to gain access to its more nuanced await methods.

Consequently, calling the method Object.wait on a class implementing the Condition interface is contradictory and should be avoided. Use Condition.await instead.

```java Bad theme={"system"} void doSomething(Condition condition) { condition.wait(); // Noncompliant, Object.wait is called ... } ``` ```java Fix theme={"system"} void doSomething(Condition condition) { condition.await(); // Compliant, Condition.await is called ... } ```

The Java Language Specification recommends listing modifiers in the following order:

  1. Annotations

  2. public

  3. protected

  4. private

  5. abstract

  6. static

  7. final

  8. transient

  9. volatile

  10. synchronized

  11. native

  12. default

  13. strictfp

Not following this convention has no technical impact, but will reduce the code’s readability because most developers are used to the standard order.

```java Bad theme={"system"} static public void main(String[] args) { // Noncompliant } ``` ```java Fix theme={"system"} public static void main(String[] args) { // Compliant } ```

Assembling a StringBuilder or StringBuffer into a String merely to see if it’s empty is a waste of cycles. Instead, jump right to the heart of the matter and get its .length() instead.

```java Bad theme={"system"} StringBuilder sb = new StringBuilder(); // ... if ("".equals(sb.toString()) { // Noncompliant // ... } ``` ```java Fix theme={"system"} StringBuilder sb = new StringBuilder(); // ... if (sb.length() == 0) { // ... } ```

An exception in a \`throws declaration in Java is superfluous if it is:

  • listed multiple times

  • a subclass of another listed exception

  • a RuntimeException\`, or one of its descendants

  • completely unnecessary because the declared exception type cannot actually be thrown

```java Bad theme={"system"} void foo() throws MyException { throw new MyException(); } @Test public void testMethod1() throws MyException, MyException { // Noncompliant; should be listed once foo(); } @Test public void testMethod2() throws MyException { //Noncompliant, exception cannot be thrown } @Test public void testMethod3() throws Throwable, Exception {} // Noncompliant; Exception is a subclass of Throwable @Test public void testMethod4 throws RuntimeException {} // Noncompliant; RuntimeException can always be thrown ``` ```java Fix theme={"system"} @Test public void testMethod1() throws MyException { foo(); } @Test public void testMethod2() { } @Test public void testMethod3()throws Throwable {} @Test public void testMethod4() {} ```

When a developer uses the StringBuilder or StringBuffer constructor with a single character as an argument, the likely intention is to create an instance with the character as the initial string value.

However, this is not what happens because of the absence of a dedicated StringBuilder(char) or StringBuffer(char) constructor. Instead, StringBuilder(int) or StringBuffer(int) is invoked, which results in an instance with the provided int value as the initial capacity of the StringBuilder or StringBuffer.

The reason behind this behavior lies in the automatic widening of char expressions to int when required. Consequently, the UTF-16 code point value of the character (for example, 65 for the character 'A') is interpreted as an int to specify the initial capacity.

```java Bad theme={"system"} StringBuffer foo = new StringBuffer('x'); // Noncompliant, replace with String ``` ```java Fix theme={"system"} StringBuffer foo = new StringBuffer("x"); // Compliant ```

The @PathVariable annotation in Spring extracts values from the URI path and binds them to method parameters in a Spring MVC controller. It is commonly used with @GetMapping, @PostMapping, @PutMapping, and @DeleteMapping to capture path variables from the URI. These annotations map HTTP requests to specific handler methods in a controller. They are part of the Spring Web module and are commonly used to define the routes for different HTTP operations in a RESTful API.

If a method has a path template containing a placeholder, like "/api/resource/\{id}", and there’s no @PathVariable annotation on a method parameter to capture the id path variable, Spring will disregard the id variable.

```java Bad theme={"system"} @GetMapping("/api/resource/{id}") public ResponseEntity getResourceById(Long id) { // Noncompliant - The 'id' parameter will not be automatically populated with the path variable value return ResponseEntity.ok("Fetching resource with ID: " + id); } ``` ```java Fix theme={"system"} @GetMapping("/api/resource/{id}") public ResponseEntity getResourceById(@PathVariable Long id) { // Compliant return ResponseEntity.ok("Fetching resource with ID: " + id); } ```

When creating an instance of HashMap or HashSet, the developer can pick a constructor with known capacity. However, the requested capacity is not fully allocated by default. Indeed, when the collection reaches the load factor of the collection (default: 0.75), the collection is resized on the fly, leading to unexpected performance issues.

```java Bad theme={"system"} private static final int KNOWN_CAPACITY = 1_000_000; public static Map buildAMap() { return new HashMap<>(KNOWN_CAPACITY); // Noncompliant } public static Set buildASet() { return new HashSet<>(KNOWN_CAPACITY); // Noncompliant } ``` ```java Fix theme={"system"} private static final int KNOWN_CAPACITY = 1_000_000; public static Map buildABetterMap() { return HashMap.newHashMap(KNOWN_CAPACITY); } public static Set buildABetterSet() { return HashSet.newHashSet(KNOWN_CAPACITY); } public static Set buildABetterSet(float customLoadFactor) { return new HashSet<>(KNOWN_CAPACITY, customLoadFactor); } ```

Sometimes when implementing a method, there is a need to return more than one value. To reduce the boilerplate of describing another class, other programming languages introduced such structures as \`Pair, Tuple, Vector, etc.

Unfortunately, in Java, there is no such structure and ++Map.Entry++ or ++Object\[]++ of fixed size are used as a workaround for returning multiple values from a method.

Java 16 introduced records to represent immutable data structures and they can be used for grouping different values in one entity. By using records, developers will have meaningful names and result in a more readable code. Furthermore, when using Object\[], there is a risk of getting ClassCastException or ArrayIndexOutOfBoundsException if not used carefully. It means that using records is not only more readable but is definitely safer.

This rule should report an issue when Object\[] of a fixed size (\< 7) or Map.Entry\` are returned from a private method.

```java Bad theme={"system"} private Map.Entry getPerson() { String name = "John"; int age = 25; return Map.entry(name, age); // Noncompliant } private Object[] getPerson() { Object[] result = new Object[2]; result[0] = "John"; result[1] = 25; return result; // Noncompliant } ``` ```java Fix theme={"system"} record Person(String name, int age) {} Person getPerson() { String name = "John"; int age = 25; return new Person(name, age); // Compliant } ```

The Object.clone / java.lang.Cloneable mechanism in Java should be considered broken for the following reasons and should, consequently, not be used:

  • Cloneable is a marker interface without API but with a contract about class behavior that the compiler cannot enforce. This is a bad practice.

  • Classes are instantiated without calling their constructor, so possible preconditions cannot be enforced.

  • There are implementation flaws by design when overriding Object.clone, like type casts or the handling of CloneNotSupportedException exceptions.

```java Bad theme={"system"} class Entity implements Cloneable { // Noncompliant, using `Cloneable` public int value; public List children; // deep copy wanted Entity() { EntityManager.register(this); // invariant } @Override public Entity clone() { try { Entity copy = (Entity) super.clone(); // invariant not enforced, because no constructor is caled copy.children = children.stream().map(Entity::clone).toList(); return copy; } catch (CloneNotSupportedException e) { // this will not happen due to behavioral contract throw new AssertionError(); } } } ``` ```java Fix theme={"system"} class Entity { // Compliant public int value; public List children; // deep copy wanted Entity() { EntityManager.register(this); // invariant } Entity(Entity template) { value = template.value; children = template.children.stream().map(Entity::new).toList(); } } ```

\`PreparedStatements and CallableStatements (for stored procedures) are safer and more efficient than Statements and should always be preferred.

This rule raises an issue each time a Statement\` is declared.

```java Bad theme={"system"} Statement stmt = null; // Noncompliant // ... ``` ```java Fix theme={"system"} PreparedStatement stmt = null; // ... ```

The Java Collections API offers a well-structured hierarchy of interfaces designed to hide collection implementation details. For the various collection data structures like lists, sets, and maps, specific interfaces (java.util.List, java.util.Set, java.util.Map) cover the essential features.

When passing collections as method parameters, return values, or when exposing fields, it is generally recommended to use these interfaces instead of the implementing classes. The implementing classes, such as java.util.LinkedList, java.util.ArrayList, and java.util.HasMap, should only be used for collection instantiation. They provide finer control over the performance characteristics of those structures, and developers choose them depending on their use case.

For example, if fast random element access is essential, java.util.ArrayList should be instantiated. If inserting elements at a random position into a list is crucial, a java.util.LinkedList should be preferred. However, this is an implementation detail your API should not expose.

```java Bad theme={"system"} public class Employees { public final HashSet employees // Noncompliant, field type should be "Set" = new HashSet(); public HashSet getEmployees() { // Noncompliant, return type should be "Set" return employees; } } ``` ```java Fix theme={"system"} public class Employees { public final Set employees // Compliant = new HashSet(); public Set getEmployees() { // Compliant return employees; } } ```

There are many ways to implement the Singleton pattern in Java, but none of them is as clean, compact and close to fool-proof as using an enum. Without an enum, the implementer must take care to properly handle thread-safety, serialization, and classloaders, but those things come for free with an enum.

```java Bad theme={"system"} public class Highlander implements Serializable { // Serializable makes Singleton tricky to get right private static final Highlander INSTANCE; public static synchronized Highlander getInstance() { if(INSTANCE == null) { INSTANCE = new Highlander(); } return INSTANCE; } private Highlander () {} private final String [] rivals = {"The Kurgan", "Ramirez"}; // oops, not serializable now private Object readResolve() { return INSTANCE; } ... } ``` ```java Fix theme={"system"} public enum Highlander { INSTANCE; private final String [] rivals = {"The Kurgan", "Ramirez"}; ... } ```

According to the EJB specification:

An enterprise bean must not attempt to listen on a socket, accept connections on a socket, or use a socket for multicast.

…​

  • The enterprise bean must not attempt to set the socket factory used by ServerSocket, Socket, or the stream handler factory used by URL.

These networking functions are reserved for the EJB container. Allowing the enterprise bean to use these functions could compromise security and decrease the container’s ability to properly manage the runtime environment.

Since EJB’s may be passivated (temporarily serialized at the discretion of the container), using sockets in an EJB could cause resource leaks. Instead, you should work at a higher level and let the container handle such resources.

This rule raises an issue each time a socket is created or or retrieved from another class in a servlet class or EJB.

```java Bad theme={"system"} public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // ... Socket sock = null; try { sock = new Socket(host, 3000); // Noncompliant // ... } catch (Exception e) { // ... } } ``` ```java Fix theme={"system"} ```

This rule raises an issue when required properties are not included in a project’s pom.

```java Bad theme={"system"} Manufacturing ``` ```java Fix theme={"system"} ```

Java 21 has introduced enhancements to switch statements and expressions, allowing them to operate on any type, not just specific ones, as in previous versions. Furthermore, case labels have been upgraded to support patterns, providing an alternative to the previous restriction of only accepting constants.

```java Bad theme={"system"} // As of Java 21 String patternMatchSwitch(Object obj) { return switch (obj) { case String s -> String.format("String %s", s); case Integer i -> String.format("int %d", i); default -> obj.toString(); }; } ``` ```java Fix theme={"system"} String guardedCaseSwitch(Object obj) { return switch (obj) { case String s when s.length() > 0 -> String.format("String %s", s); case Integer i when i > 0 -> String.format("int %d", i); default -> obj.toString(); }; } ```

It is equivalent to use the equality \`== operator and the equals method to compare two objects if the equals method inherited from Object has not been overridden. In this case both checks compare the object references.

But as soon as equals is overridden, two objects not having the same reference but having the same value can be equal. This rule spots suspicious uses of == and != operators on objects whose equals\` methods are overridden.

```java Bad theme={"system"} String firstName = getFirstName(); // String overrides equals String lastName = getLastName(); if (firstName == lastName) { ... }; // Non-compliant; false even if the strings have the same value ``` ```java Fix theme={"system"} String firstName = getFirstName(); String lastName = getLastName(); if (firstName != null && firstName.equals(lastName)) { ... }; ```

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.

```java Bad theme={"system"} public void doSomething(List inputs) { for (String input : inputs) { Marshaller m = JAXBContext.newInstance(MyObj.class).createMarshaller(); // Noncompliant; context created in loop // ... } } public List getContexts(List inputs) { List result = new ArrayList<>(); for (Class input : inputs) { result.add(JAXBContext.newInstance(input); // Compliant; context path varies } return result; } public void doSomething2(List inputs) { Marshaller m = JAXBContext.newInstance(MyObj.class).createMarshaller(); // Noncompliant; context created each time method invoked for (String input : inputs) { // ... } } ``` ```java Fix theme={"system"} private static JAXBContext context; static { try { context = JAXBContext.newInstance(MyObj.class); } catch (JAXBException e) { // handle exception... } } public void doSomething(List inputs) { Marshaller m = context.createMarshaller(); for (String input : inputs) { // ... } } public List getContexts(List inputs) { List result = new ArrayList<>(); for (Class input : inputs) { result.add(JAXBContext.newInstance(input); } return result; } ```

A common good practice is to write test methods targeting only one logical concept, that can only fail for one reason.

While it might make sense to have more than one assertion to test one concept, having too many is a sign that a test became too complex and should be refactored to multiples ones.

This rule will report any test method containing more than a given number of assertion.

```java Bad theme={"system"} @Test void test() { // Refactor this method. assertEquals(1, f(1)); assertEquals(2, f(2)); assertEquals(3, g(1)); } ``` ```java Fix theme={"system"} void test_f() { assertEquals(1, f(1)); assertEquals(2, f(2)); } void test_g() { assertEquals(3, g(1)); } ```

A non-static inner class has a reference to its outer class, and access to the outer class' fields and methods. That class reference makes the inner class larger and could cause the outer class instance to live in memory longer than necessary.

If the reference to the outer class isn’t used, it is more efficient to make the inner class \`static (also called nested). If the reference is used only in the class constructor, then explicitly pass a class reference to the constructor. If the inner class is anonymous, it will also be necessary to name it.

However, while a nested/static class would be more efficient, it’s worth noting that there are semantic differences between an inner class and a nested one:

  • an inner class can only be instantiated within the context of an instance of the outer class.

  • a nested (static\`) class can be instantiated independently of the outer class.

```java Bad theme={"system"} public class Fruit { // ... public class Seed { // Noncompliant; there's no use of the outer class reference so make it static int germinationDays = 0; public Seed(int germinationDays) { this.germinationDays = germinationDays; } public int getGerminationDays() { return germinationDays; } } } ``` ```java Fix theme={"system"} public class Fruit { // ... public static class Seed { int germinationDays = 0; public Seed(int germinationDays) { this.germinationDays = germinationDays; } public int getGerminationDays() { return germinationDays; } } } ```

Cloneable is a marker interface that defines the contract of the Object.clone method, which is to create a consistent copy of the instance. The clone method is not defined by the interface though, but by class Objects.

The general problem with marker interfaces is that their definitions cannot be enforced by the compiler because they have no own API. When a class implements Cloneable but does not override Object.clone, it is highly likely that it violates the contract for Cloneable.

```java Bad theme={"system"} class Foo implements Cloneable { // Noncompliant, override `clone` method public int value; } ``` ```java Fix theme={"system"} class Foo implements Cloneable { // Compliant public int value; @Override public Foo clone() { try { return (Foo) super.clone(); } catch (CloneNotSupportedException e) { throw new AssertionError(); } } } ```

Annotating unit tests with more than one test-related annotation is not only useless but could also result in unexpected behavior like failing tests or unwanted side-effects.

This rule reports an issue when a test method is annotated with more than one of the following competing annotation:

  • @Test

  • @RepeatedTest

  • @ParameterizedTest

  • @TestFactory

  • @TestTemplate

```java Bad theme={"system"} @Test @RepeatedTest(2) // Noncompliant, this test will be repeated 3 times void test() { } @ParameterizedTest @Test @MethodSource("methodSource") void test2(int argument) { } // Noncompliant, this test will fail with ParameterResolutionException ``` ```java Fix theme={"system"} @RepeatedTest(2) void test() { } @ParameterizedTest @MethodSource("methodSource") void test2(int argument) { } ```

Java 8 adds \`Comparator.comparing to allow the creation of a single-value comparator to be shorthanded into a single call. This cleaner syntax should be preferred.

Note that this rule is automatically disabled when the project’s sonar.java.source is lower than 8\`.

```java Bad theme={"system"} Comparator compartor = (foo1, foo2) -> foo.getName().compareTo(foo2.getName()); // Noncompliant ``` ```java Fix theme={"system"} Comparator compartor = Comparator.comparing(Foo::getName); ```

Including any logic other than a simple return of the field in a persistence-annotated method can result in odd behavior, including for example, the default construction of empty members which are annotated to be lazy.

```java Bad theme={"system"} private Double price; @Columm(name="price") public Double getPrice() { if(buyer.isLoaltyMember()) { // Noncompliant return price - getLoyaltyDiscount(); } else { return price; } } ``` ```java Fix theme={"system"} @Columm(name="price") private Double price; public Double getPrice() { if(buyer.isLoaltyMember()) { return price - getLoyaltyDiscount(); } else { return price; } } ```

Shared naming conventions allow teams to collaborate efficiently. This rule raises an issue when a test method name does not match the provided regular expression.

```java Bad theme={"system"} @Test public void foo() { // Noncompliant //... } ``` ```java Fix theme={"system"} @Test public void testFoo() { // ... } ```

AssertJ assertions taking \`Consumer objects as arguments are expected to contain "requirements", which should themselves be expressed as assertions. This concerns the following methods: allSatisfy, anySatisfy, hasOnlyOneElementSatisfyingisInstanceOfSatisfyingnoneSatisfy, satisfies, satisfiesAnyOfzipSatisfy.

These methods are assuming the Consumer will do the assertions itself. If you do not do any assertion in the Consumer, it probably means that you are inadvertently only partially testing your object.

This rule raises an issue when a Consumer\` argument of any of the above methods does not contain any assertion.

```java Bad theme={"system"} assertThat(myObject).isInstanceOfSatisfying(String.class, s -> "Hello".equals(s)); // Noncompliant - not testing the string value assertThat(myObject).satisfies("Hello"::equals); // Noncompliant - not testing the string value ``` ```java Fix theme={"system"} assertThat(myObject).isInstanceOfSatisfying(String.class, s -> assertThat(s).isEqualTo("Hello")); assertThat(myObject).satisfies(obj -> assertThat(obj).isEqualTo("Hello")); ```

Serialization is a platform-independent mechanism for writing the state of an object into a byte-stream. For serializing the object, we call the writeObject() method of java.io.ObjectOutputStream class. Only classes that implement Serializable or extend a class that does it can successfully be serialized (or de-serialized).

Attempting to write a class with the writeObject method of the ObjectOutputStream class that does not implement Serializable or extends a class that implements it, will throw an IOException.

```java Bad theme={"system"} public class Vegetable { // ... } public class Menu { public void meal(ObjectOutputStream oos) throws IOException { Vegetable veg = new Vegetable(); oos.writeObject(veg); // Noncompliant } } ``` ```java Fix theme={"system"} public class Vegetable implements Serializable { // ... } public class Menu { public void meal(ObjectOutputStream oos) throws IOException { Vegetable veg = new Vegetable(); oos.writeObject(veg); } } ```

Providing a \`serialVersionUID field on Serializable classes is strongly recommended by the Serializable documentation but blindly following that recommendation can be harmful.

serialVersionUID value is stored with the serialized data and this field is verified when deserializing the data to ensure that the code reading the data is compatible with the serialized data. In case of failure, it means the serialized data and the code are not in sync and this fine because you know what’s wrong.

When the serialVersionUID is generated by an IDE or blindly hard-coded, there is a high probability that one will forget to update the serialVersionUID value when the Serializable class is later enriched with additional fields. As a consequence, old serialized data will incorrectly be considered compatible with the newer version of the code creating situations which are hard to debug.

Therefore, defining serialVersionUID should be done with care. This rule raises an issue on each serialVersionUID field declared on classes implementing Serializable to be sure the presence and the value of the serialVersionUID\` field is challenged and validated by the team.

```java Bad theme={"system"} public class Foo implements Serializable { private static final long serialVersionUID = 1; } public class BarException extends RuntimeException { private static final long serialVersionUID = 8582433437601788991L; } ``` ```java Fix theme={"system"} ```

The \`Files.exists method has noticeably poor performance in JDK 8, and can slow an application significantly when used to check files that don’t actually exist.

The same goes for Files.notExists, Files.isDirectory and Files.isRegularFile from java.nio.file package.

Note that this rule is automatically disabled when the project’s sonar.java.source\` is not 8.

```java Bad theme={"system"} Path myPath; if(java.nio.file.Files.exists(myPath)) { // Noncompliant // do something } ``` ```java Fix theme={"system"} Path myPath; if(myPath.toFile().exists())) { // do something } ```

Catching \`Exception seems like an efficient way to handle multiple possible exceptions. Unfortunately, it traps all exception types, both checked and runtime exceptions, thereby casting too broad a net. Indeed, was it really the intention of developers to also catch runtime exceptions? To prevent any misunderstanding, if both checked and runtime exceptions are really expected to be caught, they should be explicitly listed in the catch clause.

This rule raises an issue if Exception is caught when it is not explicitly thrown by a method in the try\` block.

```java Bad theme={"system"} try { // do something that might throw an UnsupportedDataTypeException or UnsupportedEncodingException } catch (Exception e) { // Noncompliant // log exception ... } ``` ```java Fix theme={"system"} try { // do something } catch (UnsupportedEncodingException|UnsupportedDataTypeException|RuntimeException e) { // log exception ... } ```

Mockito provides argument matchers and argument captors for flexibly stubbing or verifying method calls.

Mockito.verify(), Mockito.when(), Stubber.when() and BDDMockito.given() each have overloads with and without argument matchers.

However, if argument matchers or captors are used only on some of the parameters, all the parameters need to have matchers as well, otherwise an InvalidUseOfMatchersException will be thrown.

This rule consequently raises an issue every time matchers are not used on all the parameters of a stubbed/verified method.

```java Bad theme={"system"} @Test public void myTest() { // Setting up mock responses given(foo.bar(anyInt(), i1, i2)).willReturn(null); // Noncompliant, no matchers for "i1" and "i2" when(foo.baz(eq(val1), val2)).thenReturn("hi"); // Noncompliant, no matcher for "val2" // Simulating exceptions doThrow(new RuntimeException()).when(foo).quux(intThat(x -> x >= 42), -1); // Noncompliant, no matcher for "-1" // Verifying method invocations verify(foo).bar(i1, anyInt(), i2); // Noncompliant, no matchers for "i1" and "i2" // Capturing arguments for verification ArgumentCaptor captor = ArgumentCaptor.forClass(Integer.class); verify(foo).bar(captor.capture(), i1, any()); // Noncompliant, no matchers for "i1" } ``` ```java Fix theme={"system"} @Test public void myTest() { // Setting up mock responses given(foo.bar(anyInt(), eq(i1), eq(i2))).willReturn(null); // Compliant, all arguments have matchers when(foo.baz(val1, val2)).thenReturn("hi"); // Compliant, no argument has matchers // Simulating exceptions doThrow(new RuntimeException()).when(foo).quux(intThat(x -> x >= 42), eq(-1)); // Compliant, all arguments have matchers // Verifying method invocations verify(foo).bar(eq(i1), anyInt(), eq(i2)); // Compliant, all arguments have matchers // Capturing arguments for verification ArgumentCaptor captor = ArgumentCaptor.forClass(Integer.class); verify(foo).bar(captor.capture(), any(), any()); // Compliant, all arguments have matchers } ```

The Thread class has some methods that are used to monitor and manage its execution. With the introduction of virtual threads in Java 21, there are three of these methods that behave differently between the standard platform threads and the virtual ones.

For virtual threads:

  • Thread.setDaemon(boolean) will throw an IllegalArgumentException if false is passed as an argument as a virtual thread daemon status is always true.

  • Thread.setPriority(int priority) will never change the actual priority of a virtual thread, which is always equal to Thread.NORM\_PRIORITY

  • Thread.getThreadGroup() will return a dummy "VirtualThreads" group that is empty and should not be used

This rule reports an issue when one of these methods is invoked on a virtual thread.

```java Bad theme={"system"} Thread t = Thread.ofVirtual().unstarted(()->{/* some task */}); t.setPriority(1); // Noncompliant; virtual threads' priority cannot be changed t.setDaemon(false); // Noncompliant; will throw IllegalArgumentException t.setDaemon(true); // Noncompliant; redundant t.start(); var threadGroup = t.getThreadGroup(); // Noncompliant; virtual thread groups should not be used ``` ```java Fix theme={"system"} ```

The likely intention of a user calling Thread.run() is to start the execution of code within a new thread. This, however, is not what happens when this method is called.

The purpose of Thread.run() is to provide a method that users can overwrite to specify the code to be executed. The actual thread is then started by calling Thread.start(). When Thread.run() is called directly, it will be executed as a regular method within the current thread.

```java Bad theme={"system"} Thread myThread = new Thread(runnable); myThread.run(); // Noncompliant, does not start a thread ``` ```java Fix theme={"system"} Thread myThread = new Thread(runnable); myThread.start(); // Compliant ```

To prevent URL spoofing, HostnameVerifier.verify() methods should do more than simply return true. Doing so may get you quickly past an exception, but that comes at the cost of opening a security hole in your application.

```java Bad theme={"system"} SSLContext sslcontext = SSLContext.getInstance( "TLS" ); sslcontext.init(null, new TrustManager[]{new X509TrustManager() { public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {} public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {} public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; } }}, new java.security.SecureRandom()); Client client = ClientBuilder.newBuilder().sslContext(sslcontext).hostnameVerifier(new HostnameVerifier() { @Override public boolean verify(String requestedHost, SSLSession remoteServerSession) { return true; // Noncompliant } }).build(); ``` ```java Fix theme={"system"} SSLContext sslcontext = SSLContext.getInstance( "TLSv1.2" ); sslcontext.init(null, new TrustManager[]{new X509TrustManager() { @Override public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {} @Override public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {} @Override public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; } }}, new java.security.SecureRandom()); Client client = ClientBuilder.newBuilder().sslContext(sslcontext).hostnameVerifier(new HostnameVerifier() { @Override public boolean verify(String requestedHost, SSLSession remoteServerSession) { return requestedHost.equalsIgnoreCase(remoteServerSession.getPeerHost()); // Compliant } }).build(); ```

Non-abstract classes and enums with non-static, private members should explicitly initialize those members, either in a constructor or with a default value.

```java Bad theme={"system"} class A { // Noncompliant private int field; } ``` ```java Fix theme={"system"} class A { private int field; A(int field) { this.field = field; } } ```

Naming a thread won’t make it run faster or more reliably, but it will make it easier to deal with if you need to debug the application.

```java Bad theme={"system"} Thread t1 = new Thread(new Runnable() { // ... }; t1.start(); // Noncompliant; this thread wasn't named ``` ```java Fix theme={"system"} Thread t1 = new Thread(new Runnable() { // ... }; t1.setName("t1"); t1.start(); ```

In Java, value-based classes are those for which instances are final and immutable, like String, Integer and so on, and their identity relies on their value and not their reference. When a variable of one of these types is instantiated, the JVM caches its value, and the variable is just a reference to that value. For example, multiple String variables with the same value "Hello world!" will refer to the same cached string literal in memory.

The synchronized keyword tells the JVM to only allow the execution of the code contained in the following block to one Thread at a time. This mechanism relies on the identity of the object that is being synchronized between threads, to prevent that if object X is locked, it will still be possible to lock another object Y.

It means that the JVM will fail to correctly synchronize threads on instances of the aforementioned value-based classes, for instance:

```java Bad theme={"system"} // These variables "a" and "b" will effectively reference the same object in memory Integer a = 0; Integer b = 0; // This means that in the following code, the JVM could try to lock and execute // on the variable "a" because "b" was notified to be released, as the two Integer variables // are the same object to the JVM void syncMethod(int x) { synchronized (a) { if (a == x) { // ... do something here } } synchronized (b) { if (b == x) { // ... do something else } } } ``` ```java Fix theme={"system"} private static final Boolean bLock = Boolean.FALSE; private static final Integer iLock = Integer.valueOf(0); private static final String sLock = "LOCK"; private static final List listLock = List.of("a", "b", "c", "d"); public void doSomething() { synchronized(bLock) { // Noncompliant ... } synchronized(iLock) { // Noncompliant ... } synchronized(sLock) { // Noncompliant ... } synchronized(listLock) { // Noncompliant ... } ```

In asynchronous testing, the test code is written in a way that allows it to wait for the asynchronous operation to complete before continuing with the test.

Using Thread.sleep in this case can cause flaky tests, slow test execution, and inaccurate test results. It creates brittle tests that can fail unpredictably depending on the environment or load.

Use mocks or libraries such as Awaitility instead. These tools provide features such as timeouts, assertions, and error handling to make it easier to write and manage asynchronous tests.

```java Bad theme={"system"} @Test public void testDoTheThing(){ MyClass myClass = new MyClass(); myClass.doTheThing(); Thread.sleep(500); // Noncompliant // assertions... } ``` ```java Fix theme={"system"} @Test public void testDoTheThing(){ MyClass myClass = new MyClass(); myClass.doTheThing(); await().atMost(2, Duration.SECONDS).until(didTheThing()); // Compliant // assertions... } private Callable didTheThing() { return new Callable() { public Boolean call() throws Exception { // check the condition that must be fulfilled... } }; } ```

Before it reclaims storage from an object that is no longer referenced, the garbage collector calls finalize() on the object.

This is a good time to release resources held by the object.

Because the general contract is that the finalize method should only be called once per object, calling this method explicitly is misleading and does not respect this contract.

```java Bad theme={"system"} public void dispose() throws Throwable { this.finalize(); // Noncompliant } ``` ```java Fix theme={"system"} ```

When two locks are held simultaneously, a wait call only releases one of them. The other will be held until some other thread requests a lock on the awaited object. If no unrelated code tries to lock on that object, then all other threads will be locked out, resulting in a deadlock.

```java Bad theme={"system"} synchronized (this.mon1) { // threadB can't enter this block to request this.mon2 lock & release threadA synchronized (this.mon2) { this.mon2.wait(); // Noncompliant; threadA is stuck here holding lock on this.mon1 } } ``` ```java Fix theme={"system"} ```

Resources that can be reused across multiple invocations of the Lambda function should be initialized at construction time. For example in the constructor of the class, or in field initializers. This way, when the same container is reused for multiple function invocations, the existing instance can be reused, along with all resources stored in its fields. It is a good practice to reuse SDK clients and database connections by initializing them at class construction time, to avoid recreating them on every lambda invocation. Failing to do so can lead to performance degradation, and when not closed properly, even out of memory errors.

This rule reports an issue when the SDK client or the database connection is initialized locally inside a Lambda function.

```java Bad theme={"system"} public class App implements RequestHandler { @Override public Object handleRequest(final Object input, final Context context) { S3Client s3Client = DependencyFactory.s3Client(); s3Client.listBuckets(); // ... } } ``` ```java Fix theme={"system"} public class App implements RequestHandler { private final S3Client s3Client; public App() { s3Client = DependencyFactory.s3Client(); } @Override public Object handleRequest(final Object input, final Context context) { s3Client.listBuckets(); // ... } } ```

Java 21 adds new String.indexOf methods that accept ranges (beginIndex, to endIndex) rather than just a start index. A StringIndexOutOfBounds can be thrown when indicating an invalid range, namely when:

  • beginIndex > endIndex (eg: beginIndex and endIndex arguments are mistakenly reversed)

  • beginIndex \< 0 (eg: because the older String.indexOf(what, fromIndex) accepts negative values)

```java Bad theme={"system"} String hello = "Hello, world!"; int index = hello.indexOf('o', 11, 7); // Noncompliant, 11..7 is not a valid range ``` ```java Fix theme={"system"} String hello = "Hello, world!"; int index = hello.indexOf('o', 7, 11); // Compliant ```

An inner class that extends another type can call methods from both the outer class and parent type directly, without prepending super. or Outer.this..

When both the outer and parent classes contain a method with the same name, the compiler will resolve an unqualified call to the parent type’s implementation. The maintainer or a future reader may confuse the method call as calling the outer class’s implementation, even though it really calls the super type’s.

To make matters worse, the maintainer sees the outer class’s implementation in the same file as the call in the inner class, while the parent type is often declared in another file. The maintainer may not even be aware of the ambiguity present, as they do not see the parent’s implementation.

```java Bad theme={"system"} public class Parent { public void foo() { ... } } public class Outer { public void foo() { ... } public class Inner extends Parent { public void doSomething() { foo(); // Noncompliant, it is not explicit if Outer#foo or Parent#foo is the intended implementation to be called. // ... } } } ``` ```java Fix theme={"system"} public class Parent { public void foo() { ... } } public class Outer { public void foo() { ... } public class Inner extends Parent { public void doSomething() { super.foo(); // Compliant, it is explicit that Parent#foo is the desired implementation to be called. // ... } } } ```

An XML External Entity or XSLT External Entity (XXE) vulnerability can occur when a \`javax.xml.transform.Transformer is created without enabling "Secure Processing" or when one is created without disabling resolving of both external DTDs and DTD entities. If that external data is being controlled by an attacker it may lead to the disclosure of confidential data, denial of service, server side request forgery, port scanning from the perspective of the machine where the parser is located, and other system impacts.

This rule raises an issue when a Transformer\` is created without either of these settings.

```java Bad theme={"system"} Transformer transformer = TransformerFactory.newInstance().newTransformer(); transformer.transform(input, result); ``` ```java Fix theme={"system"} TransformerFactory factory = TransformerFactory.newInstance(); factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, ""); Transformer transformer = factory.newTransformer(); transformer.transform(input, result); ```

There is no need to declare a type parameter when naming a type constraint is not required. Using wildcards makes it easier to read.

```java Bad theme={"system"} void foo(List list) { // Noncompliant, T is used only once for (MyClass myObj : list) { doSomething(myObj); } } ``` ```java Fix theme={"system"} void foo(List list) { for (MyClass myObj : list) { doSomething(myObj); } } ```

Overriding a parent class method prevents that method from being called unless an explicit super call is made in the overriding method. In some cases, not calling the parent method is fine. However, setUp and tearDown provide some shared logic that is called before all test cases. This logic may change over the lifetime of your codebase. To make sure that your test cases are set up and cleaned up consistently, your overriding implementations of setUp and tearDown should call the parent implementations explicitly.

```java Bad theme={"system"} public class MyClassTest extends MyAbstractTestCase { private MyClass myClass; @Override protected void setUp() throws Exception { // Noncompliant myClass = new MyClass(); } } ``` ```java Fix theme={"system"} public class MyClassTest extends MyAbstractTestCase { private MyClass myClass; @Override protected void setUp() throws Exception { super.setUp(); myClass = new MyClass(); } } ```

If you end up mocking every non-private method of a class in order to write tests, it is a strong sign that your test became too complex, or that you misunderstood the way you are supposed to use the mocking mechanism.

You should either refactor the test code into multiple units, or consider using the class itself, by either directly instantiating it, or creating a new one inheriting from it, with the expected behavior.

This rule reports an issue when every member of a given class are mocked.

```java Bad theme={"system"} @Test void test_requiring_MyClass() { MyClass myClassMock = mock(MyClass.class); // Noncompliant when(myClassMock.f()).thenReturn(1); when(myClassMock.g()).thenReturn(2); //... } abstract class MyClass { abstract int f(); abstract int g(); } ``` ```java Fix theme={"system"} @Test void test_requiring_MyClass() { MyClass myClass = new MyClassForTest(); //... } class MyClassForTest extends MyClass { @Override int f() { return 1; } @Override int g() { return 2; } } ```

AssertJ assertions \`allMatch and doesNotContains on an empty list always returns true whatever the content of the predicate. Despite being correct, you should make explicit if you expect an empty list or not, by adding isEmpty()/isNotEmpty() in addition to calling the assertion, or by testing the list’s content further. It will justify the useless predicate to improve clarity or increase the reliability of the test.

This rule raises an issue when any of the methods listed are used without asserting that the list is empty or not and without testing the content.

Targetted methods:

  • allMatch

  • allSatisfy

  • doesNotContain

  • doesNotContainSequence

  • doesNotContainSubsequence

  • doesNotContainAnyElementsOf\`

```java Bad theme={"system"} List logs = getLogs(); assertThat(logs).allMatch(e -> e.contains(“error”)); // Noncompliant, this test pass if logs are empty! assertThat(logs).doesNotContain("error"); // Noncompliant, do you expect any log? ``` ```java Fix theme={"system"} List logs = getLogs(); assertThat(logs).isNotEmpty().allMatch(e -> e.contains(“error”)); // Or assertThat(logs).hasSize(5).allMatch(e -> e.contains(“error”)); // Or assertThat(logs).isEmpty(); // Despite being redundant, this is also acceptable since it explains why you expect an empty list assertThat(logs).doesNotContain("error").isEmpty(); // or test the content of the list further assertThat(logs).contains("warning").doesNotContain("error"); ```

In Spring applications, application components that expose interfaces should be package protected at most, not public. Such reduced visibility helps ensure that the interface is only accessed through the container and not directly.

```java Bad theme={"system"} // TODO ``` ```java Fix theme={"system"} // TODO ```

No matter whether the optional value is present or not, \`Optional::orElse's argument will always be executed. This is usually not what the developer intended when the content of the orElse() call has side effects. Even when no side effect is involved, the unnecessary computation of the orElse() clause might be a waste of resources.

Calls to Optional::orElse should be replaced with Optional::orElseGet whenever the alternative value is not a constant.

This rule raises an issue when Optional::orElse\` is called with an argument that doesn’t evaluate to a constant value.

```java Bad theme={"system"} Optional opt = getOptMyObj(); MyObj myObj = opt.orElse(new MyObj()); // Noncompliant ``` ```java Fix theme={"system"} Optional opt = getOptMyObj(); MyObj myObj = opt.orElseGet(MyObj::new); Optional optString = getOptString(); String str = opt.orElse("hello"); ```

Characters like 'é' can be expressed either as a single code point or as a cluster of the letter 'e' and a combining accent mark. Without the CANON\_EQ flag, a regex will only match a string in which the characters are expressed in the same way.

```java Bad theme={"system"} String s = "e\u0300"; Pattern p = Pattern.compile("é|ë|è"); // Noncompliant System.out.println(p.matcher(s).replaceAll("e")); // print 'è' ``` ```java Fix theme={"system"} String s = "e\u0300"; Pattern p = Pattern.compile("é|ë|è", Pattern.CANON_EQ); System.out.println(p.matcher(s).replaceAll("e")); // print 'e' ```

Calling Iterator.hasNext() is not supposed to have any side effects and hence should not change the iterator’s state. Iterator.next() advances the iterator by one item. So calling it inside Iterator.hasNext() breaks the hasNext() contract and will lead to unexpected behavior in production.

```java Bad theme={"system"} class MyIterator implements Iterator { private Queue elements; ... @Override public boolean hasNext() { try { next(); // Noncompliant, next() is called from hasNext() return true; } catch (NoSuchElementException e) { return false; } } @Override public Integer next() { return elements.remove(); } } ``` ```java Fix theme={"system"} class MyIterator implements Iterator { private Queue elements; ... @Override public boolean hasNext() { return !elements.isEmpty(); // Compliant, no call to next() } @Override public Integer next() { return elements.remove(); } } ```

While you can use either forEach(list::add) or collect with a Stream, collect is by far the better choice because it’s automatically thread-safe and parallellizable.

```java Bad theme={"system"} List bookNames = new ArrayList<>(); books.stream().filter(book -> book.getIsbn().startsWith("0")) .map(Book::getTitle) .forEach(bookNames::add); // Noncompliant ``` ```java Fix theme={"system"} List bookNames = books.stream().filter(book -> book.getIsbn().startsWith("0")) .map(Book::getTitle) .collect(Collectors.toList()); ```

Constructors should not access the values of fields that haven’t yet been initialized.

```java Bad theme={"system"} public abstract class MyAbstractClass() { String name; String fname; int hashCode; public abstract String getValue(); public MyAbstractClass(String name) { this.fname = this.name.split()[0]; // Noncompliant; this.name not assigned yet this.hashCode = getValue().hashCode(); // Noncompliant; child class constructor hasn't run yet } } ``` ```java Fix theme={"system"} ```

The contract of the Object.finalize() method is clear: only the Garbage Collector is supposed to call this method.

Making this method public is misleading, because it implies that any caller can use it.

```java Bad theme={"system"} public class MyClass { @Override public void finalize() { // Noncompliant /* ... */ } } ``` ```java Fix theme={"system"} ```

\`getClass should not be used for synchronization in non-final classes because child classes will synchronize on a different object than the parent or each other, allowing multiple threads into the code block at once, despite the synchronized keyword.

Instead, hard code the name of the class on which to synchronize or make the class final\`.

```java Bad theme={"system"} public class MyClass { public void doSomethingSynchronized(){ synchronized (this.getClass()) { // Noncompliant // ... } } ``` ```java Fix theme={"system"} public class MyClass { public void doSomethingSynchronized(){ synchronized (MyClass.class) { // ... } } ```

Since assert statements aren’t executed by default (they must be enabled with JVM flags) developers should never rely on their execution the evaluation of any logic required for correct program function.

```java Bad theme={"system"} assert myList.remove(myList.get(0)); // Noncompliant ``` ```java Fix theme={"system"} boolean removed = myList.remove(myList.get(0)); assert removed; ```

A for loop with a counter moving away from the end of the specified range is likely a programming mistake.

If the intention is to iterate over the specified range, this differs from what the loop does because the counter moves in the wrong direction.

If the intention is to have an infinite loop or a loop terminated only by a break statement, there are two problems:

  1. The loop condition is not infinite because the counter variable will eventually overflow and fulfill the condition. This can take a long time, depending on the data type of the counter.

  2. An infinite loop terminated by a break statement should be implemented using a while or do while loop to make the developer’s intention clear to the reader.

```java Bad theme={"system"} for (int i = 10; i > 0; i++) { // Noncompliant, wrong direction System.out.println("Hello, world!") // executed ca. 2 billion times } ``` ```java Fix theme={"system"} public void doSomething(String [] strings) { for (int i = 0; i < strings.length; i--) { // Noncompliant, wrong direction String string = strings[i]; // ArrayIndexOutOfBoundsException when i reaches -1 // ... } } ```

This rule allows banning usage of certain constructors.

```java Bad theme={"system"} Date birthday; birthday = new Date("Sat Sep 27 05:42:21 EDT 1986"); // Noncompliant birthday = new Date(528176541000L); // Compliant ``` ```java Fix theme={"system"} ```

The methods declared in an \`interface are public and abstract by default. Any variables are automatically public static final. Finally, class and interface are automatically public static. There is no need to explicitly declare them so.

Since annotations are implicitly interfaces, the same holds true for them as well.

Similarly, the final modifier is redundant on any method of a final class, private is redundant on the constructor of an Enum, and static is redundant for interface nested into a class or enum\`.

```java Bad theme={"system"} public interface Vehicle { public void go(int speed, Direction direction); // Noncompliant ``` ```java Fix theme={"system"} public interface Vehicle { void go(int speed, Direction direction); ```

When testing exception via @Test annotation, having additional assertions inside that test method can be problematic because any code after the raised exception will not be executed. It will prevent you to test the state of the program after the raised exception and, at worst, make you misleadingly think that it is executed.

You should consider moving any assertions into a separate test method where possible, or using org.junit.Assert.assertThrows instead.

Alternatively, you could use try-catch idiom for JUnit version \< 4.13 or if your project does not support lambdas.

```java Bad theme={"system"} @Test(expected = IndexOutOfBoundsException.class) public void testShouldFail() { get(); // This test pass since execution will never get past this line. Assert.assertEquals(0, 1); } private Object get() { throw new IndexOutOfBoundsException(); } ``` ```java Fix theme={"system"} // This test correctly fails. @Test public void testToString() { Object obj = get(); Assert.assertThrows(IndexOutOfBoundsException.class, () -> obj.toString()); Assert.assertEquals(0, 1); } ```

AssertJ assertions methods targeting the same object can be chained instead of using multiple \`assertThat. It avoids duplication and increases the clarity of the code.

This rule raises an issue when multiples assertThat\` target the same tested value.

```java Bad theme={"system"} assertThat(someList).hasSize(3); assertThat(someList).contains("something"); ``` ```java Fix theme={"system"} assertThat(someList) .hasSize(3) .contains("something"); ```

Calling toString() or clone() on an object should always return a string or an object. Returning null instead contravenes the method’s implicit contract.

```java Bad theme={"system"} public String toString () { if (this.collection.isEmpty()) { return null; // Noncompliant } else { // ... ``` ```java Fix theme={"system"} public String toString () { if (this.collection.isEmpty()) { return ""; } else { // ... ```

\`switch can contain a default clause for various reasons: to handle unexpected values, to show that all the cases were properly considered, etc.

For readability purposes, to help a developer quickly spot the default behavior of a switch statement, it is recommended to put the default clause at the end of the switch statement.

This rule raises an issue if the default clause is not the last one of the switch’s cases.

```java Bad theme={"system"} switch (param) { case 0: doSomething(); break; default: // Noncompliant: default clause should be the last one error(); break; case 1: doSomethingElse(); break; } ``` ```java Fix theme={"system"} ```

Java 7 introduced the ability to use a digit separator (\_) to split a literal number into groups of digits for better readability.

To ensure that readability is really improved by using digit separators, this rule verifies:

  • Homogeneity

    • Except for the left-most group, which can be smaller, all groups in a number should contain the same number of digits. Mixing group sizes is at best confusing for maintainers, and at worst a typographical error that is potentially a bug.

  • Standardization

    • It is also confusing to regroup digits using a size that is not standard. This rule enforce the following standards:

      • Decimal numbers should be separated using groups of 3 digits.

      • Hexadecimal numbers should be separated using groups of 2 or 4 digits.

      • Octal and Binary should be separated using groups of 2, 3 or 4 digits.

Furthermore, using groups with more than 4 consecutive digits is not allowed because they are difficult for maintainers to read.

```java Bad theme={"system"} long decimal_int_value = 1_554_3124L; // Noncompliant; mixing groups of 3 and 4 digits double decimal_float_value = 7_91_87_14.3456d; // Noncompliant; using groups of 2 instead of 3 digits long hexadecimal_value = 0x8_3A3_248_6E2L; // Noncompliant; using groups of 3 instead of 2 or 4 digits long octal_value = 0442_03433_13726L; // Noncompliant; using groups of 5 instead of 2, 3 or 4 digits. long binary_value = 0b01010110_11101010L; // Noncompliant; using groups of 8 instead of 2, 3 or 4 digits. ``` ```java Fix theme={"system"} long decimal_int_value = 15_543_124L; double decimal_float_value = 7_918_714.3456d; long hexadecimal_value = 0x83_A324_86E2L; long octal_value = 04_4203_4331_3726L; long binary_value = 0b0101_0110_1110_1010L; ```

By contract, fields in a Serializable class must themselves be either Serializable or transient. Even if the class is never explicitly serialized or deserialized, it is not safe to assume that this cannot happen. For instance, under load, most J2EE application frameworks flush objects to disk.

An object that implements Serializable but contains non-transient, non-serializable data members (and thus violates the contract) could cause application crashes and open the door to attackers. In general, a Serializable class is expected to fulfil its contract and not exhibit unexpected behaviour when an instance is serialized.

This rule raises an issue on:

  • Non-Serializable fields.

  • When a field is assigned a non-Serializable type within the class.

  • Collection fields when they are not private. Values that are not serializable could be added to these collections externally. Due to type erasure, it cannot be guaranteed that the collection will only contain serializable objects at runtime despite being declared as a collection of serializable types.

```java Bad theme={"system"} public class Address { ... } public class Person implements Serializable { private static final long serialVersionUID = 1905122041950251207L; private String name; private Address address; // Noncompliant, Address is not serializable } ``` ```java Fix theme={"system"} public class Address implements Serializable { private static final long serialVersionUID = 2405172041950251807L; ... } public class Person implements Serializable { private static final long serialVersionUID = 1905122041950251207L; private String name; private Address address; // Compliant, Address is serializable } ```

Using certain features of regular expressions, it is possible to create regular expressions that can never match or contain subpatterns that can never match. Since a pattern or sub-pattern that can never match any input is pointless, this is a sign that the pattern does not work as intended and needs to be fixed.

This rule finds some such regular expressions and subpatterns, specifically ones that meet one of the following conditions:

  • Beginning- and end-of-line/input boundaries appearing in a position where they can never match (e.g. an end-of-input marker being followed by other characters)

  • A back reference refers to a capturing group that will never be matched before the back reference

```java Bad theme={"system"} $[a-z]*^ ``` ```java Fix theme={"system"} \1(.) ```

A \`serialVersionUID field is strongly recommended in all Serializable classes. If you do not provide one, one will be calculated for you by the compiler. The danger in not explicitly choosing the value is that when the class changes, the compiler will generate an entirely new id, and you will be suddenly unable to deserialize (read from file) objects that were serialized with the previous version of the class.

serialVersionUID's should be declared with all of these modifiers: static final long\`.

```java Bad theme={"system"} public class Raspberry extends Fruit // Noncompliant; no serialVersionUID. implements Serializable { private String variety; public Raspberry(Season ripe, String variety) { ...} public void setVariety(String variety) {...} public String getVarity() {...} } public class Raspberry extends Fruit implements Serializable { private final int serialVersionUID = 1; // Noncompliant; not static & int rather than long ``` ```java Fix theme={"system"} public class Raspberry extends Fruit implements Serializable { private static final long serialVersionUID = 1; private String variety; public Raspberry(Season ripe, String variety) { ...} public void setVariety(String variety) {...} public String getVarity() {...} } ```

Abstract classes should not have public constructors. Constructors of abstract classes can only be called in constructors of their subclasses. So there is no point in making them public. The protected modifier should be enough.

```java Bad theme={"system"} public abstract class AbstractClass1 { public AbstractClass1 () { // Noncompliant, has public modifier // do something here } } ``` ```java Fix theme={"system"} public abstract class AbstractClass2 { protected AbstractClass2 () { // do something here } } ```

A conditional operator is sometimes cluttering readability, if one of the operand is a boolean literal it can be simplified in a boolean expression :

```java Bad theme={"system"} boolean a = condition || exp; boolean a = !condition && exp; boolean a = !condition || exp; boolean a = condition && exp; ``` ```java Fix theme={"system"} ```

Cloneable is the marker Interface that indicates that clone() may be called on an object. Overriding clone() without implementing Cloneable can be useful if you want to control how subclasses clone themselves, but otherwise, it’s probably a mistake.

```java Bad theme={"system"} class Team { // Noncompliant private Person coach; private List players; public void addPlayer(Person p) { ... } public Person getCoach() { ... } @Override public Team clone() { ... } } ``` ```java Fix theme={"system"} class Team implements Cloneable { private Person coach; private List players; public void addPlayer(Person p) { ... } public Person getCoach() { ... } @Override public Team clone() { ... } } ```

Different formatters use different formatting symbols, and it can be easy to confuse one for the other. But get it wrong, and your output may be useless.

This rule logs an issue when the wrong type of format string is used for Guava, slf4j, logback or MessageFormat strings.

```java Bad theme={"system"} String message = MessageFormat.format("Now is the %s %d all good people", "time", 4); // Noncompliant ``` ```java Fix theme={"system"} String message = MessageFormat.format("Now is the {1} {2} all good people", "time", 4); // Noncompliant ``` # Java - 2 Source: https://docs.codeant.ai/antipattern-rules/Java/java2 Learn about Java Anti-Patterns and How they help you write better code, and avoid common pitfalls.

Since Java 7, \`Strings can be used as switch arguments. So when a single String is tested against three or more values in an if/else if structure, it should be converted to a switch instead for greater readability.

Note that this rule is automatically disabled when the project’s sonar.java.source is lower than 7\`.

```java Bad theme={"system"} if ("red".equals(choice)) { // Noncompliant dispenseRed(); } else if ("blue".equals(choice)) { dispenseBlue(); } else if ("yellow".equals(choice)) { dispenseYellow(); } else { promptUser(); } ``` ```java Fix theme={"system"} switch(choice) { case "Red": dispenseRed(); break; case "Blue": dispenseBlue(): break; case "Yellow": dispenseYellow(); break; default: promptUser(); break; } ```

Comparisons of dissimilar types will always return false. The comparison and all its dependent code can simply be removed. This includes:

  • comparing an object with null

  • comparing an object with an unrelated primitive (E.G. a string with an int)

  • comparing unrelated classes

  • comparing an unrelated \`class and interface

  • comparing unrelated interface types

  • comparing an array to a non-array

  • comparing two arrays

Specifically in the case of arrays, since arrays don’t override Object.equals(), calling equals on two arrays is the same as comparing their addresses. This means that array1.equals(array2) is equivalent to array1==array2.

However, some developers might expect Array.equals(Object obj) to do more than a simple memory address comparison, comparing for instance the size and content of the two arrays. Instead, the == operator or Arrays.equals(array1, array2)\` should always be used with arrays.

```java Bad theme={"system"} interface KitchenTool { ... }; interface Plant {...} public class Spatula implements KitchenTool { ... } public class Tree implements Plant { ...} //... Spatula spatula = new Spatula(); KitchenTool tool = spatula; KitchenTool [] tools = {tool}; Tree tree = new Tree(); Plant plant = tree; Tree [] trees = {tree}; if (spatula.equals(tree)) { // Noncompliant; unrelated classes // ... } else if (spatula.equals(plant)) { // Noncompliant; unrelated class and interface // ... } else if (tool.equals(plant)) { // Noncompliant; unrelated interfaces // ... } else if (tool.equals(tools)) { // Noncompliant; array & non-array // ... } else if (trees.equals(tools)) { // Noncompliant; incompatible arrays // ... } else if (tree.equals(null)) { // Noncompliant // ... } ``` ```java Fix theme={"system"} ```

Using a type parameter when you don’t have to simply obfuscates the code. Qualifying an inner type with a type parameter will compile, but confuse maintainers.

```java Bad theme={"system"} T doTheThing(T.Entry type) { // Noncompliant //... } ``` ```java Fix theme={"system"} T doTheThing(Map.Entry type) { //... } ```

This rule allows you to track the use of the Checkstyle suppression comment mechanism.

```java Bad theme={"system"} // CHECKSTYLE:OFF ``` ```java Fix theme={"system"} ```

HttpSession s are managed by web servers and can be serialized and stored on disk as the server manages its memory use in a process called "passivation" (and later restored during "activation").

Even though HttpSession does not extend Serializable, you must nonetheless assume that it will be serialized. If non-serializable objects are stored in the session, serialization might fail.

```java Bad theme={"system"} public class Address { //... } HttpSession session = request.getSession(); session.setAttribute("address", new Address()); // Noncompliant; Address isn't serializable ``` ```java Fix theme={"system"} public class Address implements Serializable { //... } HttpSession session = request.getSession(); session.setAttribute("address", new Address()); ```

A cache is a long-lived object that holds references to shorter-lived objects. To prevent a cache from growing indefinitely, old objects the cache should be removed when they’re no longer used. This can be done with the use of soft references, which allow the garbage collector to remove unused cache entries when memory needs to be freed.

This rule raises an issue when a \`static collection does not use SoftReference.

Note that this rule is automatically disabled when the project’s sonar.java.source\` is lower than 7.

```java Bad theme={"system"} public class MyClass { private static List cache = new ArrayList<>(); // Noncompliant ``` ```java Fix theme={"system"} public class MyClass { private static List> cache = new ArrayList<>(); ```

The Object#equals(Object obj) method is used to compare two objects to see if they are equal.

The obj parameter’s type is Object, this means that an object of any type can be passed as a parameter to this method.

Any class overriding Object#equals(Object obj) should respect this contract, accept any object as an argument, and return false when the argument’s type differs from the expected type. The obj parameter’s type can be checked using instanceof or by comparing the getClass() value:

```java Bad theme={"system"} @Override public boolean equals(Object obj) { // ... if (this.getClass() != obj.getClass()) { return false; } // ... } ``` ```java Fix theme={"system"} public class MyClass { @Override public boolean equals(Object obj) { MyClass that = (MyClass) obj; // may throw a ClassCastException // ... } // ... } ```

The readObject method is implemented when a Serializable object requires special handling to be reconstructed from a file. The object created by readObject is accessed only by the thread that called the method, thus using the synchronized keyword in this context is unnecessary and causes confusion.

```java Bad theme={"system"} private synchronized void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException { // Noncompliant //... } ``` ```java Fix theme={"system"} private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException { // Compliant //... } ```

In Java 8, underscore (\_) cannot be used as a parameter to a lambda, and by Java 9, it’s a keyword. To ensure future portability (not to mention current readability), it should not be used now as an identifier.

```java Bad theme={"system"} private String _; // Noncompliant ``` ```java Fix theme={"system"} private String foo; ```

According to the Java \`Comparable.compareTo(T o) documentation:

It is strongly recommended, but not strictly required that \`++(x.compareTo(y)==0)

```java Bad theme={"system"} public class Foo implements Comparable { @Override public int compareTo(Foo foo) { /* ... */ } // Noncompliant as the equals(Object obj) method is not overridden } ``` ```java Fix theme={"system"} public class Foo implements Comparable { @Override public int compareTo(Foo foo) { /* ... */ } // Compliant @Override public boolean equals(Object obj) { /* ... */ } } ```

notify and notifyAll both wake up sleeping threads waiting on the object’s monitor, but notify only wakes up one single thread, while notifyAll wakes them all up. Unless you do not care which specific thread is woken up, notifyAll should be used instead.

```java Bad theme={"system"} class MyThread implements Runnable { Object lock = new Object(); @Override public void run() { synchronized(lock) { // ... lock.notify(); // Noncompliant } } } ``` ```java Fix theme={"system"} class MyThread implements Runnable { Object lock = new Object(); @Override public void run() { synchronized(lock) { // ... lock.notifyAll(); } } } ```

The \`java.util.function package provides a large array of functional interface definitions for use in lambda expressions and method references. In general it is recommended to use the more specialised form to avoid auto-boxing. For instance IntFunction\ should be preferred over Function\.

This rule raises an issue when any of the following substitution is possible:

Current Interface Preferred Interface

Function\

IntFunction\

Function\

LongFunction\

Function\

DoubleFunction\

Function\

DoubleToIntFunction

Function\

DoubleToLongFunction

Function\

LongToDoubleFunction

Function\

LongToIntFunction

Function\

ToIntFunction\

Function\

ToLongFunction\

Function\

ToDoubleFunction\

Function\

UnaryOperator\

BiFunction\

BinaryOperator\

Consumer\

IntConsumer

Consumer\

DoubleConsumer

Consumer\

LongConsumer

BiConsumer\

ObjIntConsumer\

BiConsumer\

ObjLongConsumer\

BiConsumer\

ObjDoubleConsumer\

Predicate\

IntPredicate

Predicate\

DoublePredicate

Predicate\

LongPredicate

Supplier\

IntSupplier

Supplier\

DoubleSupplier

Supplier\

LongSupplier

Supplier\

BooleanSupplier

UnaryOperator\

IntUnaryOperator

UnaryOperator\

DoubleUnaryOperator

UnaryOperator\

LongUnaryOperator

BinaryOperator\

IntBinaryOperator

BinaryOperator\

LongBinaryOperator

BinaryOperator\

DoubleBinaryOperator

Function\

Predicate\

BiFunction\

BiPredicate\\`

```java Bad theme={"system"} public class Foo implements Supplier { // Noncompliant @Override public Integer get() { // ... } } ``` ```java Fix theme={"system"} public class Foo implements IntSupplier { @Override public int getAsInt() { // ... } } ```

By accepting persistent entities as method arguments, the application allows clients to manipulate the object’s properties directly.

```java Bad theme={"system"} import javax.persistence.Entity; @Entity public class Wish { Long productId; Long quantity; Client client; } @Entity public class Client { String clientId; String name; String password; } import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @Controller public class PurchaseOrderController { @RequestMapping(path = "/saveForLater", method = RequestMethod.POST) public String saveForLater(Wish wish) { // Noncompliant session.save(wish); } } ``` ```java Fix theme={"system"} public class WishDTO { Long productId; Long quantity; Long clientId; } import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @Controller public class PurchaseOrderController { @RequestMapping(path = "/saveForLater", method = RequestMethod.POST) public String saveForLater(WishDTO wish) { Wish persistentWish = new Wish(); persistentWish.productId = wish.productId persistentWish.quantity = wish.quantity persistentWish.client = getClientById(with.clientId) session.save(persistentWish); } } ```

Validation is the first line of defense against injection, cross-site scripting, and many other attacks. Omitting it in modern web applications is simply negligent.

When creating a Struts ActionForm, you have the choice of extending something from the org.apache.struts.action package, or extending something from the org.apache.struts.validator package. Since you can’t use the Struts validator capabilities without extending something from the validator package, that should always be your choice.

```java Bad theme={"system"} public class MyForm extends org.apache.struts.action.ActionForm { // Noncompliant // ... ``` ```java Fix theme={"system"} public class MyForm extends org.apache.struts.validator.ValidatorForm { // ... ```

If you go to the trouble of importing a symbol statically, then you should make use of it, and you should do so consistently. Similarly, there’s no reason to both import a class and then refer to it in code by its fully-qualified name. Otherwise, maintainers could be confused by the difference between qualified and unqualified references.

```java Bad theme={"system"} import java.util.*; import java.math.BigInteger; import static java.lang.String.format; //... String s1 = format("%cello %cellow", 'h','f'); // Compliant String s2 = String.format("%cello %cellow", 'm','y'); // Noncompliant; is this a different format function than on the previous line? java.util.List list = new java.util.ArrayList(); // Noncompliant; both classes included in java.util.* import java.math.BigInteger myBigI = BigInteger.ZERO; // Noncompliant. This mixed usage is particularly confusing ``` ```java Fix theme={"system"} import java.util.*; import java.math.BigInteger; import static java.lang.String.format; //... String s1 = format("%cello %cellow", 'h','f'); String s2 = format("%cello %cellow", 'm','y'); List list = new ArrayList(); BigInteger myBigI = BigInteger.ZERO; ```

By contract, the NullCipher class provides an "identity cipher" - one that does not transform or encrypt the plaintext in any way. As a consequence, the ciphertext is identical to the plaintext. So this class should be used for testing, and never in production code.

```java Bad theme={"system"} NullCipher nc = new NullCipher(); ``` ```java Fix theme={"system"} ```

Both \`FixedSizeList from the Commons library, and the list returned from Arrays.asList offer add and remove methods (as required by the List interface they implement), but neither truly supports their use. Both list types have fixed lengths and will throw errors if an add or remove method, or any of their variations, is called.

This rule raises an issue when one of the following methods is invoked on a FixedSizeList instance:

  • add

  • addAll

  • clear

  • remove

  • removeAll\`

```java Bad theme={"system"} List strings = Arrays.asList("Hello"); strings.add("world"); // Noncompliant ``` ```java Fix theme={"system"} List strings = Arrays.asList("Hello", "world"); ```

When verifying that code raises a runtime exception, a good practice is to avoid having multiple method calls inside the tested code, to be explicit about which method call is expected to raise the exception.

It increases the clarity of the test, and avoid incorrect testing when another method is actually raising the exception.

```java Bad theme={"system"} @Test public void testToString() { // Do you expect get() or toString() throwing the exception? org.junit.Assert.assertThrows(IndexOutOfBoundsException.class, () -> get().toString()); } @Test public void testToStringTryCatchIdiom() { try { // Do you expect get() or toString() throwing the exception? get().toString(); Assert.fail("Expected an IndexOutOfBoundsException to be thrown"); } catch (IndexOutOfBoundsException e) { // Test exception message... } } ``` ```java Fix theme={"system"} @Test public void testToString() { Object obj = get(); Assert.assertThrows(IndexOutOfBoundsException.class, () -> obj.toString()); } @Test public void testToStringTryCatchIdiom() { Object obj = get(); try { obj.toString(); Assert.fail("Expected an IndexOutOfBoundsException to be thrown"); } catch (IndexOutOfBoundsException e) { // Test exception message... } } ```

Fields marked as transient in a Serializable class will be ignored during serialization and consequently not written out to a file (or stream).

This can be useful in situations such as where the content of a field can be recomputed from other fields. To reduce the output size, this field can be marked as transient and recomputed when a given object is deserialized.

Since transient is very specific to classes that implement Serializable, it is superfluous in classes that do not.

This rule raises an issue when a field is marked as transient, even though the containing class does not implement Serializable.

```java Bad theme={"system"} class Vegetable { private transient Season ripe; // Noncompliant, the "Vegetable" class does not implement "Serializable" but the field is marked as "transient" // ... } ``` ```java Fix theme={"system"} class Vegetable { private Season ripe; // Compliant, the field is not marked as "transient" // ... } ```

If you’ve gone to the trouble of writing an iterator method in a class that doesn’t implement Iterable, that trivial omission is costing you half the benefit of the method because you can’t use the class in enhanced for loops.

```java Bad theme={"system"} public class MyList { // Noncompliant public Iterator iterator() { //... } } public class MyClass { public void doSomething(MyList myList) { Iterator itr = myList.iterator(); while (itr.hasNext() { Object obj = itr.next(); processObj(obj); } } } ``` ```java Fix theme={"system"} public class MyList implements Iterable{ public Iterator iterator() { //... } } public class MyClass { public void doSomething(MyList myList) { for(Object obj : myList) { processObj(obj); } } } ```

A Spring \`singleton bean may be used by many threads at once, and the use of instance (non-static) variables could cause concurrency issues.

This rule applies to classes with the following annotations: @Service, @Component, @Repository, @Scope("singleton")\`

```java Bad theme={"system"} @Service("animalService") public class AnimalService { private int age = 1; // Noncompliant private static int count = 0; // Compliant; static @Inject private AnimalDAO animalDAO; // Compliant; managed by Spring ... } ``` ```java Fix theme={"system"} ```

Using boxed values in a ternary operator does not simply return one operand or the other based on the condition. Instead, the values are unboxed and coerced to a common type, which can result in a loss of precision when converting one operand from int to float or from long to double.

While this behavior is expected for arithmetic operations, it may be unexpected for the ternary operator. To avoid confusion or unexpected behavior, cast to a compatible type explicitly.

```java Bad theme={"system"} Integer i = 123456789; Float f = 1.0f; Number n1 = condition ? i : f; // Noncompliant, unexpected precision loss, n1 = 1.23456792E8 ``` ```java Fix theme={"system"} Integer i = 123456789; Float f = 1.0f; Number n1 = condition ? (Number) i : f; // Compliant, cast to Number prevents unboxing Number n2 = condition ? i : (Number) f; // Compliant, cast to Number prevents unboxing ```

Once a value is known to be null or non-null, there’s no reason to re-check it unless it has been changed (or potentially changed) in the interim. Doing so anyway may may just be an over-abundance of caution, but it could indicate a bug.

```java Bad theme={"system"} public void assignCoach(Team team, Person person) { if (team.hasCoach()) { // team is dereferenced return; } if (team != null) { // Noncompliant; if we got this far, team is not null //... } if (person != null) { // ... if (disqualified) { person = getAlternate(); } } if (person != null) { // Compliant; person may have changed since last check team.setCoach(person); } if (person != null) { // Noncompliant; no changes to person since last check // ... ``` ```java Fix theme={"system"} ```

There’s no valid reason to test this with instanceof. The only plausible explanation for such a test is that you’re executing code in a parent class conditionally based on the kind of child class this is. But code that’s specific to a child class should be in that child class, not in the parent.

```java Bad theme={"system"} public class JunkFood{ public void doSomething() { if (this instanceof Pizza) { // Noncompliant // ... } else if (... } } ``` ```java Fix theme={"system"} ```

The old, much-derided Date and Calendar classes have always been confusing and difficult to use properly, particularly in a multi-threaded context. JodaTime has long been a popular alternative, but now an even better option is built-in. Java 8’s JSR 310 implementation offers specific classes for:

Class Use for

LocalDate

a date, without time of day, offset, or zone

LocalTime

the time of day, without date, offset, or zone

LocalDateTime

the date and time, without offset, or zone

OffsetDate

a date with an offset such as +02:00, without time of day, or zone

OffsetTime

the time of day with an offset such as +02:00, without date, or zone

OffsetDateTime

the date and time with an offset such as +02:00, without a zone

ZonedDateTime

the date and time with a time zone and offset

YearMonth

a year and month

MonthDay

month and day

Year/MonthOfDay/DayOfWeek/…​

classes for the important fields

DateTimeFields

stores a map of field-value pairs which may be invalid

Calendrical

access to the low-level API

Period

a descriptive amount of time, such as "2 months and 3 days"

```java Bad theme={"system"} Date now = new Date(); // Noncompliant DateFormat df = new SimpleDateFormat("dd.MM.yyyy"); Calendar christmas = Calendar.getInstance(); // Noncompliant christmas.setTime(df.parse("25.12.2020")); ``` ```java Fix theme={"system"} LocalDate now = LocalDate.now(); // gets calendar date. no time component LocalTime now2 = LocalTime.now(); // gets current time. no date component LocalDate christmas = LocalDate.of(2020,12,25); ```

A for loop termination condition should test the loop counter against an invariant value that does not change during the execution of the loop. Invariant termination conditions make the program logic easier to understand and maintain.

This rule tracks three types of non-invariant termination conditions:

  • When the loop counters are updated in the body of the for loop

  • When the termination condition depends on a method call

  • When the termination condition depends on an object property since such properties could change during the execution of the loop.

```java Bad theme={"system"} for (int i = 0; i < foo(); i++) { // Noncompliant, "foo()" is not an invariant // ... } ``` ```java Fix theme={"system"} int end = foo(); for (int i = 0; i < end; i++) { // Compliant, "end" does not change during loop execution // ... } ```

Even if it is technically possible, Restricted Identifiers should not be used as identifiers. This is only possible for compatibility reasons, using it in Java code is confusing and should be avoided.

Note that this applies to any version of Java, including the one where these identifiers are not yet restricted, to avoid future confusion.

This rule reports an issue when restricted identifiers:

  • var

  • yield

  • record

are used as identifiers.

```java Bad theme={"system"} var var = "var"; // Noncompliant: compiles but this code is confusing var = "what is this?"; int yield(int i) { // Noncompliant return switch (i) { case 1: yield(0); // This is a yield from switch expression, not a recursive call. default: yield(i-1); }; } String record = "record"; // Noncompliant ``` ```java Fix theme={"system"} var myVariable = "var"; int minusOne(int i) { return switch (i) { case 1: yield(0); default: yield(i-1); }; } String myRecord = "record"; ```

Collection.removeIf is more readable and less verbose than using the Iterator.remove idiom. It might also be more performant in some cases, particularly for ArrayList instances.

```java Bad theme={"system"} for (Iterator it = items.iterator(); it.hasNext();) { if (this.predicate(it.next())) { it.remove(); } } ``` ```java Fix theme={"system"} items.removeIf(this::predicate); ```

If the Service Provider does not manage to properly validate the incoming SAML response message signatures, attackers might be able to manipulate the response content without the application noticing. Especially, they might be able to alter the authentication-targeted user.

```java Bad theme={"system"} import org.opensaml.xml.parse.StaticBasicParserPool; import org.opensaml.xml.parse.ParserPool; public ParserPool parserPool() { StaticBasicParserPool staticBasicParserPool = new StaticBasicParserPool(); staticBasicParserPool.setIgnoreComments(false); // Noncompliant return staticBasicParserPool; } ``` ```java Fix theme={"system"} import org.opensaml.xml.parse.BasicParserPool; import org.opensaml.xml.parse.ParserPool; public ParserPool parserPool() { BasicParserPool basicParserPool = new BasicParserPool(); basicParserPool.setIgnoreComments(false); // Noncompliant return basicParserPool; } ```

JDK7 introduced the class \`java.nio.charset.StandardCharsets. It provides constants for all charsets that are guaranteed to be available on every implementation of the Java platform.

  • ISO\_8859\_1

  • US\_ASCII

  • UTF\_16

  • UTF\_16BE

  • UTF\_16LE

  • UTF\_8

These constants should be preferred to:

  • the use of a String such as "UTF-8" which has the drawback of requiring the catch/throw of an UnsupportedEncodingException that will never actually happen

  • the use of Guava’s Charsets\` class, which has been obsolete since JDK7

```java Bad theme={"system"} try { byte[] bytes = string.getBytes("UTF-8"); // Noncompliant; use a String instead of StandardCharsets.UTF_8 } catch (UnsupportedEncodingException e) { throw new AssertionError(e); } // ... byte[] bytes = string.getBytes(Charsets.UTF_8); // Noncompliant; Guava way obsolete since JDK7 ``` ```java Fix theme={"system"} byte[] bytes = string.getBytes(StandardCharsets.UTF_8) ```

The processHttpRequest method and methods called from it can be executed by multiple threads within the same servlet instance, and state changes to the instance caused by these methods are, therefore, not threadsafe.

This is due to the servlet container creating only one instance of each servlet (javax.servlet.http.HttpServlet) and attaching a dedicated thread to each incoming HTTP request. The same problem exists for org.apache.struts.action.Action but with different methods.

To prevent unexpected behavior, avoiding mutable states in servlets is recommended. Mutable instance fields should either be refactored into local variables or made immutable by declaring them final.

```java Bad theme={"system"} public class MyServlet extends HttpServlet { String apiVersion = "0.9.1"; // Noncompliant, field changes are not thread-safe } ``` ```java Fix theme={"system"} public class MyServlet extends HttpServlet { final String apiVersion = "0.9.1"; // Compliant, field cannot be changed } ```

In Switch Expressions, an arrow label consisting of a block with a single \`yield can be simplified to directly return the value, resulting in cleaner code.

Similarly, for Switch Statements and arrow labels, a break in a block is always redundant and should not be used. Furthermore, if the resulting block contains only one statement, the curly braces of that block can also be omitted.

This rule reports an issue when a case of a Switch Expression contains a block with a single yield or when a Switch Statement contains a block with a break\`.

```java Bad theme={"system"} int i = switch (mode) { case "a" -> { // Noncompliant: Remove the redundant block and yield. yield 1; } default -> { // Noncompliant: Remove the redundant block and yield. yield 2; } }; switch (mode) { case "a" -> { // Noncompliant: Remove the redundant block and break. result = 1; break; } default -> { // Noncompliant: Remove the redundant break. doSomethingElse(); result = 2; break; } } ``` ```java Fix theme={"system"} int i = switch (mode) { case "a" -> 1; default -> 2; }; switch (mode) { case "a" -> result = 1; default -> { doSomethingElse(); result = 2; } } ```

In a multi-threaded situation, un-\`synchronized lazy initialization of static fields could mean that a second thread has access to a half-initialized object while the first thread is still creating it. Allowing such access could cause serious bugs. Instead. the initialization block should be synchronized.

Similarly, updates of such fields should also be synchronized.

This rule raises an issue whenever a lazy static initialization is done on a class with at least one synchronized\` method, indicating intended usage in multi-threaded applications.

```java Bad theme={"system"} private static Properties fPreferences = null; private static Properties getPreferences() { if (fPreferences == null) { fPreferences = new Properties(); // Noncompliant fPreferences.put("loading", "true"); fPreferences.put("filterstack", "true"); readPreferences(); } return fPreferences; } } ``` ```java Fix theme={"system"} private static Properties fPreferences = null; private static synchronized Properties getPreferences() { if (fPreferences == null) { fPreferences = new Properties(); fPreferences.put("loading", "true"); fPreferences.put("filterstack", "true"); readPreferences(); } return fPreferences; } } ```

There’s no need to null-test a variable before an instanceof test because instanceof tests for null. Similarly, there’s no need to null-test a variable before dereferencing some other object.

```java Bad theme={"system"} if (myVar != null && myVar instanceof MyClass) { // Noncompliant // ... } else if (myVar != null && myOtherVar.equals(myVar) { // Noncompliant // ... } ``` ```java Fix theme={"system"} if (myVar instanceof MyClass) { // ... } else if (myVar != null && myVar.equals(myOtherVar) { // ... } ```

Denoted by the "@" symbol, annotations are metadata that can be added to classes, methods, and variables for various purposes such as documentation, code analysis, and runtime processing.

Annotations have retention policies that determine in which context they are retained and available for use. There are three retention policies for annotations:

  • RetentionPolicy.SOURCE - Annotations are only available during compilation and code analysis. They are not included in the compiled class file and are not available at runtime. E.G. @Override, @SuppressWarnings

  • RetentionPolicy.CLASS - Annotations are included in the compiled class file providing information to the compiler, but they are not retained by the JVM at runtime. This is the default retention policy. E.G. @PreviewFeature

  • RetentionPolicy.RUNTIME - Annotations are included in the compiled class file and available at runtime. They can be accessed and used by the program through reflection. E.G. @FunctionalInterface, @Deprecated

It is important to understand that only annotations having the RUNTIME retention policy can be accessed at runtime using reflection. For example, the following if condition is true when the method argument is the java.util.function.Function class:

```java Bad theme={"system"} void execute(Class cls) { if (cls.isAnnotationPresent(FunctionalInterface.class)) { // ... } } ``` ```java Fix theme={"system"} void execute(Method method) { if (method.isAnnotationPresent(Override.class)) { // Noncompliant, if condition will always be false because // @Override is declared with @Retention(RetentionPolicy.SOURCE) // ... } } ```

Before Java 8, a container annotation was required as wrapper to use multiple instances of the same annotation. As of Java 8, this is no longer necessary. Instead, these annotations should be used directly without a wrapper, resulting in cleaner and more readable code.

This rule is automatically disabled when the project’s sonar.java.source is lower than 8 as repeating annotations were introduced in Java 8.

```java Bad theme={"system"} @SomeAnnotations({ // Noncompliant, wrapper annotations are not necessary in Java 8+ @SomeAnnotation(..a..), @SomeAnnotation(..b..), @SomeAnnotation(..c..), }) public class SomeClass { ... } ``` ```java Fix theme={"system"} @SomeAnnotation(..a..) @SomeAnnotation(..b..) @SomeAnnotation(..c..) public class SomeClass { ... } ```

Java 21 virtual threads allow the JVM to optimize the usage of OS threads, by mounting and unmounting them on an OS thread when needed, and making them more efficient when dealing with blocking operations such as HTTP requests or I/O.

However, when code is executed inside a synchronized block or synchronized method, the virtual thread stays pinned to the underlying OS thread and cannot be unmounted during a blocking operation. This will cause the OS thread to be blocked, which can impact the scalability of the application.

Therefore, virtual threads should not execute code that contains synchronized blocks or invokes synchronized methods. Platform threads should be used in these cases.

This rule raises an issue when a virtual thread contains synchronized blocks or invokes synchronized methods.

```java Bad theme={"system"} void enqueue(){ Thread.startVirtualThread(() -> { // Noncompliant; use a platform thread instead setupOperations(); dequeLogic(); } }); } ``` ```java Fix theme={"system"} void enqueue(){ new Thread(() -> { synchronized { setupOperations(); dequeLogic(); } }).start(); } ```

According to the Java documentation, any implementation of the \`InputSteam.read() method is supposed to read the next byte of data from the input stream. The value byte must be an int in the range 0 to 255. If no byte is available because the end of the stream has been reached, the value -1 is returned.

But in Java, the byte primitive data type is an 8-bit signed two’s complement integer. It has a minimum value of -128 and a maximum value of 127. So by contract, the implementation of an InputSteam.read() method should never directly return a byte\` primitive data type. A conversion into an unsigned byte must be done before by applying a bitmask.

```java Bad theme={"system"} @Override public int read() throws IOException { if (pos == buffer.length()) { return -1; } return buffer.getByte(pos++); // Noncompliant, a signed byte value is returned } ``` ```java Fix theme={"system"} @Override public int read() throws IOException { if (pos == buffer.length()) { return -1; } return buffer.getByte(pos++) & 0xFF; // The 0xFF bitmask is applied } ```

Setting the wrong Content-Type for a response can leave an application vulnerable to cross-site scripting attacks. Specifically, JSON should always be served with the \`application/json Content-Type.

This rule checks the Content-Type of responses containing classes in the org.json and javax.json\` packages.

```java Bad theme={"system"} public void doGet(HttpServletRequest request, HttpServletResponse response) { JSONObject jsonRespone = getJsonResponse(request); try { response.setContentType("text/html"); // Noncompliant; wrong type PrintWriter out = response.getWriter(); out.println(jsonResponse.toJSONString()); out.close(); } catch (IOException e) { e.printStackTrace(); } } public void doPost(HttpServletRequest request, HttpServletResponse response) { // Noncompliant; response type not set JSONObject jsonRespone = getJsonResponse(request); try { PrintWriter out = response.getWriter(); out.println(jsonResponse.toJSONString()); out.close(); } catch (IOException e) { e.printStackTrace(); } } ``` ```java Fix theme={"system"} ```

Hibernate’s lazy loading allows you to retrieve just the data of the current class without being forced to load all its related classes. For instance with lazy loading, you can pull up an instance of a \`Lecture @Entity without being forced to load all its Students.

But that’s only if you’re storing the Students in a collection. Store them in an array instead, and the benefits of lazy loading are no longer available.

This rule raises an issue on each array in @Entity\` classes.

```java Bad theme={"system"} @Entity public class Lecture { @OneToMany private Student [] attendees; // Noncompliant // ... } ``` ```java Fix theme={"system"} @Entity public class Lecture { @OneToMany private List attendees; // ... } ```

Configured URL matchers are considered in the order they are declared. Especially, for a given resource, if a looser filter is defined before a stricter one, only the less secure configuration will apply. No request will ever reach the stricter rule.

This rule raises an issue when:

  • A URL pattern ending with \*\* precedes another one having the same prefix. E.g. /admin/\*\* is defined before /admin/example/\*\*

  • A pattern without wildcard characters is preceded by another one that matches it. E.g.: /page-index/db is defined after /page\*/\*\*

```java Bad theme={"system"} protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/resources/**", "/signup", "/about").permitAll() .antMatchers("/admin/**").hasRole("ADMIN") .antMatchers("/admin/login").permitAll() // Noncompliant .antMatchers("/**", "/home").permitAll() .antMatchers("/db/**").access("hasRole('ADMIN') and hasRole('DBA')") // Noncompliant .and().formLogin().loginPage("/login").permitAll().and().logout().permitAll(); } ``` ```java Fix theme={"system"} protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/resources/**", "/signup", "/about").permitAll() .antMatchers("/admin/login").permitAll() .antMatchers("/admin/**").hasRole("ADMIN") .antMatchers("/db/**").access("hasRole('ADMIN') and hasRole('DBA')") .antMatchers("/**", "/home").permitAll() .and().formLogin().loginPage("/login").permitAll().and().logout().permitAll(); } ```

\`ThreadLocal variables are supposed to be garbage collected once the holding thread is no longer alive. Memory leaks can occur when holding threads are re-used which is the case on application servers using pool of threads.

To avoid such problems, it is recommended to always clean up ThreadLocal variables using the remove() method to remove the current thread’s value for the ThreadLocal variable.

In addition, calling set(null) to remove the value might keep the reference to this pointer in the map, which can cause memory leak in some scenarios. Using remove\` is safer to avoid this issue.

```java Bad theme={"system"} public class ThreadLocalUserSession implements UserSession { private static final ThreadLocal DELEGATE = new ThreadLocal<>(); public UserSession get() { UserSession session = DELEGATE.get(); if (session != null) { return session; } throw new UnauthorizedException("User is not authenticated"); } public void set(UserSession session) { DELEGATE.set(session); } public void incorrectCleanup() { DELEGATE.set(null); // Noncompliant } // some other methods without a call to DELEGATE.remove() } ``` ```java Fix theme={"system"} public class ThreadLocalUserSession implements UserSession { private static final ThreadLocal DELEGATE = new ThreadLocal<>(); public UserSession get() { UserSession session = DELEGATE.get(); if (session != null) { return session; } throw new UnauthorizedException("User is not authenticated"); } public void set(UserSession session) { DELEGATE.set(session); } public void unload() { DELEGATE.remove(); // Compliant } // ... } ```

Shared naming conventions allow teams to collaborate efficiently.

This rule raises an issue when a method name does not match a provided regular expression.

For example, with the default provided regular expression ^\[a-z]\[a-zA-Z0-9]\*\$, the method:

```java Bad theme={"system"} public int DoSomething(){...} // Noncompliant ``` ```java Fix theme={"system"} public int doSomething(){...} ```

The Reader.read() and the BufferedReader.readLine() are used for reading data from a data source. The return value of these methods is the data read from the data source, or null when the end of the data source is reached. If the return value is ignored, the data read from the source is thrown away and may indicate a bug.

This rule raises an issue when the return values of Reader.read() and BufferedReader.readLine() and their subclasses are ignored or merely null-checked.

```java Bad theme={"system"} public void doSomethingWithFile(String fileName) { try(BufferedReader buffReader = new BufferedReader(new FileReader(fileName))) { while (buffReader.readLine() != null) { // Noncompliant // ... } } catch (IOException e) { // ... } } ``` ```java Fix theme={"system"} public void doSomethingWithFile(String fileName) { try(BufferedReader buffReader = new BufferedReader(new FileReader(fileName))) { String line = null; while ((line = buffReader.readLine()) != null) { // ... } } catch (IOException e) { // ... } } ```

Unlike similar AssertJ methods testing exceptions (\`assertThatCode(), assertThatExceptionOfType(), …​), the assertThatThrownBy() method can be used alone, failing if the code did not raise any exception.

Still, only testing that an exception was raised is not enough to guarantee that it was the expected one, and you should test the exception type or content further. In addition, it will make explicit what you are expecting, without relying on side-effects.

This rule raises an issue when assertThatThrownBy\` is used, without testing the exception further.

```java Bad theme={"system"} assertThatThrownBy(() -> shouldThrow()); // Noncompliant, is it really the exception you expected? ``` ```java Fix theme={"system"} assertThatThrownBy(() -> shouldThrow()).isInstanceOf(IOException.class); //or assertThatThrownBy(() -> shouldThrow()).hasMessage("My exception"); ```

JUnit assertions should not be made from the run method of a Runnable, because their failure may not be detected in the test that initiated them. Failed assertions throw assertion errors. However, if the error is thrown from another thread than the one that initiated the test, the thread will exit but the test will not fail.

```java Bad theme={"system"} class RunnableWithAnAssertion extends Thread { @Override public void run() { Assert.assertEquals(expected, actual); // Noncompliant } @Test void test() { RunnableWithAnAssertion otherThread = new RunnableWithAnAssertion(); otherThread.start(); // The assertion in the run method above will be executed by other thread than the current one // ... // Perform some actions that do not make the test fail // ... Assert.assertTrue(true); } } ``` ```java Fix theme={"system"} class RunnableWithAnAssertion extends Thread { @Override public void run() { Assert.assertEquals(expected, actual); // Noncompliant } @Test void test() { RunnableWithAnAssertion otherThread = new RunnableWithAnAssertion(); otherThread.run(); // ... // The failed assertions in the run method will prevent us from reaching the assertion below // ... Assert.assertTrue(true); } } ```

Having too many return statements in a method increases the method’s essential complexity because the flow of execution is broken each time a return statement is encountered. This makes it harder to read and understand the logic of the method.

```java Bad theme={"system"} public boolean myMethod() { // Noncompliant; there are 4 return statements if (condition1) { return true; } else { if (condition2) { return false; } else { return true; } } return false; } ``` ```java Fix theme={"system"} ```

Java 7’s try-with-resources structure automatically handles closing the resources that the try itself opens. Thus, adding an explicit close() call is redundant and potentially confusing.

```java Bad theme={"system"} try (PrintWriter writer = new PrintWriter(process.getOutputStream())) { String contents = file.contents(); writer.write(new Gson().toJson(new MyObject(contents))); writer.flush(); writer.close(); // Noncompliant } ``` ```java Fix theme={"system"} try (PrintWriter writer = new PrintWriter(process.getOutputStream())) { String contents = file.contents(); writer.write(new Gson().toJson(new MyObject(contents))); writer.flush(); } ```

In records, introduced in Java 16, there are 2 ways to write a custom constructor: canonical and compact.

A canonical constructor is an ordinary constructor with arguments for all private fields. The default implementation just provides initialization for all private fields and there is no need to write it manually. You might want to write it yourself when you need to customize the constructor logic.

A compact constructor doesn’t have parameters defined explicitly, parentheses are omitted and access to private fields is not possible (even via this). The compact constructor has access to the constructor’s arguments and its body is executed right before the field initialization. It’s a perfect place to provide validation.

This rule reports an issue when a canonical constructor can be easily replaced by a compact version when these requirements are met:

  • the last statements are trivial field initializations

  • no statement reads from fields or components

  • there are other statements in the constructor (case covered by S6207: redundant constructors in records)

```java Bad theme={"system"} record Person(String name, int age) {   Person(String name, int age) { // Noncompliant if (age < 0) { throw new IllegalArgumentException("Negative age"); }     this.name = name;     this.age = age;   } } ``` ```java Fix theme={"system"} record Person(String name, int age) {   Person { // Compliant if (age < 0) { throw new IllegalArgumentException("Negative age"); }   } } ```

The repetition of a unary operator is usually a typo. The second operator invalidates the first one in most cases:

```java Bad theme={"system"} int i = 1; int j = - - -i; // Noncompliant: equivalent to "-i" int k = ~~~i; // Noncompliant: equivalent to "~i" int m = + +i; // Noncompliant: equivalent to "i" boolean b = false; boolean c = !!!b; // Noncompliant ``` ```java Fix theme={"system"} int i = 1; int j = ++ ++i; // Noncompliant int k = i-- --; // Noncompliant ```

Non final classes shouldn’t use a hardcoded class name in the equals method. Doing so breaks the method for subclasses. Instead, make the comparison dynamic.

```java Bad theme={"system"} public class Fruit { private Season ripe; public boolean equals(Object obj) { if (obj == this) { return true; } if (Fruit.class == obj.class) { // Noncompliant return false; } // ... ``` ```java Fix theme={"system"} public class Fruit { private Season ripe; public boolean equals(Object obj) { if (obj == this) { return true; } if (this.class == obj.class) { // will work for subclasses too return false; } // ... ```

In Records, serialization is not done the same way as for ordinary serializable or externalizable classes. The serialized representation of a record object will be a sequence of values (record components). During the deserialization of records, the stream of components is read and components are constructed. Then the record object is recreated by invoking the record’s canonical constructor with the component values serving as arguments (or default values for absent arguments).

This process cannot be customized, so any class-specific \`writeObject, readObject, readObjectNoData, writeExternal, and readExternal methods or serialPersistentFields fields in record classes are ignored during serialization and deserialization.

However, there is a way to substitute serialized/deserialized objects in writeReplace and readResolve.

This rule raises an issue when any of writeObject, readObject, readObjectNoData, writeExternal, readExternal or serialPersistentFields\` are present as members in a Record class.

```java Bad theme={"system"} record Record() implements Serializable { @Serial private static final ObjectStreamField[] serialPersistentFields = new ObjectStreamField[0]; // Noncompliant @Serial private void writeObject(ObjectOutputStream out) throws IOException { // Noncompliant ... } } record Record() implements Externalizable { @Override public void writeExternal(ObjectOutput out) throws IOException { // Noncompliant ... } @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { // Noncompliant ... } } ``` ```java Fix theme={"system"} record Record() implements Serializable {} record Record() implements Serializable { private Object writeReplace() throws ObjectStreamException { ... } private Object readResolve() throws ObjectStreamException { ... } } ```

Java 21 introduces case null for switch. It is a more concise and readable way to handle nullability compared to an if statement before a switch.

```java Bad theme={"system"} switch (s) { case null: /* code if null */ // ... } ``` ```java Fix theme={"system"} if (s == null) { /* code if null */ } switch (s) { // ... } ```

When the application does not implement controls over the JMS object types, its clients could be able to force the deserialization of arbitrary objects. This may lead to deserialization injection attacks.

```java Bad theme={"system"} ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("tcp://localhost:61616"); factory.setTrustAllPackages(true); // Noncompliant ``` ```java Fix theme={"system"} ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("tcp://localhost:61616"); factory.setTrustedPackages(Arrays.asList("org.mypackage1", "org.mypackage2")); ```

StringBuffer and StringBuilder instances that are appended but never toStringed needlessly clutter the code, and worse are a drag on performance. Either they should be removed, or the missing toString call added.

```java Bad theme={"system"} public void doSomething(List strings) { StringBuilder sb = new StringBuilder(); // Noncompliant sb.append("Got: "); for (String str : strings) { sb.append(str).append(", "); // ... } } ``` ```java Fix theme={"system"} public void doSomething(List strings) { for (String str : strings) { // ... } } ```

When using the \`Stream API, call chains should be simplified as much as possible. Not only does it make the code easier to read, it also avoid creating unnecessary temporary objects.

This rule raises an issue when one of the following substitution is possible:

Original Preferred

stream.filter(predicate).findFirst().isPresent()

stream.anyMatch(predicate)

stream.filter(predicate).findAny().isPresent()

stream.anyMatch(predicate)

!stream.anyMatch(predicate)

stream.noneMatch(predicate)

!stream.anyMatch(x -> !(...))

stream.allMatch(...)

stream.map(mapper).anyMatch(Boolean::booleanValue)

stream.anyMatch(predicate)\`

```java Bad theme={"system"} boolean hasRed = widgets.stream().filter(w -> w.getColor() == RED).findFirst().isPresent(); // Noncompliant ``` ```java Fix theme={"system"} boolean hasRed = widgets.stream().anyMatch(w -> w.getColor() == RED); ```

java.lang.Error and its subclasses represent abnormal conditions, such as OutOfMemoryError, which should only be encountered by the Java Virtual Machine.

```java Bad theme={"system"} public class MyException extends Error { /* ... */ } // Noncompliant ``` ```java Fix theme={"system"} public class MyException extends Exception { /* ... */ } // Compliant ```

A common reason for a poorly performant query is because it’s processing more data than required.

Querying unnecessary data demands extra work on the server, adds network overhead, and consumes memory and CPU resources on the application server. The effect is amplified when the query includes multiple joins.

The rule flags an issue when a SELECT \* query is provided as an argument to methods in java.sql.Connection and java.sql.Statement.

```java Bad theme={"system"} public class OrderRepository { public record OrderSummary(String name, String orderId, BigDecimal price) { } public List queryOrderSummaries(Connection conn) { String sql = "SELECT * " + // Noncompliant "FROM Orders JOIN Customers ON Orders.customerId = Customers.id "; Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery(sql); return convertResultToOrderSummaryList(rs); } } ``` ```java Fix theme={"system"} public class OrderRepository { public record OrderSummary(String name, String orderId, BigDecimal price) { } public List queryOrderSummaries(Connection conn) { String sql = "SELECT Customers.name, Orders.id, Orders.price " + // Compliant "FROM Orders JOIN Customers ON Orders.customerId = Customers.id "; Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery(sql); return convertResultToOrderSummaryList(rs); } } ```

Objects annotated with Mockito annotations \`@Mock, @Spy, @Captor, or @InjectMocks need to be initialized explicitly.

There are several ways to do this:

  • Call MockitoAnnotations.openMocks(this) or MockitoAnnotations.initMocks(this) in a setup method

  • Annotate test class with @RunWith(MockitoJUnitRunner.class) (JUnit 4)

  • Annotate test class with @ExtendWith(MockitoExtension.class) (JUnit 5 Jupiter)

  • Use @Rule public MockitoRule rule = MockitoJUnit.rule();

Test using uninitialized mocks will fail.

Note that this only applies to annotated Mockito objects. It is not necessary to initialize objects instantiated via Mockito.mock() or Mockito.spy()\`.

This rule raises an issue when a test class uses uninitialized mocks.

```java Bad theme={"system"} public class FooTest { // Noncompliant: Mockito initialization missing @Mock private Bar bar; @Spy private Baz baz; @InjectMocks private Foo fooUnderTest; @Test void someTest() { // test something ... } @Nested public class Nested { @Mock private Bar bar; } ``` ```java Fix theme={"system"} @RunWith(MockitoJUnitRunner.class) public class FooTest { @Mock private Bar bar; // ... } ```

Some mathematical operations are unnecessary and should not be performed because their results are predictable.

For instance, anyValue % 1 will always return 0, as any integer value can be divided by 1 without remainder.

Similarly, casting a non-floating-point to a floating-point value and then passing it to Math.round, Math.ceil, or Math.floor is also unnecessary, as the result will always be the original value.

The following operations are unnecessary when given any constant value: Math.abs, Math.ceil, Math.floor, Math.rint, Math.round. Instead, use the result of the operation directly.

The following operations are unnecessary with certain constants and can be replaced by the result of the operation directly:

Operation Value

acos

0.0 or 1.0

asin

0.0 or 1.0

atan

0.0 or 1.0

atan2

0.0

cbrt

0.0 or 1.0

cos

0.0

cosh

0.0

exp

0.0 or 1.0

expm1

0.0

log

0.0 or 1.0

log10

0.0 or 1.0

sin

0.0

sinh

0.0

sqrt

0.0 or 1.0

tan

0.0

tanh

0.0

toDegrees

0.0 or 1.0

toRadians

0.0

```java Bad theme={"system"} public void doMath(int a) { double res1 = Math.floor((double)a); // Noncompliant, the result will always be equal to '(double) a' double res2 = Math.ceil(4.2); // Noncompliant, the result will always be 5.0 double res3 = Math.atan(0.0); // Noncompliant, the result will always be 0.0 } ``` ```java Fix theme={"system"} public void doMath(int a) { double res1 = a; // Compliant double res2 = 5.0; // Compliant double res3 = 0.0; // Compliant } ```

The Spring framework’s @RestController annotation is equivalent to using the @Controller and @ResponseBody annotations together. As such, it is redundant to add a @ResponseBody annotation when the class is already annotated with @RestController.

```java Bad theme={"system"} @RestController public class MyController { @ResponseBody // Noncompliant, the @RestController annotation already implies @ResponseBody @RequestMapping("/hello") public String hello() { return "Hello World!"; } } ``` ```java Fix theme={"system"} @RestController public class MyController { @RequestMapping("/hello") public String hello() { return "Hello World!"; } } ```

Passing single null or primitive array argument to the variable arity method may not work as expected. In the case of null, it is not passed as array with single element, but the argument itself is null. In the case of a primitive array, if the formal parameter is Object..., it is passed as a single element array. This may not be obvious to someone not familiar with such corner cases, and it is probably better to avoid such ambiguities by explicitly casting the argument to the desired type.

```java Bad theme={"system"} class A { public static void main(String[] args) { vararg(null); // Noncompliant, prints "null" int[] arr = {1,2,3}; vararg(arr); // Noncompliant, prints "length: 1" } static void vararg(Object... s) { if (s == null) { System.out.println("null"); } else { System.out.println("length: " + s.length); } } } ``` ```java Fix theme={"system"} class A { public static void main(String[] args) { vararg((Object) null); // prints 1 Object[] arr = {1,2,3}; vararg(arr); // prints 3 } static void vararg(Object... s) { if (s == null) { System.out.println("null"); // not reached } else { System.out.println("length: " + s.length); } } } ```

@VisibleForTesting can be used to mark methods, fields and classes whose visibility restrictions have been relaxed more than necessary for the API to allow for easier unit testing.

Access to such methods, fields and classes only possible thanks to this relaxed visibility is fine for test code, but it should be avoided in production code. In production code these methods should be treated as if they are private.

Supported framework:

  • Guava: \`com.google.common.annotations.VisibleForTesting

  • AssertJ: org.assertj.core.util.VisibleForTesting

  • Android: androidx.annotation.VisibleForTesting

  • Apache Flink: org.apache.flink.annotation.VisibleForTesting

or any other annotation named VisibleForTesting\`

```java Bad theme={"system"} /** src/main/java/MyObject.java */ @VisibleForTesting String foo; /** src/main/java/Service.java */ new MyObject().foo; // Noncompliant, foo is accessed from production code ``` ```java Fix theme={"system"} /** src/main/java/MyObject.java */ @VisibleForTesting String foo; /** src/test/java/MyObjectTest.java */ new MyObject().foo; // Compliant, foo is accessed from test code ```

Java 15 introduced feature of \`sealed classes. With sealed classes and interfaces you can specify a strict hierarchy of types and restrict possible inheritance.

Although this feature can help to make code safer, it is not applicable everywhere. Functional interfaces can not be sealed. This means that if an interface with a single abstract method is declared with a sealed keyword, its implementation can’t be replaced with a lambda.

This rule reports an issue when an interface with a single abstract method is marked sealed\`.

```java Bad theme={"system"} public sealed interface F permits ... { // Noncompliant void f(); } ``` ```java Fix theme={"system"} public interface F { // Compliant void f(); } ```

When List.remove() is called, the list shrinks, and the indices of all elements following the removed element are decremented by one. If this operation is performed within a loop that iterates through the elements in ascending order, it will cause the loop to skip the element immediately following the removed element.

```java Bad theme={"system"} void removeFrom(List list) { // expected: iterate over all list elements for (int i = 0; i < list.size(); i++) { if (list.get(i).isEmpty()) { list.remove(i); // Noncompliant, next element is skipped } } } ``` ```java Fix theme={"system"} void removeFrom(List list) { list.removeIf(String::isEmpty); // Compliant } ```

According to the EJB specification, EJB’s:

…​must not attempt to create a class loader; obtain the current class loader; set the context class loader…​

This rule raises an issue each time an EJB obtains a class loader.

```java Bad theme={"system"} ClassLoader loader = this.getClass().getClassLoader(); // Noncompliant ClassLoader loader = new MyClassLoader(); // Noncompliant ``` ```java Fix theme={"system"} ```

Overriding a parent class' method implementation with an \`abstract method is a terrible practice for a number of reasons:

  • it blocks invocation of the original class' method by children of the abstract class.

  • it requires the abstract\` class' children to re-implement (copy/paste?) the original class' logic.

  • it violates the inherited contract.

```java Bad theme={"system"} public class Parent { public int getNumber() { return 1; } } public abstract class AbstractChild { abstract public int getNumber(); // Noncompliant } ``` ```java Fix theme={"system"} ```

In Java, the Thread class represents a thread of execution. Synchronization between threads is typically achieved using objects or shared resources.

The methods wait(…​), notify(), and notifyAll() are related to the underlying object’s monitor and are designed to be called on objects that act as locks or monitors for synchronization. These methods are available on Java Object and, therefore, automatically inherited by all objects, including Thread.

Calling these methods on a Thread may corrupt the behavior of the JVM, which relies on them to change the state of the thread (BLOCKED, WAITING,…​).

```java Bad theme={"system"} Thread myThread = new Thread(new RunnableJob()); ... myThread.wait(); // Noncompliant ``` ```java Fix theme={"system"} ```

An equals method that unconditionally returns the same answer is an error likely to cause many bugs.

```java Bad theme={"system"} public class Fruit extends Food { private Season ripe; public boolean equals(Object obj) { return ripe.equals(this); // Noncompliant } ``` ```java Fix theme={"system"} ```

When using null-related annotations at global scope level, for instance using \`javax.annotation.ParametersAreNonnullByDefault (from JSR-305) at package level, it means that all the parameters to all the methods included in the package will, or should, be considered Non-null. It is equivalent to annotating every parameter in every method with non-null annotations (such as @Nonnull).

The rule raises an issue every time a parameter could be null\` for a method invocation, where the method is annotated as forbidding null parameters.

```java Bad theme={"system"} @javax.annotation.ParametersAreNonnullByDefault class A { void foo() { bar(getValue()); // Noncompliant - method 'bar' do not expect 'null' values as parameter } void bar(Object o) { // 'o' is by contract expected never to be null // ... } @javax.annotation.CheckForNull abstract Object getValue(); } ``` ```java Fix theme={"system"} @javax.annotation.ParametersAreNonnullByDefault abstract class A { void foo() { Object o = getValue(); if (o != null) { bar(o); // Compliant - 'o' can not be null } } void bar(Object o) { // ... } @javax.annotation.CheckForNull abstract Object getValue(); } ```

Calling an overridable method from a constructor could result in failures or strange behaviors when instantiating a subclass which overrides the method.

For example:

  • The subclass class constructor starts by contract by calling the parent class constructor.

  • The parent class constructor calls the method, which has been overridden in the child class.

  • If the behavior of the child class method depends on fields that are initialized in the child class constructor, unexpected behavior (like a NullPointerException) can result, because the fields aren’t initialized yet.

```java Bad theme={"system"} public class Parent { public Parent () { doSomething(); // Noncompliant } public void doSomething () { // not final; can be overridden ... } } public class Child extends Parent { private String foo; public Child(String foo) { super(); // leads to call doSomething() in Parent constructor which triggers a NullPointerException as foo has not yet been initialized this.foo = foo; } public void doSomething () { System.out.println(this.foo.length()); } } ``` ```java Fix theme={"system"} ```

\`Optional value can hold either a value or not. The value held in the Optional can be accessed using the get() method, but it will throw a

NoSuchElementException if there is no value present. To avoid the exception, calling the isPresent() or ! isEmpty() method should always be done before any call to get().

Alternatively, note that other methods such as orElse(...), orElseGet(...) or orElseThrow(...) can be used to specify what to do with an empty Optional\`.

```java Bad theme={"system"} Optional value = this.getOptionalValue(); // ... String stringValue = value.get(); // Noncompliant ``` ```java Fix theme={"system"} if (methodThatReturnsOptional().isEmpty()) { throw new NotFoundException(); } String value = methodThatReturnsOptional().get(); // Noncompliant: indirect access, we consider that two consecutive calls can return different values. ```

Throwing generic exceptions such as \`Error, RuntimeException, Throwable, and Exception will have a negative impact on any code trying to catch these exceptions.

From a consumer perspective, it is generally a best practice to only catch exceptions you intend to handle. Other exceptions should ideally be let to propagate up the stack trace so that they can be dealt with appropriately. When a generic exception is thrown, it forces consumers to catch exceptions they do not intend to handle, which they then have to re-throw.

Besides, when working with a generic type of exception, the only way to distinguish between multiple exceptions is to check their message, which is error-prone and difficult to maintain. Legitimate exceptions may be unintentionally silenced and errors may be hidden.

For instance, when a Throwable is caught and not re-thrown, it may mask errors such as OutOfMemoryError\` and prevent the program from terminating gracefully.

When throwing an exception, it is therefore recommended to throw the most specific exception possible so that it can be handled intentionally by consumers.

```java Bad theme={"system"} @Override public void myMethod() throws Exception {...} ``` ```java Fix theme={"system"} public void myOtherMethod() throws Exception { doTheThing(); // this method throws Exception } ```

Well-named functions can allow the users of your code to understand at a glance what to expect from the function - even before reading the documentation. Toward that end, methods returning a boolean should have names that start with "is" or "has" rather than with "get".

```java Bad theme={"system"} public boolean getFoo() { // Noncompliant // ... } public boolean getBar(Bar c) { // Noncompliant // ... } public boolean testForBar(Bar c) { // Compliant - The method does not start by 'get'. // ... } ``` ```java Fix theme={"system"} public boolean isFoo() { // ... } public boolean hasBar(Bar c) { // ... } public boolean testForBar(Bar c) { // ... } ```

The ability to map a class to a database table has made database interaction in Java a lot easier. But map multiple classes to the same table and you’ll end up with a classic case of the left hand not knowing what the right hand is doing. In the worse case scenario, it could lead to serious data corruption.

This rule raises an issue when multiple classes are mapped to the same table with Hibernate or JPA annotations.

```java Bad theme={"system"} @Entity // implicitly mapped to "point" table public class Point { // .. } @Entity @Table(name = "point") // Noncompliant public class Spot { // ... } ``` ```java Fix theme={"system"} ```

When using POSIX classes like \`\p\{Alpha} without the UNICODE\_CHARACTER\_CLASS flag or when using hard-coded character classes like "\[a-zA-Z]", letters outside of the ASCII range, such as umlauts, accented letters or letter from non-Latin languages, won’t be matched. This may cause code to incorrectly handle input containing such letters.

To correctly handle non-ASCII input, it is recommended to use Unicode classes like \p\{IsAlphabetic}. When using POSIX classes, Unicode support should be enabled by either passing Pattern.UNICODE\_CHARACTER\_CLASS as a flag to Pattern.compile or by using (?U)\` inside the regex.

```java Bad theme={"system"} Pattern.compile("[a-zA-Z]"); Pattern.compile("\\p{Alpha}"); ``` ```java Fix theme={"system"} Pattern.compile("\\p{IsAlphabetic}"); // matches all letters from all languages Pattern.compile("\\p{IsLatin}"); // matches latin letters, including umlauts and other non-ASCII variations Pattern.compile("\\p{Alpha}", Pattern.UNICODE_CHARACTER_CLASS); Pattern.compile("(?U)\\p{Alpha}"); ```

Testing equality or nullness with JUnit’s assertTrue() or assertFalse() should be simplified to the corresponding dedicated assertion.

```java Bad theme={"system"} Assert.assertTrue(a.equals(b)); Assert.assertTrue(a == b); Assert.assertTrue(a == null); Assert.assertTrue(a != null); Assert.assertFalse(a.equals(b)); ``` ```java Fix theme={"system"} Assert.assertEquals(a, b); Assert.assertSame(a, b); Assert.assertNull(a); Assert.assertNotNull(a); Assert.assertNotEquals(a, b); ```

Using \`File.createTempFile as the first step in creating a temporary directory causes a race condition and is inherently unreliable and insecure. Instead, Files.createTempDirectory (Java 7+) or a library function such as Guava’s similarly-named Files.createTempDir should be used.

This rule raises an issue when the following steps are taken in immediate sequence:

  • call to File.createTempFile

  • delete resulting file

  • call mkdir on the File object

Note that this rule is automatically disabled when the project’s sonar.java.source is lower than 7\`.

```java Bad theme={"system"} File tempDir; tempDir = File.createTempFile("", "."); tempDir.delete(); tempDir.mkdir(); // Noncompliant ``` ```java Fix theme={"system"} Path tempPath = Files.createTempDirectory(""); File tempDir = tempPath.toFile(); ```

It is not uncommon, for instance when dealing with SQL requests, to have repeated calls to StringBuilder.append() to create a long (sometimes really long) String that will be then passed to the appropriate subsystem (e.g. jdbc.Statement()). This is very undesirable because it makes it more difficult to read, and maintain, the statement in the String due to overlapping syntaxes.

It is highly recommended to address such a case with an external text file loaded as a resource.

```java Bad theme={"system"} sb = new StringBuilder() .append("SELECT CASE ") .append("WHEN year = 'FR' THEN 'FR'") .append("WHEN year = 'SO' THEN 'SO'") .append("WHEN year = 'JR' THEN 'JR'") .append("WHEN year = 'SR' THEN 'SR'") .append("ELSE 'No Year Data' END AS year_group,") .append("COUNT(1) AS count") .append("FROM benn.college_football_players") .append("GROUP BY CASE WHEN year = 'FR' THEN 'FR'") .append("WHEN year = 'SO' THEN 'SO'") .append("WHEN year = 'JR' THEN 'JR'") .append("WHEN year = 'SR' THEN 'SR'") .append("ELSE 'No Year Data' END"); ``` ```java Fix theme={"system"} InputStream inputStream = this.getClass().getResourceAsStream("MySQLRequest.txt"); ```

The purpose of the @Value annotation in org.springframework.beans.factory.annotation is to inject a value into a field or method based on the Spring context after it has been established.

If the annotation does not include an expression (either Spring Expression Language or a property injection), the injected value is a simple constant that does not depend on the Spring context, making the annotation replaceable with a standard field initialization statement.

This not only implies the redundant use of @Value, but could also indicate an error where the expression indicators (#, \$) were omitted by mistake.

```java Bad theme={"system"} @Value("catalog.name") // Noncompliant, this will not inject the property String catalog; ``` ```java Fix theme={"system"} @Value("${catalog.name}") // Compliant String catalog; ```

For maximum reusability, methods should accept parameters with as little specialization as possible. So unless specific features from a child class are required by a method, a type higher up the class hierarchy should be used instead.

```java Bad theme={"system"} public void printSize(ArrayList list) { // Collection can be used instead System.out.println(list.size()); } public static void loop(List list) { // java.lang.Iterable can be used instead for (Object o : list) { o.toString(); } } ``` ```java Fix theme={"system"} public void printSize(Collection list) { // Collection can be used instead System.out.println(list.size()); } public static void loop(Iterable list) { // java.lang.Iterable can be used instead for (Object o : list) { o.toString(); } } ```

Because printf-style format strings are interpreted at runtime, rather than validated by the Java compiler, they can contain errors that lead to unexpected behavior or runtime errors. This rule statically validates the good behavior of printf-style formats when calling the format(...) methods of java.util.Formatter, java.lang.String, java.io.PrintStream, MessageFormat, and java.io.PrintWriter classes and the printf(...) methods of java.io.PrintStream or java.io.PrintWriter classes.

```java Bad theme={"system"} String.format("The value of my integer is %d", "Hello World"); // Noncompliant; an 'int' is expected rather than a String String.format("Duke's Birthday year is %tX", c); //Noncompliant; X is not a supported time conversion character String.format("Display %0$d and then %d", 1); //Noncompliant; arguments are numbered starting from 1 String.format("Not enough arguments %d and %d", 1); //Noncompliant; the second argument is missing String.format("%< is equals to %d", 2); //Noncompliant; the argument index '<' refers to the previous format specifier but there isn't one MessageFormat.format("Result {1}.", value); // Noncompliant; Not enough arguments. (first element is {0}) MessageFormat.format("Result {{0}.", value); // Noncompliant; Unbalanced number of curly brace (single curly braces should be escaped) MessageFormat.format("Result ' {0}", value); // Noncompliant; Unbalanced number of quotes (single quote must be escaped) java.util.logging.Logger logger; logger.log(java.util.logging.Level.SEVERE, "Result {1}!", 14); // Noncompliant - Not enough arguments. org.slf4j.Logger slf4jLog; org.slf4j.Marker marker; slf4jLog.debug(marker, "message {}"); // Noncompliant - Not enough arguments. org.apache.logging.log4j.Logger log4jLog; log4jLog.debug("message {}"); // Noncompliant - Not enough arguments. ``` ```java Fix theme={"system"} String.format("The value of my integer is %d", 3); String.format("Duke's Birthday year is %tY", c); String.format("Display %1$d and then %d", 1); String.format("Not enough arguments %d and %d", 1, 2); String.format("%d is equals to %<", 2); MessageFormat.format("Result {0}.", value); MessageFormat.format("Result {0} & {1}.", value, value); MessageFormat.format("Result {0}.", myObject); java.util.logging.Logger logger; logger.log(java.util.logging.Level.SEVERE, "Result {1},{2}!", 14, 2); org.slf4j.Logger slf4jLog; org.slf4j.Marker marker; slf4jLog.debug(marker, "message {}", 1); org.apache.logging.log4j.Logger log4jLog; log4jLog.debug("message {}", 1); ```

ThreadPoolExecutor is an object that efficiently manages and controls the execution of multiple tasks in a thread pool. A thread pool is a collection of pre-initialized threads ready to execute tasks. Instead of creating a new thread for each task, which can be costly in terms of system resources, a thread pool reuses existing threads.

java.util.concurrent.ScheduledThreadPoolExecutor is an extension of ThreadPoolExecutor that can additionally schedule commands to run after a given delay or to execute periodically.

ScheduledThreadPoolExecutor 's pool is sized with corePoolSize, so setting corePoolSize to zero means the executor will have no threads and run nothing. corePoolSize should have a value greater than zero and valid for your tasks.

This rule detects instances where corePoolSize is set to zero via its setter or the object constructor.

```java Bad theme={"system"} public void do(){ int poolSize = 5; // value greater than 0 ScheduledThreadPoolExecutor threadPool1 = new ScheduledThreadPoolExecutor(0); // Noncompliant ScheduledThreadPoolExecutor threadPool2 = new ScheduledThreadPoolExecutor(poolSize); threadPool2.setCorePoolSize(0); // Noncompliant } ``` ```java Fix theme={"system"} ```

The request handler function in a Controller should set the appropriate HTTP status code based on the operation’s success or failure. This is done by returning a Response object with the appropriate status code.

If an exception is thrown during the execution of the handler, the status code should be in the range of 4xx or 5xx. Examples of such codes are BAD\_REQUEST, UNAUTHORIZED, FORBIDDEN, NOT\_FOUND, INTERNAL\_SERVER\_ERROR, BAD\_GATEWAY, SERVICE\_UNAVAILABLE, etc.

The status code should be 1xx, 2xx, or 3xx if no exception is thrown and the operation is considered successful. Such codes include OK, CREATED, MOVED\_PERMANENTLY, FOUND, etc.

```java Bad theme={"system"} @Controller public class UserController { public ResponseEntity getUserById(Long userId) { try { User user = userService.getUserById(userId); return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(user); // Noncompliant: Setting 500 for a successful operation } catch (Exception e) { return ResponseEntity.status(HttpStatus.OK).build(); // Noncompliant: Setting 200 for exception } } } ``` ```java Fix theme={"system"} @Controller public class UserController { public ResponseEntity getUserById(Long userId) { try { User user = userService.getUserById(userId); return ResponseEntity.ok(user); // Compliant: Setting 200 for a successful operation } catch (Exception e) { return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build(); // Compliant: Setting 500 for exception } } } ```

Java offers a built-in serialization mechanism for classes that implement the Serializable interface. The developer can either rely on Java’s default serialization and deserialization logic or implement custom methods for these tasks. The JVM will use methods such as readObject and writeObject to execute custom behavior. This only works, however, if these methods match exactly the expected signatures. If they do not, the JVM will fall back to the default logic, resulting in unexpected behavior at runtime, while the developer believes that the default logic has been overidden.

This rule raises an issue if an implementation of writeObject, readObject, readObjectNoData, writeReplace, or readResolve has an incorrect access modifier, return type, or is not static when it should be (and vice-versa).

```java Bad theme={"system"} public class Watermelon implements Serializable { void writeObject(java.io.ObjectOutputStream out) // Noncompliant, "writeObject" needs to be private, which it is not here throws IOException {...} static Object readResolve() throws ObjectStreamException // Noncompliant, "readResolve" should not be static {...} Watermelon writeReplace() throws ObjectStreamException // Noncompliant, "writeReplace" must return "java.lang.Object" {...} } ``` ```java Fix theme={"system"} public class Watermelon implements Serializable { private void writeObject(java.io.ObjectOutputStream out) // Compliant, method declared as private throws IOException {...} protected Object readResolve() throws ObjectStreamException // Compliant, method is not static {...} private Object writeReplace() throws ObjectStreamException // Compliant, method returns "java.lang.Object" {...} } ```

In certain Android methods, calls to the \`super version of the method should always come first. Otherwise, you risk leaving the job half-done.

This rule raises an issue when the following Activity methods do not begin with a call to super:

  • onCreate

  • onConfigurationChanged

  • onPostCreate

  • onPostResume

  • onRestart

  • onRestoreInstanceState

  • onResume

  • onStart\`

```java Bad theme={"system"} public void onCreate(Bundle bundle) { // Noncompliant; super call missing doSomething(); } public void onPostCreate(Bundle bundle) { doSomethingElse(); super.onPostCreate(bundle); // Noncompliant; should be first statement } ``` ```java Fix theme={"system"} public void onCreate(Bundle bundle) { super.onCreate(bundle); doSomething(); } public void onPostCreate(Bundle bundle) { super.onPostCreate(bundle); doSomethingElse(); } ```

Classes annotated as @Controller in Spring are responsible for handling incoming web requests. When annotating methods or the entire controller with @ResponseBody, the return value of said methods will be serialized and set as the response body. In other words, it tells the Spring framework that this method does not produce a view. This mechanism is commonly used to create API endpoints.

Spring provides @RestController as a convenient annotation to replace the combination of @Controller and @ResponseBody. The two are functionally identical, so the single annotation approach is preferred.

This rule will raise an issue on a class that is annotated with @Controller if:

  • the class is also annotated with @ResponseBody or

  • all methods in said class are annotated with @ResponseBody.

```java Bad theme={"system"} @Controller @ResponseBody public class MyController { @GetMapping("/hello") public String hello() { return "Hello World!"; } } ``` ```java Fix theme={"system"} @RestController public class MyController { @GetMapping("/hello") public String hello() { return "Hello World!"; } } ```

Calling System.exit(int status) or Rutime.getRuntime().exit(int status) calls the shutdown hooks and shuts downs the entire Java virtual machine. Calling Runtime.getRuntime().halt(int) does an immediate shutdown, without calling the shutdown hooks, and skipping finalization.

Each of these methods should be used with extreme care, and only when the intent is to stop the whole Java process. For instance, none of them should be called from applications running in a J2EE container.

```java Bad theme={"system"} System.exit(0); Runtime.getRuntime().exit(0); Runtime.getRuntime().halt(0); ``` ```java Fix theme={"system"} ```

This rule is not really a rule, but a demonstration of the features from Asciidoc that can appear in a rule description.

More specifically, its "How to fix it" section contains several frameworks.

```java Bad theme={"system"} FIXME ``` ```java Fix theme={"system"} FIXED ```

By default case insensitivity only affects letters in the ASCII range. This can be changed by either passing Pattern.UNICODE\_CASE or Pattern.UNICODE\_CHARACTER\_CLASS as an argument to Pattern.compile or using (?u) or (?U) within the regex.

If not done, regular expressions involving non-ASCII letters will still handle those letters as being case sensitive.

```java Bad theme={"system"} Pattern.compile("söme pättern", Pattern.CASE_INSENSITIVE); str.matches("(?i)söme pättern"); str.matches("(?i:söme) pättern"); ``` ```java Fix theme={"system"} Pattern.compile("söme pättern", Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE); str.matches("(?iu)söme pättern"); str.matches("(?iu:söme) pättern"); // UNICODE_CHARACTER_CLASS implies UNICODE_CASE Pattern.compile("söme pättern", Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CHARACTER_CLASS); str.matches("(?iU)söme pättern"); str.matches("(?iU:söme) pättern"); ```

Most checks against an indexOf value compare it with -1 because 0 is a valid index. Checking against > 0 ignores the first element, which is likely a bug.

```java Bad theme={"system"} String name = "ishmael"; if (name.indexOf("ish") > 0) { // Noncompliant // ... } ``` ```java Fix theme={"system"} String name = "ishmael"; if (name.contains("ish") { // ... } ```

Generic types (types with type parameters) have been introduced into Java with language version 1.5. If type parameters are specified for a class or method, it is still possible to ignore them to keep backward compatibility with older code, which is called the raw type of the class or interface.

Using raw type expressions is highly discouraged because the compiler cannot perform static type checking on them. This means that the compiler will not report typing errors about them at compile time, but a ClassCastException will be thrown during runtime.

In Java 1.5, generics were also added to the Java collections API, and the data structures in java.util, such as List, Set, or Map, now feature type parameters. Collections.EMPTY\_LIST, Collections.EMPTY\_SET, and Collections.EMPTY\_MAP are relics from before generics, and they return raw lists, sets, or maps, with the limitations mentioned above.

```java Bad theme={"system"} List collection1 = Collections.EMPTY_LIST; // Noncompliant, raw List Set collection2 = Collections.EMPTY_SET; // Noncompliant, raw Set Map collection3 = Collections.EMPTY_MAP; // Noncompliant, raw Map ``` ```java Fix theme={"system"} List collection1 = Collections.emptyList(); // Compliant, List Set collection2 = Collections.emptySet(); // Compliant, Set Map collection3 = Collections.emptyMap(); // Compliant, Map ```

Iterating over a collection using a for-each loop in Java relies on iterators.

An iterator is an object that allows you to traverse a collection of elements, such as a list or a dictionary. Iterators are used in for-each loops to iterate over the elements of a collection one at a time.

It is important to note that iterators are designed to be read-only. Modifying a collection while iterating over it can cause unexpected behavior, as the iterator may skip over or repeat elements. Therefore, it is important to avoid modifying a collection while iterating over it to ensure that your code behaves as expected.

Most JDK collection implementations don’t support such modification and may throw a ConcurrentModificationException. Even if no such exception is thrown, attempting to modify a collection during iteration could be the source of incorrect or unspecified behaviors in the code.

If you still want to modify the collection, it is best to refactor the code and use a second collection (e.g by using streams and filter operations).

```java Bad theme={"system"} public static void foo(List lst) { for (String element : lst) { if (element.startsWith("x")) { lst.remove(element); // Noncompliant: lst size has been modified by "remove" call while it's iterated. } } } ``` ```java Fix theme={"system"} public static void foo(List lst) { List toRemove = new ArrayList<>(); for (String element : lst) { if (element.startsWith("x")) { toRemove.add(element); } } lst.removeAll(toRemove); } ```

The BigDecimal is used to represents immutable, arbitrary-precision signed decimal numbers.

Differently from the BigDecimal, the double primitive type and the Double type have limited precision due to the use of double-precision 64-bit IEEE 754 floating point. Because of floating point imprecision, the BigDecimal(double) constructor can be somewhat unpredictable.

For example writing new BigDecimal(0.1) doesn’t create a BigDecimal which is exactly equal to 0.1, but it is equal to 0.1000000000000000055511151231257827021181583404541015625. This is because 0.1 cannot be represented exactly as a double (or, for that matter, as a binary fraction of any finite length).

```java Bad theme={"system"} double d = 1.1; BigDecimal bd1 = new BigDecimal(d); // Noncompliant BigDecimal bd2 = new BigDecimal(1.1); // Noncompliant ``` ```java Fix theme={"system"} double d = 1.1; BigDecimal bd1 = BigDecimal.valueOf(d); // Compliant BigDecimal bd2 = new BigDecimal("1.1"); // Compliant ```

Primitives can be read and written to atomically. Except for \`long and double, that is. These 64-bit primitives must be marked volatile in multi-threaded environments, or swapped out for their atomic counterparts: AtomicLong, and AtomicDouble to guarantee that their updates are always visible to other threads.

Similarly, to ensure that updates to 32-bit primitives are visible to all threads, they should also be marked volatile\`.

```java Bad theme={"system"} long m = 0; // Noncompliant public void increment() { m++; } ``` ```java Fix theme={"system"} volatile long m = 0; public void increment() { m++; } ```

In regular expressions the escape sequence \`\cX, where the X stands for any character that’s either @, any capital ASCII letter, \[, , ], ^ or \_, represents the control character that "corresponds" to the character following \c, meaning the control character that comes 64 bytes before the given character in the ASCII encoding.

In some other regex engines (for example in that of Perl) this escape sequence is case insensitive and \cd produces the same control character as \cD. Further using \c with a character that’s neither @, any ASCII letter, \[, , ], ^ nor \_, will produce a warning or error in those engines. Neither of these things is true in Java, where the value of the character is always XORed with 64 without checking that this operation makes sense. Since this won’t lead to a sensible result for characters that are outside of the @ to \_ range, using \c\` with such characters is almost certainly a mistake.

```java Bad theme={"system"} Pattern.compile("\\ca"); // Noncompliant, 'a' is not an upper case letter Pattern.compile("\\c!"); // Noncompliant, '!' is outside of the '@'-'_' range ``` ```java Fix theme={"system"} Pattern.compile("\\cA"); // Compliant, this will match the "start of heading" control character Pattern.compile("\\c^"); // Compliant, this will match the "record separator" control character ```

This rule raises an issue when:

  • a JavaMail’s \`javax.mail.Session is created with a Properties object having no mail.smtp.ssl.checkserveridentity or mail.smtps.ssl.checkserveridentity not configured to true

  • a Apache Common Emails’s org.apache.commons.mail.SimpleEmail is used with setSSLOnConnect(true) or setStartTLSEnabled(true) or setStartTLSRequired(true) without a call to setSSLCheckServerIdentity(true)\`

```java Bad theme={"system"} Email email = new SimpleEmail(); email.setSmtpPort(465); email.setAuthenticator(new DefaultAuthenticator(username, password)); email.setSSLOnConnect(true); // Noncompliant; setSSLCheckServerIdentity(true) should also be called before sending the email email.send(); ``` ```java Fix theme={"system"} Properties props = new Properties(); props.put("mail.smtp.host", "smtp.gmail.com"); props.put("mail.smtp.socketFactory.port", "465"); props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); // Noncompliant; Session is created without having "mail.smtp.ssl.checkserveridentity" set to true props.put("mail.smtp.auth", "true"); props.put("mail.smtp.port", "465"); Session session = Session.getDefaultInstance(props, new javax.mail.Authenticator() { protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication("username@gmail.com", "password"); } }); ```

The battery life is a major concern for mobile devices and choosing the right Sensor is very important to reduce the power usage and extend the battery life.

It is recommended, for reducing the power usage, to use TYPE\_GEOMAGNETIC\_ROTATION\_VECTOR for background tasks, long-running tasks and other tasks not requiring accurate motion detection.

The rule reports an issue when android.hardware.SensorManager#getDefaultSensor uses TYPE\_ROTATION\_VECTOR instead of TYPE\_GEOMAGNETIC\_ROTATION\_VECTOR.

```java Bad theme={"system"} public class BackGroundActivity extends Activity { private Sensor motionSensor; @Override protected void onCreate(Bundle savedInstanceState) { SensorManager sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); motionSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR); // Noncompliant // .. } //.. } ``` ```java Fix theme={"system"} public class BackGroundActivity extends Activity { private Sensor motionSensor; @Override protected void onCreate(Bundle savedInstanceState) { SensorManager sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); motionSensor = sensorManager.getDefaultSensor(Sensor.TYPE_GEOMAGNETIC_ROTATION_VECTOR); // Compliant // .. } //.. } ```

Spring beans belonging to packages that are not included in a \`@ComponentScan configuration will not be accessible in the Spring Application Context. Therefore, it’s likely to be a configuration mistake that will be detected by this rule.

Note: the @ComponentScan is implicit in the @SpringBootApplication\` annotation, case in which Spring Boot will auto scan for components in the package containing the Spring Boot main class and its sub-packages.

```java Bad theme={"system"} package com.mycompany.app; @Configuration @ComponentScan("com.mycompany.app.beans") public class Application { ... } package com.mycompany.app.web; @Controller public class MyController { // Noncompliant; MyController belong to "com.mycompany.app.web" while the ComponentScan is looking for beans in "com.mycompany.app.beans" package ... } ``` ```java Fix theme={"system"} package com.mycompany.app; @Configuration @ComponentScan({"com.mycompany.app.beans","com.mycompany.app.web"}) or @ComponentScan("com.mycompany.app") or @ComponentScan public class Application { ... } package com.mycompany.app.web; @Controller public class MyController { // "com.mycompany.app.web" is referenced by a @ComponentScan annotated class ... } ```

Java’s garbage collection cannot be relied on to clean up everything. Specifically, subclasses of \`org.eclipse.swt.graphics.Resource must be manually dispose()-ed when you’re done with them.

Particularly for the Image subclass, which retains an open FileHandle for the life of the instance, failure to properly dispose of Resource\`s can result in a resource leak which could bring first the application and then perhaps the box it’s on to their knees.

```java Bad theme={"system"} import org.eclipse.swt.graphics.Image; public class MyLeakyView { Image myImage = new Image("image/path"); // Noncompliant; not disposed ``` ```java Fix theme={"system"} import org.eclipse.swt.graphics.Image; public class MyView { Image myImage = new Image("image/path"); public void callMeWhenItsDone() { myImage.dispose(); } ```

The use of org.fest.assertions.Assertions.assertThat by itself does nothing. You must combine it with another method that actually tests the value in use.

```java Bad theme={"system"} assertThat(name); // Noncompliant ``` ```java Fix theme={"system"} assertThat(name).isNotNull(); ```

When the call to a function doesn’t have any side effects, what is the point of making the call if the results are ignored? In such case, either the function call is useless and should be dropped or the source code doesn’t behave as expected.

To prevent generating any false-positives, this rule triggers an issue only on the following predefined list of immutable classes in the Java API :

  • \`java.lang.String

  • java.lang.Boolean

  • java.lang.Integer

  • java.lang.Double

  • java.lang.Float

  • java.lang.Byte

  • java.lang.Character

  • java.lang.Short

  • java.lang.StackTraceElement

  • java.time.DayOfWeek

  • java.time.Duration

  • java.time.Instant

  • java.time.LocalDate

  • java.time.LocalDateTime

  • java.time.LocalTime

  • java.time.Month

  • java.time.MonthDay

  • java.time.OffsetDateTime

  • java.time.OffsetTime

  • java.time.Period

  • java.time.Year

  • java.time.YearMonth

  • java.time.ZonedDateTime

  • java.math.BigInteger

  • java.math.BigDecimal

  • java.util.Optional

As well as methods of the following classes:

  • java.util.Collection:

    • size()

    • isEmpty()

    • contains(...)

    • containsAll(...)

    • iterator()

    • toArray()

  • java.util.Map:

    • size()

    • isEmpty()

    • containsKey(...)

    • containsValue(...)

    • get(...)

    • getOrDefault(...)

    • keySet()

    • entrySet()

    • values()

  • java.util.stream.Stream

    • toArray

    • reduce

    • collect

    • min

    • max

    • count

    • anyMatch

    • allMatch

    • noneMatch

    • findFirst

    • findAny

    • toList\`

```java Bad theme={"system"} public void handle(String command){ command.toLowerCase(); // Noncompliant; result of method thrown away ... } ``` ```java Fix theme={"system"} public void handle(String command){ String formattedCommand = command.toLowerCase(); ... } ```

When a type variable or a wildcard declares an upper bound that is final, the parametrization is not generic at all because it accepts one and only one type at runtime: the one that is final. Instead of using Generics, it’s simpler to directly use the concrete final class.

```java Bad theme={"system"} public static T getMyString() { // Noncompliant; String is a "final" class and so can't be extended [...] } ``` ```java Fix theme={"system"} public static String getMyString() { // Compliant [...] } ```

By default, the Maven Surefire plugin only executes test classes with names that end in "Test" or "TestCase". Name your class "TestClassX.java", for instance, and it will be skipped.

This rule raises an issue for each test class with a name not ending in "Test" or "TestCase".

```java Bad theme={"system"} public class TestClassX { // Noncompliant @Test public void testDoTheThing() { //... ``` ```java Fix theme={"system"} public class ClassXTest { @Test public void testDoTheThing() { //... ```

In Java 16 \`records are finalized and can be safely used in production code. Records represent immutable read-only data structure and should be used instead of creating immutable classes. Immutability of records is guaranteed by the Java language itself, while implementing immutable classes on your own might lead to some bugs.

One of the important aspects of records\` is that final fields can’t be overwritten using reflection.

This rule reports an issue on classes for which all these statements are true:

  • all instance fields are private and final

  • has only one constructor with a parameter for all fields

  • has getters for all fields

```java Bad theme={"system"} final class Person { // Noncompliant private final String name; private final int age; public Person(String name, int age) { this.name = name; this.age = age; } public String getName() {...} public int getAge() {...} @Override public boolean equals(Object o) {...} @Override public int hashCode() {...} @Override public String toString() {...} } ``` ```java Fix theme={"system"} record Person(String name, int age) { } ```

Deserialization takes a stream of bits and turns it into an object. If the stream contains the type of object you expect, all is well. But if you’re deserializing untrusted input, and an attacker has inserted some other type of object, you’re in trouble. Why? There are a few different attack scenarios, but one widely-documented one goes like this: Deserialization first instantiates an \`Object, then uses the readObject method to populate it. If the attacker has overridden readObject then he is entirely in control of what code executes during that process. It is only after readObject has completed that your newly-minted Object can be cast to the type you expected. A ClassCastException or ClassNotFoundException will be thrown, but at that point it’s too late.

To prevent this, you should either use look-ahead deserialization (pre-Java 9) or filtering to make sure you’re dealing with the correct type of object before you act on it.

Several third-party libraries offer look-ahead deserialization, including:

  • ikkisoft’s SerialKiller

  • Apache Commons Class IO’s ValidatingObjectInputStream

  • contrast-rO0’s SafeObjectInputStream\`

Note that it is possible to set a deserialization filter at the level of the JVM, but relying on that requires that your environment be configured perfectly. Every time. Additionally, such a filter may have unwanted impacts on other applications in the environment. On the other hand, setting a filter as close as possible to the deserialization that uses it allows you to specify a very narrow, focused filter.

```java Bad theme={"system"} FileInputStream in = new FileInputStream("obj"); ObjectInputStream ois = new ObjectInputStream(in); // Noncompliant Foo reconstitutedFoo = (foo)ois.readObject(); ``` ```java Fix theme={"system"} FileInputStream in = new FileInputStream("obj"); ObjectInputStream ois = new SerialKiller(is, "/etc/serialkiller.conf"); String msg = (String) ois.readObject(); ```

Some implementations of java.sql.ResultSet#getMetaData() suffer from performance issue and should not be called in a loop. Instead, multiple calls in a row should be replaced by a single cached call.

```java Bad theme={"system"} ResultSetMetaData rsmd = rs.getMetaData(); for (int i=1; i

In Java 14 there is a new way to write cases in Switch Statement and Expression when the same action should be performed for different cases. Instead of declaring multiples branches with the same action, you can combine all of them in a single case group, separated with commas. It will result in a more concise code and improved readability.

This rule reports an issue when multiple cases in a Switch can be grouped into a single comma-separated case.

```java Bad theme={"system"} // Switch Expression int i = switch (mode) { case "a": case "b": yield 1; default: yield 3; }; // Switch Statement switch (mode) { case "a": case "b": doSomething(); break; default: doSomethingElse(); } ``` ```java Fix theme={"system"} // Switch Expression int i = switch (mode) { case "a", "b": yield 1; default: yield 3; }; // Switch Statement switch (mode) { case "a", "b": doSomething(); break; default: doSomethingElse(); } // Or even better: switch (mode) { case "a", "b" -> doSomething(); default -> doSomethingElse(); } ```

There’s no need to invoke stream() on a Collection before a forEach call because each Collection has its own forEach method.

```java Bad theme={"system"} identifiers.stream().forEach(System.out::println); // Noncompliant ``` ```java Fix theme={"system"} identifiers.forEach(System.out::println); // Noncompliant ```

An \`assert is inappropriate for parameter validation because assertions can be disabled at runtime in the JVM, meaning that a bad operational setting would completely eliminate the intended checks. Further, asserts that fail throw AssertionErrors, rather than throwing some type of Exception. Throwing Errors is completely outside of the normal realm of expected catch/throw behavior in normal programs.

This rule raises an issue when a public method uses one or more of its parameters with assert\`s.

```java Bad theme={"system"} public void setPrice(int price) { assert price >= 0 && price <= MAX_PRICE; // Set the price } ``` ```java Fix theme={"system"} public void setPrice(int price) { if (price < 0 || price > MAX_PRICE) { throw new IllegalArgumentException("Invalid price: " + price); } // Set the price } ```

Synchronizing at the method, rather than the block level could lead to problems when maintenance adds code to the method, perhaps inadvertently synchronizing it as well. Instead, synchronization should be applied to the smallest feasible block for optimum performance and maintainability.

```java Bad theme={"system"} public class MyClass() { public void synchronized doSomething() { // Noncompliant // ... } } ``` ```java Fix theme={"system"} public class MyClass() { private Object lockObj = new Object(); public void doSomething() { synchronized(lockObj) { // ... } } } ```

The MD5 algorithm and its successor, SHA-1, are no longer considered secure, because it is too easy to create hash collisions with them. That is, it takes too little computational effort to come up with a different input that produces the same MD5 or SHA-1 hash, and using the new, same-hash value gives an attacker the same access as if he had the originally-hashed value. This applies as well to the other Message-Digest algorithms: MD2, MD4, MD6, HAVAL-128, HMAC-MD5, DSA (which uses SHA-1), RIPEMD, RIPEMD-128, RIPEMD-160, HMACRIPEMD160.

The following APIs are tracked for use of obsolete crypto algorithms:

  • \`java.security.AlgorithmParameters (JDK)

  • java.security.AlgorithmParameterGenerator (JDK)

  • java.security.MessageDigest (JDK)

  • java.security.KeyFactory (JDK)

  • java.security.KeyPairGenerator (JDK)

  • java.security.Signature (JDK)

  • javax.crypto.Mac (JDK)

  • javax.crypto.KeyGenerator (JDK)

  • org.apache.commons.codec.digest.DigestUtils (Apache Commons Codec)

  • org.springframework.util.DigestUtils

  • com.google.common.hash.Hashing (Guava)

  • org.springframework.security.authentication.encoding.ShaPasswordEncoder (Spring Security 4.2.x)

  • org.springframework.security.authentication.encoding.Md5PasswordEncoder (Spring Security 4.2.x)

  • org.springframework.security.crypto.password.LdapShaPasswordEncoder (Spring Security 5.0.x)

  • org.springframework.security.crypto.password.Md4PasswordEncoder (Spring Security 5.0.x)

  • org.springframework.security.crypto.password.MessageDigestPasswordEncoder (Spring Security 5.0.x)

  • org.springframework.security.crypto.password.NoOpPasswordEncoder (Spring Security 5.0.x)

  • org.springframework.security.crypto.password.StandardPasswordEncoder\` (Spring Security 5.0.x)

Consider using safer alternatives, such as SHA-256, SHA-3 or adaptive one way functions like bcrypt or PBKDF2.

```java Bad theme={"system"} MessageDigest md = MessageDigest.getInstance("SHA1"); // Noncompliant ``` ```java Fix theme={"system"} MessageDigest md = MessageDigest.getInstance("SHA-256"); ```

An interface that consists solely of constant definitions is a bad practice. The purpose of interfaces is to provide an API, not implementation details. That is, they should provide functions in the first place and constants only to assist these functions, for example, as possible arguments.

If an interface contains constants only, move them either to somewhere else, or replace the interface with an Enum or a final class with a private constructor.

```java Bad theme={"system"} public interface Status { // Noncompliant, enum should be used int OPEN = 1; int CLOSED = 2; } ``` ```java Fix theme={"system"} public enum Status { // Compliant OPEN, CLOSED } ```

Failing to explicitly declare the visibility of a member variable could result it in having a visibility you don’t expect, and potentially leave it open to unexpected modification by other classes.

The default access level modifier may be intentional; in that case, this rule can report false positives.

```java Bad theme={"system"} class Ball { String color = "red"; // Noncompliant } enum A { B; int a; // Noncompliant } ``` ```java Fix theme={"system"} class Ball { private String color = "red"; // Compliant } enum A { B; private int a; // Compliant } ```

Mutable objects are those whose state can be changed. For instance, an array is mutable, but a String is not. Private mutable class members should never be returned to a caller or accepted and stored directly. Doing so leaves you vulnerable to unexpected changes in your class state.

Instead use an unmodifiable Collection (via Collections.unmodifiableCollection, Collections.unmodifiableList, …​) or make a copy of the mutable object, and store or return the copy instead.

This rule checks that private arrays, collections and Dates are not stored or returned directly.

```java Bad theme={"system"} class A { private String [] strings; public A () { strings = new String[]{"first", "second"}; } public String [] getStrings() { return strings; // Noncompliant } public void setStrings(String [] strings) { this.strings = strings; // Noncompliant } } public class B { private A a = new A(); // At this point a.strings = {"first", "second"}; public void wreakHavoc() { a.getStrings()[0] = "yellow"; // a.strings = {"yellow", "second"}; } } ``` ```java Fix theme={"system"} class A { private String [] strings; public A () { strings = new String[]{"first", "second"}; } public String [] getStrings() { return strings.clone(); } public void setStrings(String [] strings) { this.strings = strings.clone(); } } public class B { private A a = new A(); // At this point a.strings = {"first", "second"}; public void wreakHavoc() { a.getStrings()[0] = "yellow"; // a.strings = {"first", "second"}; } } ```

\`@ComponentScan is used to determine which Spring Beans are available in the application context. The packages to scan can be configured thanks to the basePackageClasses or basePackages (or its alias value) parameters. If neither parameter is configured, @ComponentScan will consider only the package of the class annotated with it. When @ComponentScan is used on a class belonging to the default package, the entire classpath will be scanned.

This will slow-down the start-up of the application and it is likely the application will fail to start with an BeanDefinitionStoreException because you ended up scanning the Spring Framework package itself.

This rule raises an issue when:

  • @ComponentScan, @SpringBootApplication and @ServletComponentScan are used on a class belonging to the default package

  • @ComponentScan\` is explicitly configured with the default package

```java Bad theme={"system"} import org.springframework.boot.SpringApplication; @SpringBootApplication // Noncompliant; RootBootApp is declared in the default package public class RootBootApp { ... } ``` ```java Fix theme={"system"} @ComponentScan("") public class Application { ... } ```

The use of shorts saves a little bit of memory, but actually increases processor use because the JVM has no real capability for handling shorts. Instead, it must convert each short to an int before performing any operations on it, then convert it back to a short for storage.

```java Bad theme={"system"} public class MyClass { short s = 0; // Noncompliant public short doubleSmallNumber(short num) { // Noncompliant return num+num; } } ``` ```java Fix theme={"system"} public class MyClass { int s = 0; public int doubleSmallNumber(int num) { return num+num; } } ```

Many existing switch statements are essentially simulations of switch expressions, where each arm either assigns to a common target variable or returns a value. Expressing this as a statement is roundabout, repetitive, and error-prone.

Java 14 added support for switch expressions, which provide more succinct and less error-prone version of switch.

```java Bad theme={"system"} void day_of_week(DoW day) { int numLetters; switch (day) { // Noncompliant case MONDAY: case FRIDAY: case SUNDAY: numLetters = 6; break; case TUESDAY: numLetters = 7; break; case THURSDAY: case SATURDAY: numLetters = 8; break; case WEDNESDAY: numLetters = 9; break; default: throw new IllegalStateException("Wat: " + day); } } int return_switch(int x) { switch (x) { // Noncompliant case 1: return 1; case 2: return 2; default: throw new IllegalStateException(); } } ``` ```java Fix theme={"system"} int numLetters = switch (day) { case MONDAY, FRIDAY, SUNDAY -> 6; case TUESDAY -> 7; case THURSDAY, SATURDAY -> 8; case WEDNESDAY -> 9; }; ```

A hardcoded file path is a guarantee that eventually the program will fail. It may happen because the paths on the target machine changed or because the application was deployed on an OS other than the one on which it was developed. After all, not every OS has a "C:" drive, just has not every OS has a "/home" directory.

This rule checks for hardcoded, absolute paths in Files and all types of input and output streams.

```java Bad theme={"system"} public void readProperties() { File in = new File("C:/myappdir/app.properties"); // Noncompliant } ``` ```java Fix theme={"system"} public void readProperties(String path) { File in = new File(path + "app.properties"); } ```

Using wildcards in imports may look cleaner as it reduces the number of lines in the import section and simplifies the code. On the other hand, it makes the code harder to maintain:

  • It reduces code readability as developers will have a hard time knowing where names come from.

  • It could lead to conflicts between names defined locally and the ones imported.

  • It could later raise conflicts on dependency upgrade or Java version migration, as a wildcard import that works today might be broken tomorrow.

That is why it is better to import only the specific classes or modules you need.

```java Bad theme={"system"} import static java.lang.Math.*; ``` ```java Fix theme={"system"} import java.sql.*; // Noncompliant import java.util.*; // Noncompliant private Date date; // Date class exists in java.sql and java.util. Which one is this? ```

Java 21 introduces the new method Math.clamp(value, min, max) that fits a value within a specified interval. Before Java 21, this behavior required explicit calls to the Math.min and Math.max methods, as in Math.min(max, Math.max(value, min)).

If min > max, Math.clamp throws an IllegalArgumentException, indicating an invalid interval. This can occur if the min and max arguments are mistakenly reversed.

Note that Math.clamp is not a general substitute for Math.min or Math.max, but for the combination of both. If value is the same as min or max, using Math.clamp is unnecessary and Math.min or Math.max should be used instead.

```java Bad theme={"system"} Math.clamp(red, 255, 0); // Noncompliant, [255,0] is not a valid range ``` ```java Fix theme={"system"} Math.clamp(red, 0, 255); // Compliant ```

@Autowired is an annotation in the Spring Framework for automatic dependency injection. It tells Spring to automatically provide the required dependencies (such as other beans or components) to a class’s fields, methods, or constructors, allowing for easier and more flexible management of dependencies in a Spring application. In other words, it’s a way to wire up and inject dependencies into Spring components automatically, reducing the need for manual configuration and enhancing modularity and maintainability.

In any bean class, only one constructor is permitted to declare @Autowired with the required attribute set to true. This signifies the constructor to be automatically wired when used as a Spring bean. Consequently, when the required attribute remains at its default value (true), only a singular constructor can bear the @Autowired annotation. In cases where multiple constructors have this annotation, they must all specify required=false to be eligible as candidates for auto-wiring.

```java Bad theme={"system"} @Component public class MyComponent { private final MyService myService; @Autowired public MyComponent(MyService myService) { this.myService = myService; // ... } @Autowired // Noncompliant public MyComponent(MyService myService, Integer i) { this.myService = myService; // ... } @Autowired // Noncompliant public MyComponent(MyService myService, Integer i, String s) { this.myService = myService; // ... } } ``` ```java Fix theme={"system"} @Component public class MyComponent { private final MyService myService; @Autowired public MyComponent(MyService myService) { this.myService = myService; // ... } public MyComponent(MyService myService, Integer i) { this.myService = myService; // ... } public MyComponent(MyService myService, Integer i, String s) { this.myService = myService; // ... } } ```

A Single Abstract Method (SAM) interface is a Java interface containing only one method. The Java API is full of SAM interfaces, such as \`java.lang.Runnable, java.awt.event.ActionListener, java.util.Comparator and java.util.concurrent.Callable. SAM interfaces have a special place in Java 8 because they can be implemented using Lambda expressions or Method references.

Using @FunctionalInterface forces a compile break when an additional, non-overriding abstract method is added to a SAM, which would break the use of Lambda implementations.

Note that this rule is automatically disabled when the project’s sonar.java.source is lower than 8\`.

```java Bad theme={"system"} public interface Changeable { public void change(T o); } ``` ```java Fix theme={"system"} @FunctionalInterface public interface Changeable { public void change(T o); } ```

Use of File.deleteOnExit() is not recommended for the following reasons:

  • The deletion occurs only in the case of a normal JVM shutdown but not when the JVM crashes or is killed.

  • For each file handler, the memory associated with the handler is released only at the end of the process.

```java Bad theme={"system"} File file = new File("file.txt"); file.deleteOnExit(); // Noncompliant ``` ```java Fix theme={"system"} ```

When @Autowired is used, dependencies need to be resolved when the class is instantiated, which may cause early initialization of beans or lead the context to look in places it shouldn’t to find the bean. To avoid this tricky issue and optimize the way the context loads, dependencies should be requested as late as possible. That means using parameter injection instead of field injection for dependencies that are only used in a single @Bean method.

```java Bad theme={"system"} @Configuration public class ​FooConfiguration { @Autowired private ​DataSource dataSource​; // Noncompliant @Bean public ​MyService myService() { return new ​MyService(this​.dataSource​); } } ``` ```java Fix theme={"system"} @Configuration public class ​FooConfiguration { @Bean public ​MyService myService(DataSource dataSource) { return new ​MyService(dataSource); } } ```

The right-hand side of a lambda expression can be written in two ways:

  1. Expression notation: the right-hand side is as an expression, such as in (a, b) → a + b

  2. Block notation: the right-hand side is a conventional function body with a code block and an optional return statement, such as in (a, b) → \{return a + b;}

By convention, expression notation is preferred over block notation. Block notation must be used when the function implementation requires more than one statement. However, when the code block consists of only one statement (which may or may not be a return statement), it can be rewritten using expression notation.

This convention exists because expression notation has a cleaner, more concise, functional programming style and is regarded as more readable.

```java Bad theme={"system"} (a, b) -> { return a + b; } // Noncompliant, replace code block with expression ``` ```java Fix theme={"system"} (a, b) -> a + b // Compliant ```

Assertions comparing an object to itself are more likely to be bugs due to developer’s carelessness.

This rule raises an issue when the actual expression matches the expected expression.

```java Bad theme={"system"} assertThat(actual).isEqualTo(actual); // Noncompliant ``` ```java Fix theme={"system"} assertThat(actual).isEqualTo(expected); ```

Declaring multiple variables on one line is difficult to read.

```java Bad theme={"system"} class MyClass { private int a, b; public void method(){ int c; int d; } } ``` ```java Fix theme={"system"} class MyClass { private int a; private int b; public void method(){ int c; int d; } } ``` ```java Bad theme={"system"} class Outer { public static int A; public class Inner { public int A; // Noncompliant public int MyProp { get { return A; } // Returns inner A. Was that intended? } } } ``` ```java Fix theme={"system"} class Outer { public static int A; // Compliant public class Inner { public int B; public int MyProp { get { return A; } // Returns inner A } } } ```

The Java 8 version of \`HashMap handles key clashes by storing nodes in a binary tree when more than 11 keys clash with each other, and that tree needs to know the relative order of the keys. If you don’t provide a compareTo method, System.identityHashCode() will be used as the fallback, and that typically returns a value based on the object’s memory location, resulting in a performance degradation to O(n) where n is the number of objects at that map location.

Therefore, it’s considered a best practice to implement compareTo in classes that are used as HashMap keys.

Note that this rule is automatically disabled when the project’s sonar.java.source is lower than 8\`.

```java Bad theme={"system"} public class Key { @Override public boolean equals(Object obj) { /* ... */ } @Override public int hashCode() { /* ... */ } } public void doTheThing() { Map map = new HashMap<>(); // Noncompliant // ... } ``` ```java Fix theme={"system"} public class Key implements Comparable{ @Override public boolean equals(Object obj) { /* ... */ } @Override public int hashCode() { /* ... */ } @Override public int compareTo(Object o) { //... } } public void doTheThing() { Map map = new HashMap<>(); // ... } ```

The use of a StringBuilder or StringBuffer is supposed to make String assembly more efficient than plain concatenation. So don’t ruin the effect by concatenating the arguments to append.

```java Bad theme={"system"} StringBuilder sb = new StringBuilder(); sb.append("foo is: " + getFoo()); // Noncompliant ``` ```java Fix theme={"system"} StringBuilder sb = new StringBuilder(); sb.append("foo is: ").append(getFoo()); ```

Using \`Integer.toHexString is a common mistake when converting sequences of bytes into hexadecimal string representations. The problem is that the method trims leading zeroes, which can lead to wrong conversions. For instance a two bytes value of 0x4508 would be converted into 45 and 8 which once concatenated would give 0x458.

This is particularly damaging when converting hash-codes and could lead to a security vulnerability.

This rule raises an issue when Integer.toHexString\` is used in any kind of string concatenations.

```java Bad theme={"system"} MessageDigest md = MessageDigest.getInstance("SHA-256"); byte[] bytes = md.digest(password.getBytes("UTF-8")); StringBuilder sb = new StringBuilder(); for (byte b : bytes) { sb.append(Integer.toHexString( b & 0xFF )); // Noncompliant } ``` ```java Fix theme={"system"} MessageDigest md = MessageDigest.getInstance("SHA-256"); byte[] bytes = md.digest(password.getBytes("UTF-8")); StringBuilder sb = new StringBuilder(); for (byte b : bytes) { sb.append(String.format("%02X", b)); } ```

JUnit rules are predefined classes that extend the behavior of JUnit tests, allowing to add new functionalities, such as managing resources, modifying test behavior, and handling exceptions.

Unused JUnit rules can lead to confusion when reading the test code, making tests harder to understand and maintain. Having unused rules can also slow down the test suite, as JUnit has to process the rules even though they are not being used. Some TestRule classes have the desired effect without being directly referenced by a test, while others do not. There’s no reason to leave them cluttering the file if they’re not in use.

The rule raises an issue when in a Test class, there is no method referencing a declared TestRule of the following types:

  • TemporaryFolder and TestName in JUnit

  • TempDir and TestInfo in JUnit 5

```java Bad theme={"system"} public class ProjectDefinitionTest { @Rule public TemporaryFolder temp = new TemporaryFolder(); // Noncompliant @Test public void shouldSetKey() { ProjectDefinition def = ProjectDefinition.create(); def.setKey("mykey"); assertThat(def.getKey(), is("mykey")); } } ``` ```java Fix theme={"system"} public class ProjectDefinitionTest { @Test public void shouldSetKey() { ProjectDefinition def = ProjectDefinition.create(); def.setKey("mykey"); assertThat(def.getKey(), is("mykey")); } } ```

According to the Java Language Specification:

It is permitted, but discouraged as a matter of style, to redundantly specify the public and/or abstract modifier for a method declared in an interface.

```java Bad theme={"system"} public interface Task{ public abstract void execute(); } ``` ```java Fix theme={"system"} public interface Task{ void execute(); } ```

The classes in the sun.\* packages are not part of the official Java API and are not intended for public use. They are internal implementation details specific to the Oracle JDK (Java Development Kit). Therefore, their availability, behavior, or compatibility is not guaranteed across different Java implementations or versions.

Since these classes are not part of the official Java API, they usually lack proper documentation and support. Finding comprehensive and up-to-date information about their usage, functionality, and potential limitations can be challenging. This lack of documentation can make it difficult to understand how to use these classes correctly.

Classes in the sun.\* packages are often platform-dependent and can vary between different operating systems or Java Virtual Machine (JVM) implementations. Relying on these classes may lead to code that works on one platform but fails on others, limiting your code’s portability and cross-platform compatibility.

```java Bad theme={"system"} import sun.misc.BASE64Encoder; // Noncompliant ``` ```java Fix theme={"system"} ```

The \`java.util.regex.Pattern.compile() methods have a significant performance cost, and therefore should be used sensibly.

Moreover they are the only mechanism available to create instances of the Pattern class, which are necessary to do any pattern matching using regular expressions. Unfortunately that can be hidden behind convenience methods like String.matches() or String.split().

It is therefore somewhat easy to inadvertently repeatedly compile the same regular expression at great performance cost with no valid reason.

This rule raises an issue when:

  • A Pattern is compiled from a String literal or constant and is not stored in a static final reference.

  • String.matches, String.split, String.replaceAll or String.replaceFirst are invoked with a String literal or constant. In which case the code should be refactored to use a java.util.regex.Pattern\` while respecting the previous rule.

```java Bad theme={"system"} public void doingSomething(String stringToMatch) { Pattern regex = Pattern.compile("myRegex"); // Noncompliant Matcher matcher = regex.matcher("s"); // ... if (stringToMatch.matches("myRegex2")) { // Noncompliant // ... } } ``` ```java Fix theme={"system"} private static final Pattern myRegex = Pattern.compile("myRegex"); private static final Pattern myRegex2 = Pattern.compile("myRegex2"); public void doingSomething(String stringToMatch) { Matcher matcher = myRegex.matcher("s"); // ... if (myRegex2.matcher(stringToMatch).matches()) { // ... } } ```

Java packages serve two purposes:

  1. Structure — Packages give a structure to the set of classes of your project. It is a bad practice to put all classes flat into the source directory of a project without a package structure. A structure helps to mentally break down a project into smaller parts, simplifying readers' understanding of how components are connected and how they interact.

  2. Avoiding name clashes — a class part of the default package if no explicit package name is specified. This can easily cause name collisions when other projects define a class of the same name.

When no package is explicitly specified for the classes in your project, this makes the project harder to understand and may cause name collisions with other projects. Also, classes located in the default package not be accessed from classes within named packages since Java 1.4.

```java Bad theme={"system"} public class MyClass { /* ... */ } // Noncompliant, no package spacified ``` ```java Fix theme={"system"} package org.example; // Compliant public class MyClass{ /* ... */ } ```

A for loop is a type of loop construct that allows a block of code to be executed repeatedly for a fixed number of times. The for loop is typically used when the number of iterations is known in advance and consists of three parts:

  • The initialization statement is executed once at the beginning of the loop. It is used to initialize the loop counter or any other variables that may be used in the loop.

  • The loop condition is evaluated at the beginning of each iteration, and if it is true, the code inside the loop is executed.

  • The update statement is executed at the end of each iteration and is used to update the loop counter or any other variables that may be used in the loop.

```java Bad theme={"system"} for (initialization; termination; increment) { /*...*/ } ``` ```java Fix theme={"system"} for (;condition;) { /*...*/ } // Noncompliant; only the condition is specified ```

When you call isEmpty(), it clearly communicates the code’s intention, which is to check if the collection is empty. Using \`size()

```java Bad theme={"system"} public class MyClass { public void doSomething(Collection myCollection) { if (myCollection.size() == 0) { // Noncompliant doSomethingElse(); } } } ``` ```java Fix theme={"system"} public class MyClass { public void doSomething(Collection myCollection) { if (myCollection.isEmpty()) { doSomethingElse(); } } } ```

Servlets are components in Java web development, responsible for processing HTTP requests and generating responses. In this context, exceptions are used to handle and manage unexpected errors or exceptional conditions that may occur during the execution of a servlet.

Catching exceptions within the servlet allows us to convert them into meaningful, user-friendly messages. Otherwise, failing to catch exceptions will propagate them to the servlet container, where the default error-handling mechanism may impact the overall security and stability of the server.

Possible security problems are:

  1. Vulnerability to denial-of-service attacks: Not caught exceptions can leave the servlet container in an unstable state, which can exhaust the available resources and make the system unavailable in the worst cases.

  2. Exposure of sensitive information: Exceptions handled by the servlet container, by default, expose detailed error messages or debugging information to the user, which may contain sensitive data such as stack traces, database connection, or system configuration.

Unfortunately, servlet method signatures do not force developers to handle IOException and ServletException:

```java Bad theme={"system"} public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { } ``` ```java Fix theme={"system"} public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { InetAddress addr = InetAddress.getByName(request.getRemoteAddr()); // Noncompliant //... } ```

The purpose of Java packages is to give structure to your project. A structure helps to mentally break down a project into smaller parts, simplifying readers' understanding of how components are connected and how they interact.

By convention, the source files' directory structure should replicate the project’s package structure. This is for the following reasons:

  1. The mapping between the package name and the location of the source file of a class is straightforward. That is, the path to the source file is easier to find for a given fully qualified class name.

  2. If two different structures are applied to the same project - one to the packages but another to the source file directories - this confuses developers while not providing any benefit.

  3. The directory structure of the class files generated by the compiler will match the package structure, no matter the source file’s directory. It would not make sense to have one directory structure for the generated class files but a different one for the associated source files.

Similarly, a source directory should not have the character . in its name, as this would make it impossible to match the directory to the package structure.

```java Bad theme={"system"} // file: src/main/foo/Fubar.java package com.foo.bar; class Fubar { } ``` ```java Fix theme={"system"} // file: src/main/com/foo/bar/Fubar.java package com.foo.bar; class Fubar { } ```

The Spring Framework provides several specializations of the generic @Component stereotype annotation which better express the programmer’s intent. Using them should be preferred.

```java Bad theme={"system"} @Component // Noncompliant; class name suggests it's a @Service public class CustomerServiceImpl { // ... } @Component // Noncompliant; class name suggests it's a @Repository public class ProductRepository { // ... } @Component // Noncompliant; class name suggests it's a @Controller or @RestController public class FooBarRestController { // ... } ``` ```java Fix theme={"system"} @Service // Compliant public class CustomerServiceImpl { // ... } @Repository // Compliant public class ProductRepository { // ... } @RestController // Compliant public class FooBarRestController { // ... } @Component // Compliant public class SomeOtherComponent { // ... } ```

Using compound operators as well as increments and decrements (and toggling, in the case of booleans) on primitive fields are not atomic operations. That is, they don’t happen in a single step. For instance, when a volatile primitive field is incremented or decremented you run the risk of data loss if threads interleave in the steps of the update. Instead, use a guaranteed-atomic class such as AtomicInteger, or synchronize the access.

```java Bad theme={"system"} private volatile int count = 0; private volatile boolean boo = false; public void incrementCount() { count++; // Noncompliant } public void toggleBoo(){ boo = !boo; // Noncompliant } ``` ```java Fix theme={"system"} private AtomicInteger count = 0; private boolean boo = false; public void incrementCount() { count.incrementAndGet(); } public synchronized void toggleBoo() { boo = !boo; } ```

\`Throwable is the superclass of all errors and exceptions in Java. Error is the superclass of all errors, which are not meant to be caught by applications.

Catching either Throwable or Error will also catch OutOfMemoryError and InternalError\`, from which an application should not attempt to recover.

```java Bad theme={"system"} try { /* ... */ } catch (Throwable t) { /* ... */ } try { /* ... */ } catch (Error e) { /* ... */ } ``` ```java Fix theme={"system"} try { /* ... */ } catch (RuntimeException e) { /* ... */ } try { /* ... */ } catch (MyException e) { /* ... */ } ```

A org.assertj.core.configuration.Configuration will be effective only once you call Configuration.apply() or Configuration.applyAndDisplay().

This rule raises an issue when configurations are set without the appropriate call to apply them.

```java Bad theme={"system"} Configuration configuration = new Configuration(); // Noncompliant, this configuration will not be applied. configuration.setComparingPrivateFields(true); ``` ```java Fix theme={"system"} Configuration configuration = new Configuration(); configuration.setComparingPrivateFields(true); configuration.applyAndDisplay(); // Alternatively: configuration.apply(); ```

When a class has all final fields, the compiler ensures that the object’s state remains constant. It also enforces a clear design intent of immutability, making the class easier to reason about and use correctly.

Exceptions are meant to represent the application’s state at the point at which an error occurred. Making all fields in an Exception class final ensures that these class fields do not change after initialization.

```java Bad theme={"system"} public class MyException extends Exception { private int status; // Noncompliant public MyException(String message) { super(message); } public int getStatus() { return status; } public void setStatus(int status) { this.status = status; } } ``` ```java Fix theme={"system"} public class MyException extends Exception { private final int status; // Compliant public MyException(String message, int status) { super(message); this.status = status; } public int getStatus() { return status; } } ```

In the Java object lifecycle, the finalize method for an instance is called after the garbage collector has determined that the instance can be removed from the object heap. Therefore, it is unnecessary to implement a finalizer to set instance fields explicitly to null to tell the garbage collector that the instance no longer needs them.

In the worst case, implementing finalize is even counterproductive because it might accidentally create new references from other (living) objects on the heap to the collectible instance, thus, reviving it.

Important note about finalizers:

There are no guarantees when the Java Runtime will call the finalize method or whether it will be called at all.

Using finalizers is, therefore, a bad practice. They should never be used to free resources, such as closing streams, freeing locks, or freeing native system resources. Consider other freeing mechanisms instead, such as an explicit close, unlock, or free method in your class.

```java Bad theme={"system"} public class Foo { private String name; @Override void finalize() { name = null; // Noncompliant, instance will be removed anyway } } ``` ```java Fix theme={"system"} public class Foo { // Compliant private String name; } ```

The ZonedDateTime is an immutable representation of a date-time with a time-zone, introduced in Java 8. This class stores all date and time fields, to a precision of nanoseconds, and a time zone, with a zone offset used to handle ambiguous local date times.

Date truncation to a specific time unit means setting the values up to the specific time unit to zero while keeping the values of the larger time units unchanged.

The ZonedDateTime class provides a truncatedTo method that allows truncating the date in a significantly faster way than the DateUtils class from Commons Lang.

Note that this rule is automatically disabled when the project’s sonar.java.source is lower than 8.

```java Bad theme={"system"} public Date trunc(Date date) { return DateUtils.truncate(date, Calendar.SECOND); // Noncompliant } ``` ```java Fix theme={"system"} public Date trunc(Date date) { Instant instant = date.toInstant(); ZonedDateTime zonedDateTime = instant.atZone(ZoneId.systemDefault()); ZonedDateTime truncatedZonedDateTime = zonedDateTime.truncatedTo(ChronoUnit.SECONDS); Instant truncatedInstant = truncatedZonedDateTime.toInstant(); return Date.from(truncatedInstant); } ```

Passing a collection as an argument to the collection’s own method is either an error - some other argument was intended - or simply nonsensical code.

Further, because some methods require that the argument remain unmodified during the execution, passing a collection to itself can result in undefined behavior.

```java Bad theme={"system"} List objs = new ArrayList(); objs.add("Hello"); objs.add(objs); // Noncompliant; StackOverflowException if objs.hashCode() called objs.addAll(objs); // Noncompliant; behavior undefined objs.containsAll(objs); // Noncompliant; always true objs.removeAll(objs); // Noncompliant; confusing. Use clear() instead objs.retainAll(objs); // Noncompliant; NOOP ``` ```java Fix theme={"system"} ```

Developers may want to add some logic to handle deserialized objects before they are returned to the caller. This can be achieved by implementing the readResolve method.

Non-final classes implementing readResolve should not set its visibility to private as this would make it unavailable to child classes. Instead, mark readResolve as protected, allowing it to be inherited.

```java Bad theme={"system"} public class Fruit implements Serializable { private static final long serialVersionUID = 1; private Object readResolve() throws ObjectStreamException // Noncompliant, `readResolve` should not be private {...} //... } public class Raspberry extends Fruit implements Serializable { // This class has no access to the parent's "readResolve" method //... } ``` ```java Fix theme={"system"} public class Fruit implements Serializable { private static final long serialVersionUID = 1; protected Object readResolve() throws ObjectStreamException // Compliant, `readResolve` is protected {...} //... } public class Raspberry extends Fruit implements Serializable { // This class has access to the parent's "readResolve" //... } ```

Generating random floating point values to cast them into integers is inefficient. A random bounded integer value can be generated with a single proper method call. Use nextInt to make the code more efficient and the intent clearer.

```java Bad theme={"system"} Random r = new Random(); int rand = (int) (r.nextDouble() * 50); // Noncompliant way to get a pseudo-random value between 0 and 50 int rand2 = (int) r.nextFloat(); // Noncompliant; will always be 0; ``` ```java Fix theme={"system"} Random r = new Random(); int rand = r.nextInt(50); // returns pseudo-random value between 0 and 50 int rand2 = 0; ```

Concurrent maps are used for thread-safety, but the use of such maps alone does not ensure thread-safety; they must also be used in a thread-safe manner. Specifically, retrieving a key’s value from a map, and then using \`put to add a map element if the value is null is not performed in an atomic manner. Here’s what can happen

Thread1 cmap.get("key") => null
        Thread2 cmap.get("key") => null
        Thread1 cmap.put("key", new Value())
        Thread2 cmap.put("key", new Value())

Note that this example is written as though the threads take turns performing operations, but that’s not necessarily the case.

Instead of put, putIfAbsent\` should be used.

```java Bad theme={"system"} private static final ConcurrentMap cmap = new ConcurrentHashMap(); public void populateMyClass(String key, String mcProp) { MyClass mc = cmap.get(key); if (mc == null) { mc = new MyClass(); cmap.put(key, mc); // Noncompliant } mc.setProp(mcProp); // could be futile since mc may have been replaced in another thread! } ``` ```java Fix theme={"system"} private static final ConcurrentMap cmap = new ConcurrentHashMap(); public void populateMyClass(String key, String mcProp) { MyClass mc = cmap.get(key); if (mc == null) { mc = new MyClass(); cmap.putIfAbsent(key, mc); mc = cmap.get(key); // re-retrieve value since another thread could have beaten this one to the "put" } mc.setProp(mcProp); } ```

Dynamically loaded classes could contain malicious code executed by a static class initializer. I.E. you wouldn’t even have to instantiate or explicitly invoke methods on such classes to be vulnerable to an attack.

This rule raises an issue for each use of dynamic class loading.

```java Bad theme={"system"} String className = System.getProperty("messageClassName"); Class clazz = Class.forName(className); // Noncompliant ``` ```java Fix theme={"system"} ```

For arrays of objects, Arrays.asList(T ... a).stream() and Arrays.stream(array) are basically equivalent in terms of performance. However, for arrays of primitives, using Arrays.asList will force the construction of a list of boxed types, and then use that list as a stream. On the other hand, Arrays.stream uses the appropriate primitive stream type (IntStream, LongStream, DoubleStream) when applicable, with much better performance.

```java Bad theme={"system"} Arrays.asList("a1", "a2", "b1", "c2", "c1").stream() .filter(...) .forEach(...); Arrays.asList(1, 2, 3, 4).stream() // Noncompliant .filter(...) .forEach(...); ``` ```java Fix theme={"system"} Arrays.asList("a1", "a2", "b1", "c2", "c1").stream() .filter(...) .forEach(...); int[] intArray = new int[]{1, 2, 3, 4}; Arrays.stream(intArray) .filter(...) .forEach(...); ```

If a string fits on a single line, without concatenation and escaped newlines, you should probably continue to use a string literal.

```java Bad theme={"system"} String question = """ What's the point, really?"""; ``` ```java Fix theme={"system"} String question = "What's the point, really?"; ```

You cannot assume that any given stream reading call will fill the \`byte\[] passed in to the method. Instead, you must check the value returned by the read method to see how many bytes were read. Fail to do so, and you introduce bug that is both harmful and difficult to reproduce.

Similarly, you cannot assume that InputStream.skip will actually skip the requested number of bytes, but must check the value returned from the method.

This rule raises an issue when an InputStream.read method that accepts a byte\[] is called, but the return value is not checked, and when the return value of InputStream.skip is not checked. The rule also applies to InputStream\` child classes.

```java Bad theme={"system"} public void doSomething(String fileName) { try { InputStream is = new InputStream(file); byte [] buffer = new byte[1000]; is.read(buffer); // Noncompliant // ... } catch (IOException e) { ... } } ``` ```java Fix theme={"system"} public void doSomething(String fileName) { try { InputStream is = new InputStream(file); byte [] buffer = new byte[1000]; int count = 0; while (count = is.read(buffer) > 0) { // ... } } catch (IOException e) { ... } } ```

Connections, streams, files, and other classes that implement the Closeable interface or its super-interface, AutoCloseable, needs to be closed after use. Further, that close call must be made in a finally block otherwise an exception could keep the call from being made. Preferably, when class implements AutoCloseable, resource should be created using "try-with-resources" pattern and will be closed automatically.

Failure to properly close resources will result in a resource leak which could bring first the application and then perhaps the box the application is on to their knees.

```java Bad theme={"system"} private void readTheFile() throws IOException { Path path = Paths.get(this.fileName); BufferedReader reader = Files.newBufferedReader(path, this.charset); // ... reader.close(); // Noncompliant // ... Files.lines("input.txt").forEach(System.out::println); // Noncompliant: The stream needs to be closed } private void doSomething() { OutputStream stream = null; try { for (String property : propertyList) { stream = new FileOutputStream("myfile.txt"); // Noncompliant // ... } } catch (Exception e) { // ... } finally { stream.close(); // Multiple streams were opened. Only the last is closed. } } ``` ```java Fix theme={"system"} private void readTheFile(String fileName) throws IOException { Path path = Paths.get(fileName); try (BufferedReader reader = Files.newBufferedReader(path, StandardCharsets.UTF_8)) { reader.readLine(); // ... } // .. try (Stream input = Files.lines("input.txt")) { input.forEach(System.out::println); } } private void doSomething() { OutputStream stream = null; try { stream = new FileOutputStream("myfile.txt"); for (String property : propertyList) { // ... } } catch (Exception e) { // ... } finally { stream.close(); } } ``` # Java - 3 Source: https://docs.codeant.ai/antipattern-rules/Java/java3 Learn about Java Anti-Patterns and How they help you write better code, and avoid common pitfalls.

This rule involves the use of Math.abs and negation on numbers that could be MIN\_VALUE. It is a problem because it can lead to incorrect results and unexpected behavior in the program.

When Math.abs and negation are used on numbers that could be MIN\_VALUE, the result can be incorrect due to integer overflow. Common methods that can return a MIN\_VALUE and raise an issue when used together with Math.abs are:

  • Random.nextInt() and Random.nextLong()

  • hashCode()

  • compareTo()

Alternatively, the absExact() method throws an ArithmeticException for MIN\_VALUE.

```java Bad theme={"system"} public void doSomething(String str) { if (Math.abs(str.hashCode()) > 0) { // Noncompliant // ... } } ``` ```java Fix theme={"system"} public void doSomething(String str) { if (str.hashCode() != 0) { // ... } } ```

By definition, primitive types are not Objects and so they can’t be \`null. Adding @CheckForNull or @Nullable on primitive types adds confusion and is useless.

This rule raises an issue when @CheckForNull or @Nullable\` is set on a method returning a primitive type: byte, short, int, long, float, double, boolean, char.

```java Bad theme={"system"} @CheckForNull boolean isFoo() { ... } ``` ```java Fix theme={"system"} boolean isFoo() { ... } ```

In Java, the Object.equals() method is used for object comparison, and it is typically overridden in classes to provide a custom equality check based on your criteria for equality.

The default implementation of equals() provided by the Object class compares the memory references of the two objects, that means it checks if the objects are actually the same instance in memory.

The "equals" as a method name should be used exclusively to override Object.equals(Object) to prevent confusion.

It is important to note that when you override equals(), you should also override the hashCode() method to maintain the contract between equals() and hashCode().

```java Bad theme={"system"} class MyClass { private int foo = 1; public boolean equals(MyClass o) { // Noncompliant; does not override Object.equals(Object) return o != null && o.foo == this.foo; } public static void main(String[] args) { MyClass o1 = new MyClass(); Object o2 = new MyClass(); System.out.println(o1.equals(o2)); // Prints "false" because o2 an Object not a MyClass } } ``` ```java Fix theme={"system"} class MyClass { private int foo = 1; @Override public boolean equals(Object o) { // Compliant if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } MyClass other = (MyClass)o; return this.foo == other.foo; } } ```

According to the documentation,

A program may produce unpredictable results if it attempts to distinguish two references to equal values of a value-based class, whether directly via reference equality or indirectly via an appeal to synchronization, identity hashing, serialization…​

For example (credit to Brian Goetz), imagine Foo is a value-based class:

Foo\[] arr = new Foo\[2];
        arr\[0] = new Foo(0);
        arr\[1] = new Foo(0);

Serialization promises that on deserialization of arr, elements 0 and 1 will not be aliased. Similarly, in:

Foo\[] arr = new Foo\[2];
        arr\[0] = new Foo(0);
        arr\[1] = arr\[0];

Serialization promises that on deserialization of \`arr, elements 0 and 1 will be aliased.

While these promises are coincidentally fulfilled in current implementations of Java, that is not guaranteed in the future, particularly when true value types are introduced in the language.

This rule raises an issue when a Serializable class defines a non-transient, non-static field field whose type is a known serializable value-based class. Known serializable value-based classes are: all the classes in the java.time package except Clock; the date classes for alternate calendars: HijrahDate, JapaneseDate, MinguoDate, ThaiBuddhistDate\`.

```java Bad theme={"system"} class MyClass implements Serializable { private HijrahDate date; // Noncompliant; mark this transient // ... } ``` ```java Fix theme={"system"} class MyClass implements Serializable { private transient HijrahDate date; // ... } ```

"Boxing" is the process of putting a primitive value into a primitive-wrapper object. When that’s done purely to use the wrapper class' toString method, it’s a waste of memory and cycles because those methods are static, and can therefore be used without a class instance. Similarly, using the static method valueOf in the primitive-wrapper classes with a non-String argument should be avoided.

```java Bad theme={"system"} int myInt = 4; String myIntString = (new Integer(myInt)).toString(); // Noncompliant; creates & discards an Integer object myIntString = Integer.valueOf(myInt).toString(); // Noncompliant ``` ```java Fix theme={"system"} int myInt = 4; String myIntString = Integer.toString(myInt); ```

The \`Class.isInstance method is the dynamic equivalent of the instanceof operator. According to the JavaDoc, isInstance

returns true if the specified Object argument is an instance of the represented class (or of any of its subclasses); it returns false otherwise

Thus, calling isInstance with a class argument is likely a mistake, since any random Class will only be "an instance of the represented class" when the left-hand side of the call is Class.class itself. To test for a class/sub-class relationship, use isAssignableFrom\` instead.

```java Bad theme={"system"} Class num = Number.class; Class bi = BigInteger.class; System.out.println(num.isInstance(bi)); // Noncompliant. false System.out.println(bi.isInstance(Class.class)); // Noncompliant. false System.out.println(Class.class.isInstance(bi)); // Noncompliant. true ``` ```java Fix theme={"system"} Class num = Number.class; Class bi = BigInteger.class; System.out.println(num.isAssignableFrom(bi)); // true System.out.println(bi.isAssignableFrom(Class.class)); // false System.out.println(Class.class.isAssignableFrom(bi)); // false ```

The String class has a toString method because Object itself does. I.e. it couldn’t not have the method. But having the method doesn’t mean it should be used. In fact doing so is worse than pointless since it returns the String itself.

```java Bad theme={"system"} String str1 = "Now is the time for all good people"; String str2 = str1.toString(); ``` ```java Fix theme={"system"} String str1 = "Now is the time for all good people"; String str2 = str1; ```

Singletons that aren’t actually singletons become problems instead. To make sure a singleton isn’t instantiable, make sure all constructors are \`private. If the singleton doesn’t have any constructors then add a private no-args constructor to override the default constructor.

This rule raises an issue when a class that holds a public static final instance of itself has non-private\` constructors or no constructor.

```java Bad theme={"system"} public class Highlander implements Immortal { // Noncompliant; no constructor; default, public constructor generated public static final Highlander INSTANCE = new Highlander(); public void eliminateRival(Immortal immortal) { // ... } } public class Kurgan implements Immortal { public static final Kurgan INSTANCE = new Kurgan(); Kurgan() { // Noncompliant; should be private } public void eliminateRival(Immortal immortal) { // ... } } ``` ```java Fix theme={"system"} public class Highlander implements Immortal { public static final Highlander INSTANCE = new Highlander; private Highlander() { } public void eliminateRival(Immortal immortal) { // ... } } public class Kurgan implements Immortal { public static final Kurgan INSTANCE = new Kurgan; private Kurgan() { } public void eliminateRival(Immortal immortal) { // ... } } ```

A key facet of the \`equals contract is that if a.equals(b) then b.equals(a), i.e. that the relationship is symmetric.

Using instanceof breaks the contract when there are subclasses, because while the child is an instanceof the parent, the parent is not an instanceof the child. For instance, assume that Raspberry extends Fruit and adds some fields (requiring a new implementation of equals):

          Fruit fruit = new Fruit();
          Raspberry raspberry = new Raspberry();

          if (raspberry instanceof Fruit) \{ ... } // true
          if (fruit instanceof Raspberry) \{ ... } // false
        

If similar instanceof checks were used in the classes' equals methods, the symmetry principle would be broken:

raspberry.equals(fruit); // false
        fruit.equals(raspberry); //true

Additionally, non final classes shouldn’t use a hardcoded class name in the equals method because doing so breaks the method for subclasses. Instead, make the comparison dynamic.

Further, comparing to an unrelated class type breaks the contract for that unrelated type, because while thisClass.equals(unrelatedClass) can return true, unrelatedClass.equals(thisClass)\` will not.

```java Bad theme={"system"} public class Fruit extends Food { private Season ripe; public boolean equals(Object obj) { if (obj == this) { return true; } if (obj == null) { return false; } if (Fruit.class == obj.getClass()) { // Noncompliant; broken for child classes return ripe.equals(((Fruit)obj).getRipe()); } if (obj instanceof Fruit ) { // Noncompliant; broken for child classes return ripe.equals(((Fruit)obj).getRipe()); } else if (obj instanceof Season) { // Noncompliant; symmetry broken for Season class // ... } //... ``` ```java Fix theme={"system"} public class Fruit extends Food { private Season ripe; public boolean equals(Object obj) { if (obj == this) { return true; } if (obj == null) { return false; } if (this.getClass() == obj.getClass()) { return ripe.equals(((Fruit)obj).getRipe()); } return false; } ```

Map computeIfAbsent and computeIfPresent methods are convenient to avoid the cumbersome process to check if a key exists or not, followed by the addition of the entry. However, when the function used to compute the value returns \`null, the entry key->null will not be added to the Map. Furthermore, in the case of computeIfPresent, if the key is present the entry will be removed. These methods should therefore not be used to conditionally add an entry with a null value. The traditional way should be used instead.

This rule raises an issue when computeIfAbsent or computeIfPresent\` is used with a lambda always returning null.

```java Bad theme={"system"} map.computeIfAbsent(key, k -> null); // Noncompliant, the map will not contain an entry key->null. map.computeIfPresent(key, (k, oldValue) -> null); // Noncompliant ``` ```java Fix theme={"system"} if (!map.containsKey(key)) { map.put(key, null); } if (map.containsKey(key)) { map.put(key, null); } ```

Before Java 8, the only way to partially support closures in Java was by using anonymous inner classes. Java 8 introduced lambdas, which are significantly more readable and should be used instead.

This rule is automatically disabled when the project’s sonar.java.source is lower than 8, as lambda expressions were introduced in Java 8.

```java Bad theme={"system"} myCollection.stream().map(new Function() { // Noncompliant, use a lambda expression instead @Override public String apply(String input) { return new StringBuilder(input).reverse().toString(); } }) ... ``` ```java Fix theme={"system"} myCollection.stream() .map(input -> new StringBuilder(input).reverse().toString()) // Compliant ... ```

If the region is not specified when creating a new AwsClient with an AwsClientBuilder, the AWS SDK will execute some logic to identify the endpoint automatically.

While it will probably identify the correct one, this extra logic will slow down startup time, already known to be a hotspot.

You should therefore always define the logic to set the region yourself. This is typically done by retrieving the region from the Lambda provided AWS\_REGION environment variable.

This will make the code more explicit and spare initialization time.

This rule reports an issue when the region is not set when creating an AwsClient.

```java Bad theme={"system"} S3Client.builder() .credentialsProvider(EnvironmentVariableCredentialsProvider.create()) .build(); ``` ```java Fix theme={"system"} S3Client.builder() .region(Region.of(System.getenv(SdkSystemSetting.AWS_REGION.environmentVariable())) .credentialsProvider(EnvironmentVariableCredentialsProvider.create()) .build(); ```

Because Object implements hashCode, any Java class can be put into a hash structure. However, classes that define equals(Object) but not hashCode() aren’t truly hash-able because instances that are equivalent according to the equals method can return different hashes.

```java Bad theme={"system"} public class Student { // no hashCode() method; not hash-able // ... public boolean equals(Object o) { // ... } } public class School { private Map studentBody = // okay so far new HashTable(); // Noncompliant // ... ``` ```java Fix theme={"system"} public class Student { // has hashCode() method; hash-able // ... public boolean equals(Object o) { // ... } public int hashCode() { // ... } } public class School { private Map studentBody = new HashTable(); // ... ```

Java serialization is the conversion from objects to byte streams for storage or transmission. And later, java deserialization is the reverse conversion, it reconstructs objects from byte streams.

To make a java class serializable, this class should implement the java.io.Serializable interface directly or through its inheritance.

```java Bad theme={"system"} import java.io.Serializable; public class NonSerializableClass { } public class SerializableClass implements Serializable { } public class OtherSerializableClass extends SerializableClass { // is also serializable because it is a subtype of Serializable } ``` ```java Fix theme={"system"} public class NonSerializableClassWithoutConstructor { // after deserialization, "field1" will always be set to 42 private int field1 = 42; // this non-serializable class has an implicit no-argument constructor } public class NonSerializableClass extends NonSerializableClassWithoutConstructor { // after deserialization, "field2" will always be set to 12 by the no-argument constructor private int field2; // this non-serializable class has an explicit no-argument constructor public NonSerializableClass() { field2 = 12; } public NonSerializableClass(int field2) { this.field2 = field2; } } public class SerializableClass extends NonSerializableClass implements Serializable { // after deserialization, "field3" will have the previously serialized value. private int field3; // deserialization does not use declared constructors public SerializableClass(int field3) { super(field3 * 2); this.field3 = field3; } } ```

Failure to specify a locale when calling the methods \`toLowerCase(), toUpperCase() or format() on String objects means the system default encoding will be used, possibly creating problems with international characters or number representations. For instance with the Turkish language, when converting the small letter 'i' to upper case, the result is capital letter 'I' with a dot over it.

Case conversion without a locale may work fine in its "home" environment, but break in ways that are extremely difficult to diagnose for customers who use different encodings. Such bugs can be nearly, if not completely, impossible to reproduce when it’s time to fix them. For locale-sensitive strings, the correct locale should always be used, but Locale.ROOT\` can be used for case-insensitive ones.

```java Bad theme={"system"} myString.toLowerCase() ``` ```java Fix theme={"system"} myString.toLowerCase(Locale.TR) ```

If all the keys in a Map are values from a single enum, it is recommended to use an EnumMap as the specific implementation. An EnumMap, which has the advantage of knowing all possible keys in advance, is more efficient compared to other implementations, as it can use a simple array as its underlying data structure.

```java Bad theme={"system"} public enum Color { RED, GREEN, BLUE, ORANGE; } Map colorMap = new HashMap<>(); // Noncompliant ``` ```java Fix theme={"system"} public enum Color { RED, GREEN, BLUE, ORANGE; } Map colorMap = new EnumMap<>(Color.class); // Compliant ```

The implementation of certain \`ResultSet methods is optional for result sets of type TYPE\_FORWARD\_ONLY. Even if your current JDBC driver does implement those methods, there’s no guarantee you won’t change drivers in the future.

This rule looks for invocations of the following methods on TYPE\_FORWARD\_ONLY ResultSets:

  • isBeforeFirst

  • isAfterLast

  • isFirst

  • getRow\`

```java Bad theme={"system"} Statement stmt = con.createStatement(ResultSet.TYPE_FORWARD_ONLY); stmt.executeQuery("SELECT name, address FROM PERSON"); ResultSet rs = stmt.getResultSet(); if (rs.isBeforeFirst()) { // Noncompliant } ``` ```java Fix theme={"system"} ```

Return of boolean literal statements wrapped into \`if-then-else ones should be simplified.

Similarly, method invocations wrapped into if-then-else\` differing only from boolean literals should be simplified into a single invocation.

```java Bad theme={"system"} boolean foo(Object param) { if (expression) { // Noncompliant bar(param, true, "qix"); } else { bar(param, false, "qix"); } if (expression) { // Noncompliant return true; } else { return false; } } ``` ```java Fix theme={"system"} boolean foo(Object param) { bar(param, expression, "qix"); return expression; } ```

While not mandatory, using the @Override annotation on compliant methods improves readability by making it explicit that methods are overriden.

A compliant method either overrides a parent method or implements an interface or abstract method.

```java Bad theme={"system"} class ParentClass { public boolean doSomething(){/*...*/} } class FirstChildClass extends ParentClass { public boolean doSomething(){/*...*/} // Noncompliant } ``` ```java Fix theme={"system"} class ParentClass { public boolean doSomething(){/*...*/} } class FirstChildClass extends ParentClass { @Override public boolean doSomething(){/*...*/} // Compliant } ```

Since an int is a 32-bit variable, shifting by more than +/-31 is confusing at best and an error at worst. When the runtime shifts 32-bit integers, it uses the lowest 5 bits of the shift count operand. In other words, shifting an int by 32 is the same as shifting it by 0, and shifting it by 33 is the same as shifting it by 1.

Similarly, when shifting 64-bit integers, the runtime uses the lowest 6 bits of the shift count operand and shifting long by 64 is the same as shifting it by 0, and shifting it by 65 is the same as shifting it by 1.

```java Bad theme={"system"} public int shift(int a) { int x = a >> 32; // Noncompliant return a << 48; // Noncompliant } ``` ```java Fix theme={"system"} public int shift(int a) { int x = a >> 31; return a << 16; } ```

Whenever a virtual thread is started, the JVM will mount it on an OS thread. As soon as the virtual thread runs into a blocking operation like an HTTP request or a filesystem read/write operation, the JVM will detect this and unmount the virtual thread. This allows another virtual thread to take over the OS thread and continue its execution.

This is why virtual threads should be preferred to platform threads for tasks that involve blocking operations. By default, a Java thread is a platform thread. To use a virtual thread it must be started either with Thread.startVirtualThread(Runnable) or Thread.ofVirtual().start(Runnable).

This rule raises an issue when a platform thread is created with a task that includes heavy blocking operations.

```java Bad theme={"system"} new Thread(() -> { try { Thread.sleep(1000); // Noncompliant blocking operation in platform thread } catch (InterruptedException e) { throw new RuntimeException(e); } }); ``` ```java Fix theme={"system"} Thread.ofVirtual().start(() -> { try { Thread.sleep(1000); // Compliant } catch (InterruptedException e) { throw new RuntimeException(e); } }); ```

There is no reason to concatenate literal strings. Doing so is an exercise is reducing code readability. Instead, the strings should be combined. Similarly, literal strings should not be appended to a StringBuffer or StringBuilder sequentially, but combined into one call.

```java Bad theme={"system"} String message = "Hello " + "world" + "!"; // Noncompliant StringBuilder sb = new StringBuilder(); sb.append("I'm pleased").append(" to meet you."); //Noncompliant ``` ```java Fix theme={"system"} String message = "Hello world!"; StringBuilder sb = new StringBuilder(); sb.append("I'm pleased to meet you."); ```

In Spring, singleton beans and their dependencies are initialized when the application context is created.

If a Singleton bean depends on a bean with a shorter-lived scope (like Request or Session beans), it retains the same instance of that bean, even when new instances are created for each Request or Session. This mismatch can cause unexpected behavior and bugs, as the Singleton bean doesn’t interact correctly with the new instances of the shorter-lived bean.

This rule raises an issue when non-singleton beans are injected into a singleton bean.

```java Bad theme={"system"} @Component @Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS) public class RequestBean { //... } public class SingletonBean { @Autowired private final RequestBean requestBean; // Noncompliant, the same instance of RequestBean is used for each HTTP request. public RequestBean getRequestBean() { return requestBean; } } ``` ```java Fix theme={"system"} @Component @Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS) public class RequestBean { //... } public class SingletonBean { private final ObjectFactory requestBeanFactory; @Autowired public SingletonBean(ObjectFactory requestBeanFactory) { this.requestBeanFactory = requestBeanFactory; } public RequestBean getRequestBean() { return requestBeanFactory.getObject(); } } ```

Java 21 introduces the new Sequenced Collections API, which is applicable to all collections with a defined sequence on their elements, such as LinkedList, TreeSet, and others (see JEP 431). For projects using Java 21 and onwards, this API should be utilized instead of workaround implementations that were necessary before Java 21.

This rule reports when a collection is iterated in reverse through explicit implementation or workarounds, instead of using the reversed view of the collection.

```java Bad theme={"system"} void printLastToFirst(List list) { for (var it = list.listIterator(list.size()); it.hasPrevious();) { var element = it.previous(); System.out.println(element); } } ``` ```java Fix theme={"system"} void printLastToFirst(List list) { for (var element: list.reversed()) { System.out.println(element); } } ```

The purpose of checked exceptions is to ensure that errors will be dealt with, either by propagating them or by handling them, but some believe that checked exceptions negatively impact the readability of source code, by spreading this error handling/propagation logic everywhere.

This rule verifies that no method throws a new checked exception.

```java Bad theme={"system"} public void myMethod1() throws CheckedException { ... throw new CheckedException(message); // Noncompliant ... throw new IllegalArgumentException(message); // Compliant; IllegalArgumentException is unchecked } public void myMethod2() throws CheckedException { // Compliant; propagation allowed myMethod1(); } ``` ```java Fix theme={"system"} ```

A class that implements java.io.Externalizable is a class that provides a way to customize the serialization and deserialization, allowing greater control over how the object’s state is written or read.

The first step of the deserialization process is to call the class' no-argument constructor before the readExternal(ObjectInput in) method.

An implicit default no-argument constructor exists on a class when no constructor is explicitly defined within the class. But this implicit constructor does not exist when any constructor is explicitly defined, and in this case, we should always ensure that one of the constructors has no-argument.

It is an issue if the implicit or explicit no-argument constructor is missing or not public, because the deserialization will fail and throw an InvalidClassException: no valid constructor..

```java Bad theme={"system"} public class Tomato implements Externalizable { public Color color; // Noncompliant; because of this constructor there is no implicit no-argument constructor, // deserialization will fail public Tomato(Color color) { this.color = color; } @Override public void writeExternal(ObjectOutput out) throws IOException { out.writeUTF(color.name()); } @Override public void readExternal(ObjectInput in) throws IOException { color = Color.valueOf(in.readUTF()); } } ``` ```java Fix theme={"system"} public class Tomato implements Externalizable { public Color color; // Compliant; deserialization will invoke this public no-argument constructor public Tomato() { this.color = Color.UNKNOWN; } public Tomato(Color color) { this.color = color; } @Override public void writeExternal(ObjectOutput out) throws IOException { out.writeUTF(color.name()); } @Override public void readExternal(ObjectInput in) throws IOException { color = Color.valueOf(in.readUTF()); } } ```

Deprecated method should be avoided, rather than overridden. Deprecation is a warning that the method has been superseded, and will eventually be removed. The deprecation period allows you to make a smooth transition away from the aging, soon-to-be-retired technology.

```java Bad theme={"system"} class A { @Deprecated void foo(){} } class B extends A { @Override void foo(){ // Noncompliant } } ``` ```java Fix theme={"system"} ```

In Java 16, the feature "Pattern matching for instanceof" is finalized and can be used in production. Previously developers needed to do 3 operations in order to do this: check the variable type, cast it and assign the casted value to the new variable. This approach is quite verbose and can be replaced with pattern matching for \`instanceof, doing these 3 actions (check, cast and assign) in one expression.

This rule raises an issue when an instanceof\` check followed by a cast and an assignment could be replaced by pattern matching.

```java Bad theme={"system"} int f(Object o) { if (o instanceof String) {  // Noncompliant String string = (String) o; return string.length(); } return 0; } ``` ```java Fix theme={"system"} int f(Object o) {   if (o instanceof String string) {  // Compliant     return string.length();   }   return 0; } ```

Making a \`public constant just final as opposed to static final leads to duplicating its value for every instance of the class, uselessly increasing the amount of memory required to execute the application.

Further, when a non-public, final field isn’t also static, it implies that different instances can have different values. However, initializing a non-static final field in its declaration forces every instance to have the same value. So such fields should either be made static\` or initialized in the constructor.

```java Bad theme={"system"} public class Myclass { public final int THRESHOLD = 3; } ``` ```java Fix theme={"system"} public class Myclass { public static final int THRESHOLD = 3; // Compliant } ```

Strings are immutable objects, so concatenation doesn’t simply add the new String to the end of the existing string. Instead, in each loop iteration, the first String is converted to an intermediate object type, the second string is appended, and then the intermediate object is converted back to a String. Further, performance of these intermediate operations degrades as the String gets longer. Therefore, the use of StringBuilder is preferred.

```java Bad theme={"system"} String str = ""; for (int i = 0; i < arrayOfStrings.length ; ++i) { str = str + arrayOfStrings[i]; } ``` ```java Fix theme={"system"} StringBuilder bld = new StringBuilder(); for (int i = 0; i < arrayOfStrings.length; ++i) { bld.append(arrayOfStrings[i]); } String str = bld.toString(); ```

Using the standard getClassLoader() may not return the right class loader in a JEE context. Instead, go through the currentThread.

```java Bad theme={"system"} ClassLoader cl = this.getClass().getClassLoader(); // Noncompliant ``` ```java Fix theme={"system"} ClassLoader cl = Thread.currentThread().getContextClassLoader(); ```

A generic type is a generic class or interface that is parameterized over types. For example, java.util.List has one type parameter: the type of its elements.

When generic types are used raw (without type parameters), the compiler is not able to do generic type checking. For this reason, it is sometimes necessary to cast objects and defer type-checking to runtime.

```java Bad theme={"system"} List integers = new ArrayList<>(); // It is possible to add a string to a list that is supposed to be integers only integers.add("Hello World!"); Integer a = (Integer) integers.get(0); // ClassCastException! ``` ```java Fix theme={"system"} List integers = new ArrayList<>(); // The program does not compile anymore with this mistake: // integers.add("Hello World!"); integers.add(42); Integer a = integers.get(0); // No need to cast anymore. ```

In a multithreaded environment, a thread may need to wait for a particular condition to become true. One way of pausing execution in Java is Thread.sleep(…​).

If a thread that holds a lock calls Thread.sleep(…​), no other thread can acquire said lock. This can lead to performance and scalability issues, in the worst case leading to deadlocks.

```java Bad theme={"system"} public void doSomething(){ synchronized(monitor) { while(notReady()){ Thread.sleep(200); // Noncompliant, any other thread synchronizing on monitor is blocked from running while the first thread sleeps. } process(); } ... } ``` ```java Fix theme={"system"} public void doSomething(){ synchronized(monitor) { while(notReady()){ monitor.wait(200); // Compliant, the current monitor is released. } process(); } ... } ```

Creating a new Random object each time a random value is needed is inefficient and may produce numbers that are not random, depending on the JDK. For better efficiency and randomness, create a single Random, store it, and reuse it.

The Random() constructor tries to set the seed with a distinct value every time. However, there is no guarantee that the seed will be randomly or uniformly distributed. Some JDK will use the current time as seed, making the generated numbers not random.

This rule finds cases where a new Random is created each time a method is invoked.

```java Bad theme={"system"} class MyClass { public void doSomethingCommon() { Random random = new Random(); // Noncompliant - new instance created with each invocation int rValue = random.nextInt(); } } ``` ```java Fix theme={"system"} class MyClass { private Random random = new Random(); // Compliant public void doSomethingCommon() { int rValue = this.random.nextInt(); } } ```

As mentioned in JUnit5 documentation, it is possible to integrate JUnit4 with JUnit5:

JUnit provides a gentle migration path via a JUnit Vintage test engine which allows existing tests based on JUnit 3 and JUnit 4 to be executed using the JUnit Platform infrastructure. Since all classes and annotations specific to JUnit Jupiter reside under a new org.junit.jupiter base package, having both JUnit 4 and JUnit Jupiter in the classpath does not lead to any conflicts.

However, maintaining both systems is a temporary solution. This rule flags all the annotations from JUnit4 which would need to be migrated to JUnit5, hence helping migration of a project.

Here is the list of JUnit4 annotations tracked by the rule, with their corresponding annotations in JUnit5:

JUnit4 JUnit5

\`org.junit.Test

org.junit.jupiter.api.Test

org.junit.Before

org.junit.jupiter.api.BeforeEach

org.junit.After

org.junit.jupiter.api.AfterEach

org.junit.BeforeClass

org.junit.jupiter.api.BeforeAll

org.junit.AfterClass

org.junit.jupiter.api.AfterAll

org.junit.Ignore

org.junit.jupiter.api.Disabled

Note that the following annotations might requires some rework of the tests to have JUnit5 equivalent behavior. A simple replacement of the annotation won’t work immediately:

JUnit4 JUnit5

org.junit.experimental.categories.Category

org.junit.jupiter.api.Tag

org.junit.Rule

org.junit.jupiter.api.extension.ExtendWith

org.junit.ClassRule

org.junit.jupiter.api.extension.RegisterExtension

org.junit.runner.RunWith

org.junit.jupiter.api.extension.ExtendWith\`

```java Bad theme={"system"} package org.foo; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Ignore; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; @RunWith(MyJUnit4Runner.class) public class MyJUnit4Test { @BeforeClass public static void beforeAll() { System.out.println("beforeAll"); } @AfterClass public static void afterAll() { System.out.println("AfterAll"); } @Before public void beforeEach() { System.out.println("beforeEach"); } @After public void afterEach() { System.out.println("afterEach"); } @Test public void test1() throws Exception { System.out.println("test1"); } public interface SomeTests { /* category marker */ } @Test @Category(SomeTests.class) public void test2() throws Exception { System.out.println("test2"); } @Test @Ignore("Requires fix of #42") public void ignored() throws Exception { System.out.println("ignored"); } } ``` ```java Fix theme={"system"} package org.foo; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @ExtendWith(MyJUnit5Extension.class) class MyJUnit5Test { @BeforeAll static void beforeAll() { System.out.println("beforeAll"); } @AfterAll static void afterAll() { System.out.println("afterAll"); } @BeforeEach void beforeEach() { System.out.println("beforeEach"); } @AfterEach void afterEach() { System.out.println("afterEach"); } @Test void test1() { System.out.println("test1"); } @Test @Tag("SomeTests") void test2() { System.out.println("test2"); } @Test @Disabled("Requires fix of #42") void disabled() { System.out.println("ignored"); } } ```

Field injection seems like a tidy way to get your classes what they need to do their jobs, but it’s really a \`NullPointerException waiting to happen unless all your class constructors are private. That’s because any class instances that are constructed by callers, rather than instantiated by a Dependency Injection framework compliant with the JSR-330 (Spring, Guice, …​), won’t have the ability to perform the field injection.

Instead @Inject should be moved to the constructor and the fields required as constructor parameters.

This rule raises an issue when classes with non-private\` constructors (including the default constructor) use field injection.

```java Bad theme={"system"} class MyComponent { // Anyone can call the default constructor @Inject MyCollaborator collaborator; // Noncompliant public void myBusinessMethod() { collaborator.doSomething(); // this will fail in classes new-ed by a caller } } ``` ```java Fix theme={"system"} class MyComponent { private final MyCollaborator collaborator; @Inject public MyComponent(MyCollaborator collaborator) { Assert.notNull(collaborator, "MyCollaborator must not be null!"); this.collaborator = collaborator; } public void myBusinessMethod() { collaborator.doSomething(); } } ```

Either use only spaces or only tabs for the indentation of a text block. Mixing white space will lead to a result with irregular indentation.

```java Bad theme={"system"} String textBlock = """ this is text block! !!!! """; ``` ```java Fix theme={"system"} String textBlock = """ this is text block! !!!! """; ```

With Java 8’s "default method" feature, any abstract class without direct or inherited field should be converted into an interface. However, this change may not be appropriate in libraries or other applications where the class is intended to be used as an API.

Note that this rule is automatically disabled when the project’s sonar.java.source is lower than 8.

```java Bad theme={"system"} public abstract class Car { public abstract void start(Environment c); public void stop(Environment c) { c.freeze(this); } } ``` ```java Fix theme={"system"} public interface Car { public void start(Environment c); public default void stop(Environment c) { c.freeze(this); } } ```

Rather than creating a boxed primitive from a String to extract the primitive value, use the relevant parse method instead. Using parse makes the code more efficient and the intent of the developer clearer.

```java Bad theme={"system"} String myNum = "42.0"; float myFloat = new Float(myNum); // Noncompliant float myFloatValue = (new Float(myNum)).floatValue(); // Noncompliant int myInteger = Integer.valueOf(myNum); // Noncompliant int myIntegerValue = Integer.valueOf(myNum).intValue(); // Noncompliant ``` ```java Fix theme={"system"} String myNum = "42.0"; float f = Float.parseFloat(myNum); int myInteger = Integer.parseInt(myNum); ```

In general, altering or bypassing the accessibility of classes, methods, or fields violates the encapsulation principle and could lead to runtime errors. For records the case is even trickier: you cannot change the visibility of records’s fields and trying to update the existing value will lead to IllegalAccessException at runtime.

This rule raises an issue when reflection is used to change the visibility of a record’s field, and when it is used to directly update a record’s field value.

```java Bad theme={"system"} record Person(String name, int age) {} Person person = new Person("A", 26); Field field = Person.class.getDeclaredField("name"); field.setAccessible(true); // secondary field.set(person, "B"); // Noncompliant ``` ```java Fix theme={"system"} ```

When a class overrides Object.equals, this indicates that the class not just considers object identity as equal (the default implementation of Object.equals) but implements another logic for what is considered equal in the context of this class. Usually (but not necessarily), the semantics of equals in this case is that two objects are equal when their state is equal field by field.

Because of this, adding new fields to a subclass of a class that overrides Object.equals but not updating the implementation of equals in the subclass is most likely an error.

```java Bad theme={"system"} class Foo { final int a; @Override public boolean equals(Object other) { if (other == null) return false; if (getClass() != other.getClass()) return false; return a == ((Foo) other).a; } } ``` ```java Fix theme={"system"} class Bar extends Foo { // Noncompliant, `equals` ignores the value of `b` final int b; } ```

Due to the similar name with the methods Object.toString, Object.hashCode and Object.equals, there is a significant likelihood that a developer intended to override one of these methods but made a spelling error.

Even if no such error exists and the naming was done on purpose, these method names can be misleading. Readers might not notice the difference, or if they do, they may falsely assume that the developer made a mistake.

```java Bad theme={"system"} public int hashcode() { /* ... */ } // Noncompliant public String tostring() { /* ... */ } // Noncompliant public boolean equal(Object obj) { /* ... */ } // Noncompliant ``` ```java Fix theme={"system"} @Override public int hashCode() { /* ... */ } // Compliant @Override public String toString() { /* ... */ } // Compliant @Override public boolean equals(Object obj) { /* ... */ } // Compliant ```

Dependency injection frameworks such as Spring support dependency injection by using annotations such as @Inject and @Autowired. These annotations can be used to inject beans via constructor, setter, and field injection.

Generally speaking, field injection is discouraged. It allows the creation of objects in an invalid state and makes testing more difficult. The dependencies are not explicit when instantiating a class that uses field injection.

In addition, field injection is not compatible with final fields. Keeping dependencies immutable where possible makes the code easier to understand, easing development and maintenance.

Finally, because values are injected into fields after the object has been constructed, they cannot be used to initialize other non-injected fields inline.

This rule raises an issue when the @Autowired or @Inject annotations are used on a field.

```java Bad theme={"system"} public class SomeService { @Autowired private SomeDependency someDependency; // Noncompliant private String name = someDependency.getName(); // Will throw a NullPointerException } ``` ```java Fix theme={"system"} public class SomeService { private final SomeDependency someDependency; private final String name; @Autowired public SomeService(SomeDependency someDependency) { this.someDependency = someDependency; name = someDependency.getName(); } } ```

JUnit5 is more tolerant regarding the visibility of test classes and methods than JUnit4, which required everything to be public. Test classes and methods can have any visibility except private. It is however recommended to use the default package visibility to improve readability.

Test classes, test methods, and lifecycle methods are not required to be public, but they must not be private.

It is generally recommended to omit the public modifier for test classes, test methods, and lifecycle methods unless there is a technical reason for doing so – for example, when a test class is extended by a test class in another package. Another technical reason for making classes and methods public is to simplify testing on the module path when using the Java Module System.

— JUnit5 User Guide
```java Bad theme={"system"} import org.junit.jupiter.api.Test; public class MyClassTest { // Noncompliant - modifier can be removed @Test protected void test() { // Noncompliant - modifier can be removed // ... } } ``` ```java Fix theme={"system"} import org.junit.jupiter.api.Test; class MyClassTest { @Test void test() { // ... } } ```

A method annotated with Spring’s @Async or @Transactional annotations will not work as expected if invoked directly from within its class.

This is because Spring generates a proxy class with wrapper code to manage the method’s asynchronicity (@Async) or to handle the transaction (@Transactional). However, when called using this, the proxy instance is bypassed, and the method is invoked directly without the required wrapper code.

```java Bad theme={"system"} @Service public class AsyncNotificationProcessor implements NotificationProcessor { @Override public void process(Notification notification) { processAsync(notification); // Noncompliant, call bypasses proxy } @Async public processAsync(Notification notification) { // ... } } ``` ```java Fix theme={"system"} @Service public class AsyncNotificationProcessor implements NotificationProcessor { @Resource private AsyncNotificationProcessor @Override public void process(Notification notification) { asyncNotificationProcessor.processAsync(notification); // Compliant, call via injected proxy } @Async public processAsync(Notification notification) { // ... } } ```

An infinite loop will never end while the program runs, meaning you have to kill the program to get out of the loop. Every loop should have an end condition, whether by meeting the loop’s termination condition or via a break statement.

```java Bad theme={"system"} for (;;) { // Noncompliant; end condition omitted // ... } ``` ```java Fix theme={"system"} int j; while (true) { // Noncompliant; end condition omitted j++; } ```

In Spring Framework, the @Qualifier annotation is typically used to disambiguate between multiple beans of the same type when auto-wiring dependencies. It is not necessary to use @Qualifier when defining a bean using the @Bean annotation because the bean’s name can be explicitly specified using the name attribute or derived from the method name. Using @Qualifier on @Bean methods can lead to confusion and redundancy. Beans should be named appropriately using either the name attribute of the @Bean annotation or the method name itself.

```java Bad theme={"system"} @Configuration public class MyConfiguration { @Bean @Qualifier("myService") public MyService myService() { // ... return new MyService(); } @Bean @Qualifier("betterService") public MyService aBetterService() { // ... return new MyService(); } @Bean @Qualifier("evenBetterService") public MyService anEvenBetterService() { // ... return new MyService(); } @Bean @Qualifier("differentService") public MyBean aDifferentService() { // ... return new MyBean(); } } ``` ```java Fix theme={"system"} @Configuration public class MyConfiguration { @Bean public MyService myService() { // ... return new MyService(); } @Bean(name="betterService") public MyService aBetterService() { // ... return new MyService(); } @Bean(name="evenBetterService") public MyService anEvenBetterService() { // ... return new MyService(); } @Bean(name="differentService") public MyBean aDifferentService() { // ... return new MyBean(); } } ```

Maps use hashes of the keys to select a bucket to store data in. Objects that hash to the same value will be added to the same bucket.

When the hashing function has a poor distribution, buckets can grow to very large sizes. This may negatively affect lookup performance, as, by default, matching a key within a bucket has linear complexity.

In addition, as the default hashCode function can be selected at runtime, performance expectations cannot be maintained.

Implementing Comparable mitigates the performance issue for objects that hash to the same value.

```java Bad theme={"system"} class MyKeyType { // ... } class Program { Map data = new HashMap<>(); // Noncompliant Map buildMap() { // Noncompliant //... } } ``` ```java Fix theme={"system"} class MyKeyType implements Comparable { // ... } class MyChildKeyType extends MyKeyType { // ... } class Program { Map data = new HashMap<>(); Map data = new HashMap<>(); Map buildMap() { //... } } ```

The IllegalMonitorStateException is an exception that occurs when a thread tries to perform an operation on an object’s monitor that it does not own. This exception is typically thrown when a method like wait(), notify(), or notifyAll() is called outside a synchronized block or method.

IllegalMonitorStateException is specifically designed to be an unchecked exception to point out a programming mistake. This exception serves as a reminder for developers to rectify their code by correctly acquiring and releasing locks using synchronized blocks or methods. It also emphasizes the importance of calling monitor-related methods on the appropriate objects to ensure proper synchronization.

Catching and handling this exception can mask underlying synchronization issues and lead to unpredictable behavior.

```java Bad theme={"system"} public void doSomething() { try { anObject.notify(); } catch(IllegalMonitorStateException e) { // Noncompliant } } ``` ```java Fix theme={"system"} public void doSomething() { synchronized(anObject) { anObject.notify(); } } ```

Tests should always:

  • Make sure that production code behaves as expected, including edge cases.

  • Be easy to debug, i.e. understandable and reproducible.

Using random values in tests will not necessarily check edge cases, and it will make test logs a lot harder to read. It is better to use easily readable hardcoded values. If this makes your code bigger you can use helper functions.

There is one valid use case for random data in tests: when testing every value would make tests impractically slow. In this case the best you can do is use random to test every value on the long run. You should however make sure that random values are logged so that you can reproduce failures. Some libraries exist to make all this easier. You can for example use property-based testing libraries such as jqwik.

This rule raises an issue when new Random() or UUID.randomUUID() are called in test code.

```java Bad theme={"system"} int userAge = new Random().nextInt(42); // Noncompliant UUID userID = UUID.randomUUID(); // Noncompliant ``` ```java Fix theme={"system"} int userAge = 31; UUID userID = UUID.fromString("00000000-000-0000-0000-000000000001"); ```

Double-checked locking is the practice of checking a lazy-initialized object’s state both before and after a synchronized block is entered to determine whether to initialize the object. In early JVM versions, synchronizing entire methods was not performant, which sometimes caused this practice to be used in its place.

Apart from float and int types, this practice does not work reliably in a platform-independent manner without additional synchronization of mutable instances. Using double-checked locking for the lazy initialization of any other type of primitive or mutable object risks a second thread using an uninitialized or partially initialized member while the first thread is still creating it. The results can be unexpected, potentially even causing the application to crash.

```java Bad theme={"system"} public class ResourceFactory { private static Resource resource; public static Resource getInstance() { if (resource == null) { synchronized (DoubleCheckedLocking.class) { // Noncompliant, not thread-safe due to the use of double-checked locking. if (resource == null) resource = new Resource(); } } return resource; } } ``` ```java Fix theme={"system"} public class ResourceFactory { private static Resource resource; public static synchronized Resource getInstance() { // Compliant, the entire method is synchronized and hence thread-safe if (resource == null) resource = new Resource(); return resource; } } ```

To check the type of an object there are at least two options:

  • The simplest and shortest one with help of the \`instanceof operator

  • The cumbersome and error-prone one with help of the Class.isAssignableFrom(...)\` method

```java Bad theme={"system"} if (MyClass.class.isAssignableFrom(x.getClass())) { // Noncompliant MyClass mc = (MyClass)x; } ``` ```java Fix theme={"system"} if (x instanceof MyClass.class) { MyClass mc = (MyClass)x; } ```

When a cycle exists between classes during their static initialization, the results can be unpredictable because they depend on which class was initialized first.

```java Bad theme={"system"} public class A { public static int a = B.b + 1; // Noncompliant; sometimes a = 1, others a = 2 } public class B { public static int b = A.a + 1; // Noncompliant; sometimes b = 1, others b = 2 } ``` ```java Fix theme={"system"} ```

\`transient fields are ignored by Java’s automatic serizalization mechanisms, which means that when a object is deserialized, those fields will be set to their default values.

transient fields that are referenced in multiple places in a class seem to play a significant role in that class. Allowing such significant fields to be left in a default state after deserialization may not be the best course, so they should probably be set in either a readObject() or readResolve()\` method.

```java Bad theme={"system"} class Fruit implements Serializable { private transient Seed seed; public Fruit (Seed seed) { this.seed = seed; // 1st set } public void setSeed (Seed seed) { this.seed = seed; // 2nd set } public Seed getSeed() { return seed; // not counted; read, not write. } public void sprout () { this.seed = new GerminatedSeed(); // Noncompliant; 3rd write //... } } ``` ```java Fix theme={"system"} class Fruit implements Serializable { private transient Seed seed; public Fruit (Seed seed) { this.seed = seed; // 1st reference } public void setSeed (Seed seed) this.seed = seed; // 2nd reference } public Seed getSeed() { return seed; // not counted; read, not write. } public void sprout () { this.seed = new GerminatedSeed(); // Noncompliant; 3rd write //... } protected Object readResolve() throws ObjectStreamException { // ... } } ```

A synchronized method is a method marked with the synchronized keyword, meaning it can only be accessed by one thread at a time. If multiple threads try to access the synchronized method simultaneously, they will be blocked until the method is available.

Synchronized methods prevent race conditions and data inconsistencies in multi-threaded environments. Ensuring that only one thread can access a method at a time, prevents multiple threads from modifying the same data simultaneously, and causing conflicts.

When one part of a getter/setter pair is synchronized the other should be too. Failure to synchronize both sides may result in inconsistent behavior at runtime as callers access an inconsistent method state.

This rule raises an issue when either the method or the contents of one method in a getter/setter pair are synchronized, but the other is not.

```java Bad theme={"system"} public class Person { String name; int age; public synchronized void setName(String name) { this.name = name; } public String getName() { // Noncompliant return this.name; } public void setAge(int age) { // Noncompliant this.age = age; } public int getAge() { synchronized (this) { return this.age; } } } ``` ```java Fix theme={"system"} public class Person { String name; int age; public synchronized void setName(String name) { this.name = name; } public synchronized String getName() { return this.name; } public void setAge(int age) { synchronized (this) { this.age = age; } } public int getAge() { synchronized (this) { return this.age; } } } ```

In the past, it was required to load a JDBC driver before creating a \`java.sql.Connection. Nowadays, when using JDBC 4.0 drivers, this is no longer required and Class.forName() can be safely removed because JDBC 4.0 (JDK 6) drivers available in the classpath are automatically loaded.

This rule raises an issue when Class.forName() is used with one of the following values:

  • com.mysql.jdbc.Driver

  • oracle.jdbc.driver.OracleDriver

  • com.ibm.db2.jdbc.app.DB2Driver

  • com.ibm.db2.jdbc.net.DB2Driver

  • com.sybase.jdbc.SybDriver

  • com.sybase.jdbc2.jdbc.SybDriver

  • com.teradata.jdbc.TeraDriver

  • com.microsoft.sqlserver.jdbc.SQLServerDriver

  • org.postgresql.Driver

  • sun.jdbc.odbc.JdbcOdbcDriver

  • org.hsqldb.jdbc.JDBCDriver

  • org.h2.Driver

  • org.firebirdsql.jdbc.FBDriver

  • net.sourceforge.jtds.jdbc.Driver

  • com.ibm.db2.jcc.DB2Driver\`

```java Bad theme={"system"} import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; public class Demo { private static final String DRIVER_CLASS_NAME = "org.postgresql.Driver"; private final Connection connection; public Demo(String serverURI) throws SQLException, ClassNotFoundException { Class.forName(DRIVER_CLASS_NAME); // Noncompliant; no longer required to load the JDBC Driver using Class.forName() connection = DriverManager.getConnection(serverURI); } } ``` ```java Fix theme={"system"} import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; public class Demo { private final Connection connection; public Demo(String serverURI) throws SQLException { connection = DriverManager.getConnection(serverURI); } } ```

The Spring framework comes with dedicated classes to help writing better and simpler unit tests. In particular, when testing applications built on top of Spring MVC, it is recommended to use Spring’s \`ModelAndViewAssert assertions class, instead of manually testing MVC’s properties.

 

This rule raises an issue when Spring’s ModelAndViewAssert\` assertions should be used instead of manual testing.

```java Bad theme={"system"} ModelAndView mav = getMyModelAndView(); Assert.assertEquals("register", mav.getViewName()); Assert.assertTrue((Boolean) mav.getModelMap().get("myAttribute")); Assert.assertFalse((Boolean) mav.getModelMap().get("myAttribute")); Assert.assertEquals(myObject, mav.getModelMap().get("myAttribute")); ``` ```java Fix theme={"system"} ModelAndView mav = getMyModelAndView(); ModelAndViewAssert.assertViewName(mav, "register"); ModelAndViewAssert.assertModelAttributeValue(mav, "myAttribute", Boolean.TRUE); ModelAndViewAssert.assertModelAttributeValue(mav, "myAttribute", Boolean.FALSE); ModelAndViewAssert.assertModelAttributeValue(mav, "myAttribute", myObject); ```

There is no reason to have a \`main method in a web application. It may have been useful for debugging during application development, but such a method should never make it into production. Having a main method in a web application opens a door to the application logic that an attacker may never be able to reach (but watch out if one does!), but it is a sloppy practice and indicates that other problems may be present.

This rule raises an issue when a main\` method is found in a servlet or an EJB.

```java Bad theme={"system"} public class MyServlet extends HttpServlet { public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { if (userIsAuthorized(req)) { updatePrices(req); } } public static void main(String[] args) { // Noncompliant updatePrices(req); } } ``` ```java Fix theme={"system"} ```

By default, Hibernate session flushing is set to FlushMode.AUTO, and is called from Transaction.commit, Session.flush and before some queries are executed. Setting it to FlushMode.COMMIT, FlushMode.NEVER, or FlushMode.MANUAL could mean that parts of your application get stale data, so you should be sure of what you’re doing before you use any of these modes.

This rule raises an issue when flush mode is explicitly set to any of these modes.

```java Bad theme={"system"} Session session = sessionFactory.openSession(); session.setFlushMode(FlushMode.NEVER); // Noncompliant ``` ```java Fix theme={"system"} ```

While this can be useful, whenever we want to instantiate and start an unnamed virtual thread, there is a more convenient static method to do so: Thread.startVirtualThread(Runnable task)

This rule raises an issue every time the form Thread.ofVirtual().start(task); is found.

```java Bad theme={"system"} Thread virtualThread = Thread.ofVirtual().start(task); // Noncompliant `Thread.startVirtualThread` should be used instead ``` ```java Fix theme={"system"} Thread virtualThread = Thread.startVirtualThread(task); // Compliant Thread unstartedVirtualThread = Thread.ofVirtual().unstarted(task); // Compliant, the thread is unstarted Thread namedVirtualThread = Thread.ofVirtual().name("MyThread").start(); // Compliant, the builder pattern is being used to set the name Thread platformThread = Thread.ofPlatform().start(task); // Compliant, there is no `Thread.startPlatformThread` method ```

Since Java 9, \`@Deprecated has two additional arguments to the annotation:

  • since allows you to describe when the deprecation took place

  • forRemoval, indicates whether the deprecated element will be removed at some future date

In order to ease the maintainers work, it is recommended to always add one or both of these arguments.

This rule reports an issue when @Deprecated\` is used without any argument.

```java Bad theme={"system"} @Deprecated ``` ```java Fix theme={"system"} @Deprecated(since="4.2", forRemoval=true) ```

rm is security-sensitive. For example, their use has led in the past to the following vulnerability:

All classes extending org.apache.struts.action.Action are potentially remotely reachable. The ActionForm object provided as a parameter of the execute method is automatically instantiated and populated with the HTTP parameters. One should review the use of these parameters to be sure they are used safely.

```java Bad theme={"system"} // Struts 1.1+ public final class CashTransferAction extends Action { public String fromAccount = ""; public String toAccount = ""; public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest req, HttpServletResponse res) throws Exception { // usage of the "form" object to call some services doing JDBC actions [...] return mapping.findForward(resultat); } } ``` ```java Fix theme={"system"} ```

The array brackets (\[]) for methods that return arrays may appear either immediately after the array type or after the list of parameters. Both styles will compile, but placing array brackets at the end of the method signature is deprecated, and retained in the language specification only for backward compatibility.

Additionally, placing the array brackets at the end is far less readable than keeping the brackets with the return type. Therefore, this style should be found only in legacy code, never in new code.

```java Bad theme={"system"} String sayHello() [] { // Noncompliant return new String[] {"hello", "world"}; } ``` ```java Fix theme={"system"} String [] sayHello() { return new String[] {"hello", "world"}; } ```

The hasNext method of an Iterator should only report on the state of the iterator, not change it. Making a change to an iterator in its hasNext method violates all expectations of what the method will do, and almost guarantees bad results when the iterator class is used.

```java Bad theme={"system"} public class MyItr implements Iterator { //... public boolean hasNext() { if (next() != null) { // Noncompliant return true; } return false; } ``` ```java Fix theme={"system"} public class MyItr implements Iterator { private List list; private int index = 0; //... public boolean hasNext() { return index < list.size(); } ```

xtract strings from an application source code or binary, passwords should not be hard-coded. This is particularly true for applications that are distributed or that are open-source.

In the past, it has led to the following vulnerabilities:

Passwords should be stored outside of the code in a configuration file, a database, or a password management service.

This rule flags instances of hard-coded passwords used in database and LDAP connections. It looks for hard-coded passwords in connection strings, and for variable names that match any of the patterns from the provided list.

```java Bad theme={"system"} String username = "steve"; String password = "blue"; Connection conn = DriverManager.getConnection("jdbc:mysql://localhost/test?" + "user=" + username + "&password=" + password); // Sensitive ``` ```java Fix theme={"system"} String username = getEncryptedUser(); String password = getEncryptedPassword(); Connection conn = DriverManager.getConnection("jdbc:mysql://localhost/test?" + "user=" + username + "&password=" + password); ```

Because Double Brace Initialization (DBI) creates an anonymous class with a reference to the instance of the owning object, its use can lead to memory leaks if the anonymous inner class is returned and held by other objects. Even when there’s no leak, DBI is so obscure that it’s bound to confuse most maintainers.

For collections, use Arrays.asList instead, or explicitly add each item directly to the collection.

```java Bad theme={"system"} Map source = new HashMap(){{ // Noncompliant put("firstName", "John"); put("lastName", "Smith"); }}; ``` ```java Fix theme={"system"} Map source = new HashMap(); // ... source.put("firstName", "John"); source.put("lastName", "Smith"); // ... ```

In records, the default behavior of the \`equals() method is to check the equality by field values. This works well for primitive fields or fields, whose type overrides equals(), but this behavior doesn’t work as expected for array fields.

By default, array fields are compared by their reference, and overriding equals() is highly appreciated to achieve the deep equality check. The same strategy applies to hashCode() and toString() methods.

This rule reports an issue if a record class has an array field and is not overriding equals(), hashCode() or toString()\` methods.

```java Bad theme={"system"} record Person(String[] names, int age) {} // Noncompliant ``` ```java Fix theme={"system"} record Person(String[] names, int age) { @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Person person = (Person) o; return age == person.age && Arrays.equals(names, person.names); } @Override public int hashCode() { int result = Objects.hash(age); result = 31 * result + Arrays.hashCode(names); return result; } @Override public String toString() { return "Person{" + "names=" + Arrays.toString(names) + ", age=" + age + '}'; } } ```

According to Hibernate’s documentation:

Hibernate’s own connection pooling algorithm is, …​ quite rudimentary. It is intended to help you get started and is not intended for use in a production system, or even for performance testing. You should use a third party pool for best performance and stability.

This rule raises an issue when a hibernate.connection.pool\_size value is found in a hibernate.cfg.xml or hibernate.properties file.

```java Bad theme={"system"} 10 ``` ```java Fix theme={"system"} // ... hibernate.connection.pool_size=10 // Noncompliant ```

Nested \`switch structures are difficult to understand because you can easily confuse the cases of an inner switch as belonging to an outer statement or expression. Therefore nested switch statements and expressions should be avoided.

Specifically, you should structure your code to avoid the need for nested switch statements or expressions, but if you cannot, then consider moving the inner switch\` to another method.

```java Bad theme={"system"} void foo(int n, int m) { switch (n) { case 0: switch (m) { // Noncompliant; nested switch // ... } case 1: // ... default: // ... } } ``` ```java Fix theme={"system"} void foo(int n, int m) { switch (n) { case 0: bar(m); case 1: // ... default: // ... } } void bar(int m){ switch(m) { // ... } } ```

Invoking other Lambdas synchronously from a Lambda is a scalability anti-pattern. Lambdas have a maximum execution time before they timeout (15 minutes as of May 2021). Having to wait for another Lambda to finish its execution could lead to a timeout.

A better solution is to generate events that can be consumed asynchronously by other Lambdas.

```java Bad theme={"system"} InvokeRequest invokeRequest = new InvokeRequest() .withFunctionName("myFunction"); AWSLambda awsLambda = AWSLambdaClientBuilder.standard() .withCredentials(new ProfileCredentialsProvider()) .withRegion(Regions.US_WEST_2).build(); awsLambda.invoke(invokeRequest); // Noncompliant ``` ```java Fix theme={"system"} ```

Non-static initializers, also known as instance initializers, are blocks of code within a class that are executed when an instance of the class is created. They are executed when an object of the class is created just before the constructor is called. Non-static initializers are useful when you want to perform some common initialization logic for all objects of a class. They allow you to initialize instance variables in a concise and centralized manner, without having to repeat the same initialization code in each constructor.

While non-static initializers may have some limited use cases, they are rarely used and can be confusing for most developers because they only run when new class instances are created.

```java Bad theme={"system"} class MyClass { private static final Map MY_MAP = new HashMap() { { put("a", "b"); } }; // Noncompliant - HashMap should be extended only to add behavior, not for initialization } ``` ```java Fix theme={"system"} class MyClass { private static final Map MY_MAP = new HashMap<>(); static { MY_MAP.put("a", "b"); // Compliant } } ```

The counter of a for loop should be updated in the loop’s increment clause. The purpose of a for loop is to iterate over a range using a counter variable. It should not be used for other purposes, and alternative loops should be used in those cases.

If the counter is not updated, the loop will be infinite with a constant counter variable. If this is intentional, use a while or do while loop instead of a for loop.

If the counter variable is updated within the loop’s body, try to move it to the increment clause. If this is impossible due to certain conditions, replace the for loop with a while or do while loop.

```java Bad theme={"system"} for (int i = 0; i < 10; ) { // Noncompliant, i not updated in increment clause // ... i++; } ``` ```java Fix theme={"system"} int sum = 0 for (int i = 0; i < 10; sum++) { // Noncompliant, i not updated in increment clause // ... i++; } ```

Many resources in Java need be closed after they have been used. If they are not, the garbage collector cannot reclaim the resources' memory, and they are still considered to be in use by the operating system. Such resources are considered to be leaked, which can lead to performance issues.

Java 7 introduced the try-with-resources statement, which guarantees that the resource in question will be closed.

```java Bad theme={"system"} try (InputStream input = Files.newInputStream(path)) { // "input" will be closed after the execution of this block } ``` ```java Fix theme={"system"} try (/* resources declarations */) { // resources usage ... } ```

When a test fails due, for example, to infrastructure issues, you might want to ignore it temporarily. But without some kind of notation about why the test is being ignored, it may never be reactivated. Such tests are difficult to address without comprehensive knowledge of the project, and end up polluting their projects.

This rule raises an issue for each ignored test that does not have any comment about why it is being skipped.

  • For Junit4, this rule targets the @Ignore annotation.

  • For Junit5, this rule targets the @Disabled annotation.

  • Cases where assumeTrue(false) or assumeFalse(true) are used to skip tests are targeted as well.

```java Bad theme={"system"} @Ignore // Noncompliant @Test public void testDoTheThing() { // ... ``` ```java Fix theme={"system"} @Test public void testDoTheThing() { Assume.assumeFalse(true); // Noncompliant // ... ```

JUnit5 is more tolerant regarding the visibilities of Test classes and methods than JUnit4, which required everything to be public. JUnit5 supports default package, public and protected visibility, even if it is recommended to use the default package visibility, which improves the readability of code.

But JUnit5 ignores without any warning:

  • private classes and private methods

  • static methods

  • methods returning a value without being a TestFactory

```java Bad theme={"system"} import org.junit.jupiter.api.Test; class MyClassTest { @Test private void test1() { // Noncompliant - ignored by JUnit5 // ... } @Test static void test2() { // Noncompliant - ignored by JUnit5 // ... } @Test boolean test3() { // Noncompliant - ignored by JUnit5 // ... } @Nested private class MyNestedClass { // Noncompliant - ignored by JUnit5 @Test void test() { // ... } } } ``` ```java Fix theme={"system"} import org.junit.jupiter.api.Test; class MyClassTest { @Test void test1() { // ... } @Test void test2() { // ... } @Test void test3() { // ... } @Nested class MyNestedClass { @Test void test() { // ... } } } ```

A test case without assertions ensures only that no exceptions are thrown. Beyond basic runnability, it ensures nothing about the behavior of the code under test.

This rule raises an exception when no assertions from any of the following known frameworks are found in a test:

  • AssertJ

  • Awaitility

  • EasyMock

  • Eclipse Vert.x

  • Fest 1.x and 2.x

  • Hamcrest

  • JMock

  • JMockit

  • JUnit

  • Mockito

  • Rest-assured 2.x, 3.x and 4.x

  • RxJava 1.x and 2.x

  • Selenide

  • Spring’s \`org.springframework.test.web.servlet.ResultActions.andExpect() and org.springframework.test.web.servlet.ResultActions.andExpectAll()

  • Truth Framework

  • WireMock

Furthermore, as new or custom assertion frameworks may be used, the rule can be parametrized to define specific methods that will also be considered as assertions. No issue will be raised when such methods are found in test cases. The parameter value should have the following format \#\, where MethodName can end with the wildcard character. For constructors, the pattern should be \#\.

Example: com.company.CompareToTester#compare\*,com.company.CustomAssert#customAssertMethod,com.company.CheckVerifier#\\`.

```java Bad theme={"system"} @Test public void testDoSomething() { // Noncompliant MyClass myClass = new MyClass(); myClass.doSomething(); } ``` ```java Fix theme={"system"} import com.company.CompareToTester; @Test public void testDoSomething() { MyClass myClass = new MyClass(); assertNull(myClass.doSomething()); // JUnit assertion assertThat(myClass.doSomething()).isNull(); // Fest assertion } @Test public void testDoSomethingElse() { MyClass myClass = new MyClass(); new CompareToTester().compareWith(myClass); // Compliant - custom assertion method defined as rule parameter CompareToTester.compareStatic(myClass); // Compliant } ```

Non-static inner classes contain a reference to an instance of the outer class. Hence, serializing a non-static inner class will result in an attempt at serializing the outer class as well. If the outer class is not serializable, serialization will fail, resulting in a runtime error.

Making the inner class static (i.e., "nested") avoids this problem, as no reference to an instance of the outer class is required. Serializing the inner class can be done independently of the outer class. Hence, inner classes implementing Serializable should be static if the outer class does not implement Serializable.

Be aware of the semantic differences between an inner class and a nested one:

  • an inner class can only be instantiated within the context of an instance of the outer class.

  • a nested (static) class can be instantiated independently of the outer class.

```java Bad theme={"system"} public class Pomegranate { // ... public class Seed implements Serializable { // Noncompliant, serialization will fail due to the outer class not being serializable // ... } } ``` ```java Fix theme={"system"} public class Pomegranate { // ... public static class Seed implements Serializable { // Compliant, the outer class will not be serialized and hence cannot be the cause for a failure at runtime // ... } } ```

The java.util.Collection type and its subtypes provide methods to access and modify collections such as Collection.remove(Object o) and Collection.contains(Object o). Some of these methods accept arguments of type java.lang.Object and will compare said argument with objects already in the collection.

If the actual type of the argument is unrelated to the type of object contained in the collection, these methods will always return false, null, or -1. This behavior is most likely unintended and can be indicative of a design issue.

This rule raises an issue when the type of the argument provided to one of the following methods is unrelated to the type used for the collection declaration:

  • Collection.remove(Object o)

  • Collection.removeAll(Collection\)

  • Collection.contains(Object o)

  • List.indexOf(Object o)

  • List.lastIndexOf(Object o)

  • Map.containsKey(Object key)

  • Map.containsValue(Object value)

  • Map.get(Object key)

  • Map.getOrDefault(Object key, V defaultValue)

  • Map.remove(Object key)

  • Map.remove(Object key, Object value)

```java Bad theme={"system"} void removeFromMap(Map map, String strKey) { map.remove(strKey); // Noncompliant, this call will remove nothing and always return 'null' because 'map' is handling only Integer keys and String cannot be cast to Integer. } void listContains(List list, Integer integer) { if (list.contains(integer)) { // Noncompliant; always false as the list only contains Strings, not integers. // ... } } ``` ```java Fix theme={"system"} void removeFromMap(Map map, String strKey) { map.remove(Integer.parseInt(strKey)); // Compliant, strKey is parsed into an Integer before trying to remove it from the map. } void listContains(List list, Integer integer) { if (list.contains(integer.toString())) { // Compliant, 'integer' is converted to a String before checking if the list contains it. // ... } } ```

When implementing the \`Comparable\.compareTo method, the parameter’s type has to match the type used in the Comparable declaration. When a different type is used this creates an overload instead of an override, which is unlikely to be the intent.

This rule raises an issue when the parameter of the compareTo method of a class implementing Comparable\ is not same as the one used in the Comparable\` declaration.

```java Bad theme={"system"} public class Foo { static class Bar implements Comparable { public int compareTo(Bar rhs) { return -1; } } static class FooBar extends Bar { public int compareTo(FooBar rhs) { // Noncompliant: Parameter should be of type Bar return 0; } } } ``` ```java Fix theme={"system"} public class Foo { static class Bar implements Comparable { public int compareTo(Bar rhs) { return -1; } } static class FooBar extends Bar { public int compareTo(Bar rhs) { return 0; } } } ```

The @Remote annotation indicates that an interface may be called from a remote client. Therefore the parameters and return types of methods in the interface must be Serializable.

```java Bad theme={"system"} public class Employee { // Nonserializable } @Remote public interface EmployeeServiceRemote { public Employee getEmployee(String id); // Noncompliant } ``` ```java Fix theme={"system"} public class Employee implements Serializable{ } @Remote public interface EmployeeServiceRemote { public Employee getEmployee(String id); // Noncompliant } ```

Using \`return, break, throw, and so on from a finally block suppresses the propagation of any unhandled Throwable which was thrown in the try or catch block.

This rule raises an issue when a jump statement (break, continue, return, throw, and goto) would force control flow to leave a finally\` block.

```java Bad theme={"system"} public static void main(String[] args) { try { doSomethingWhichThrowsException(); System.out.println("OK"); // incorrect "OK" message is printed } catch (RuntimeException e) { System.out.println("ERROR"); // this message is not shown } } public static void doSomethingWhichThrowsException() { try { throw new RuntimeException(); } finally { for (int i = 0; i < 10; i ++) { //... if (q == i) { break; // ignored } } /* ... */ return; // Noncompliant - prevents the RuntimeException from being propagated } } ``` ```java Fix theme={"system"} public static void main(String[] args) { try { doSomethingWhichThrowsException(); System.out.println("OK"); } catch (RuntimeException e) { System.out.println("ERROR"); // "ERROR" is printed as expected } } public static void doSomethingWhichThrowsException() { try { throw new RuntimeException(); } finally { for (int i = 0; i < 10; i ++) { //... if (q == i) { break; // ignored } } /* ... */ } } ```

If not annotated with \`@Nested, an inner class containing some tests will never be executed during tests execution. While you could still be able to manually run its tests in an IDE, it won’t be the case during the build. By contrast, a static nested class containing some tests should not be annotated with @Nested, JUnit5 will not share setup and state with an instance of its enclosing class.

This rule raises an issue on inner classes and static nested classes containing JUnit5 test methods which has a wrong usage of @Nested\` annotation.

Note: This rule does not check if the context in which JUnit 5 is running (e.g. Maven Surefire Plugin) is properly configured to execute static nested classes, it could not be the case using the default configuration.

```java Bad theme={"system"} import org.junit.jupiter.api.Test; class MyJunit5Test { @Test void test() { /* ... */ } class InnerClassTest { // Noncompliant, missing @Nested annotation @Test void test() { /* ... */ } } @Nested static class StaticNestedClassTest { // Noncompliant, invalid usage of @Nested annotation @Test void test() { /* ... */ } } } ``` ```java Fix theme={"system"} import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Nested; class MyJunit5Test { @Test void test() { /* ... */ } @Nested class InnerClassTest { @Test void test() { /* ... */ } } static class StaticNestedClassTest { @Test void test() { /* ... */ } } } ```

Comparing a variable to multiple cases is a frequent operation. This can be done using a sequence of if-else statements. However, for many cases like enums or simple value comparisons, a switch statement is the better alternative. With Java 21, the switch statement has been significantly improved to support pattern matching and record pattern.

Using a switch statement instead of an if-else chain provides benefits like clearer code, certainty of covering all cases, and may even improve performance.

This rule raises an issue when an if-else chain should be replaced by a switch statement.

```java Bad theme={"system"} sealed interface Expression {} record Plus(Expression left, Expression right) implements Expression {} record Minus(Expression left, Expression right) implements Expression {} record Div(Expression left, Expression right) implements Expression {} int eval(Expression expr){ if(expr instanceof Plus plus){ // Noncompliant; should be replaced by a switch expression return eval(plus.left) + eval(plus.right); }else if(expr instanceof Div div){ return eval(div.left) / eval(div.right); }else if(expr instanceof Minus minus){ return eval(minus.left) - eval(minus.right); } else { throw new IllegalArgumentException("Unknown expression"); } } ``` ```java Fix theme={"system"} enum Color{RED,GREEN,YELLOW} String name(Color c){ if(c == Color.RED){ // Noncompliant; should be replaced by a switch expression return "red"; }else if(c == Color.GREEN){ return "green"; }else if(c == Color.YELLOW){ return "yellow"; }else{ throw new IllegalArgumentException("Unknown color"); } } ```

The Java Language Specification defines a set of rules called naming conventions that apply to Java programs. These conventions provide recommendations for naming packages, classes, methods, and variables.

By following shared naming conventions, teams can collaborate more efficiently.

This rule checks that static non-final field names match a provided regular expression.

```java Bad theme={"system"} public class MyClass { private static String foo_bar; // Noncompliant } ``` ```java Fix theme={"system"} public class MyClass { private static String fooBar; } ```

Double.longBitsToDouble converts the bit pattern into its corresponding floating-point representation. The method expects a 64-bit long argument to interpret the bits as a double value correctly.

When the argument is a smaller data type, the cast to long may lead to a different value than expected due to the interpretation of the most significant bit, which, in turn, results in Double.longBitsToDouble returning an incorrect value.

```java Bad theme={"system"} int i = 0x80003800; Double.longBitsToDouble(i); // Noncompliant - NaN ``` ```java Fix theme={"system"} long i = 0x80003800L; Double.longBitsToDouble(i); // Compliant - 1.0610049784E-314 ```

"@EnableAutoConfiguration" is a convenient feature to configure the Spring Application Context by attempting to guess the beans that you are likely to need. The drawback is that it may load and configure beans the application will never use and therefore consume more CPU and RAM than really required. \`@EnableAutoConfiguration should be configured to exclude all the beans not required by the application. Alternatively, use the @Import annotation instead of @EnableAutoConfiguration, to explicitly import the useful AutoConfiguration classes.

This rule applies for @SpringBootApplication\` as well.

```java Bad theme={"system"} @SpringBootApplication public class MyApplication { ... } ``` ```java Fix theme={"system"} @Configuration @EnableAutoConfiguration public class MyApplication { ... } ```

Overriding the \`Object.finalize() method must be done with caution to dispose some system resources.

Calling the super.finalize()\` at the end of this method implementation is highly recommended in case parent implementations must also dispose some system resources.

```java Bad theme={"system"} protected void finalize() { // Noncompliant; no call to super.finalize(); releaseSomeResources(); } protected void finalize() { super.finalize(); // Noncompliant; this call should come last releaseSomeResources(); } ``` ```java Fix theme={"system"} protected void finalize() { releaseSomeResources(); super.finalize(); } ```

If a lock is acquired and released within a method, then it must be released along all execution paths of that method.

Failing to do so will expose the conditional locking logic to the method’s callers and hence be deadlock-prone.

```java Bad theme={"system"} public class MyClass { public void doSomething() { Lock lock = new Lock(); lock.lock(); // Noncompliant if (isInitialized()) { // ... lock.unlock(); } } } ``` ```java Fix theme={"system"} public class MyClass { public void doSomething() { Lock lock = new Lock(); if (isInitialized()) { lock.lock(); // ... lock.unlock(); } } } ```

Exposing HTTP endpoints is security-sensitive. It has led in the past to the following vulnerabilities:

HTTP endpoints are webservices' main entrypoint. Attackers will take advantage of any vulnerability by sending crafted inputs for headers (including cookies), body and URI. No input should be trusted and extreme care should be taken with all returned value (header, body and status code).

This rule flags code which creates HTTP endpoint. It guides security code reviews to security-sensitive code.

```java Bad theme={"system"} @RequestMapping(path = "/profile", method = RequestMethod.GET) // Noncompliant public UserProfile getUserProfile(String name) { ... } ``` ```java Fix theme={"system"} ```

Overly complicated regular expressions are hard to read and to maintain and can easily cause hard-to-find bugs. If a regex is too complicated, you should consider replacing it or parts of it with regular code or splitting it apart into multiple patterns at least.

The complexity of a regular expression is determined as follows:

Each of the following operators increases the complexity by an amount equal to the current nesting level and also increases the current nesting level by one for its arguments:

  • \`| - when multiple | operators are used together, the subsequent ones only increase the complexity by 1

  • && (inside character classes) - when multiple && operators are used together, the subsequent ones only increase the complexity by 1

  • Quantifiers (\*, +, ?, \{n,m}, \{n,} or \{n})

  • Non-capturing groups that set flags (such as (?i:some\_pattern) or (?i)some\_pattern\`)

  • Lookahead and lookbehind assertions

Additionally, each use of the following features increase the complexity by 1 regardless of nesting:

  • character classes

  • back references

If a regular expression is split among multiple variables, the complexity is calculated for each variable individually, not for the whole regular expression. If a regular expression is split over multiple lines, each line is treated individually if it is accompanied by a comment (either a Java comment or a comment within the regular expression), otherwise the regular expression is analyzed as a whole.

```java Bad theme={"system"} if (dateString.matches("^(?:(?:31(\\/|-|\\.)(?:0?[13578]|1[02]))\\1|(?:(?:29|30)(\\/|-|\\.)(?:0?[13-9]|1[0-2])\\2))(?:(?:1[6-9]|[2-9]\\d)?\\d{2})$|^(?:29(\\/|-|\\.)0?2\\3(?:(?:(?:1[6-9]|[2-9]\\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:0?[1-9]|1\\d|2[0-8])(\\/|-|\\.)(?:(?:0?[1-9])|(?:1[0-2]))\\4(?:(?:1[6-9]|[2-9]\\d)?\\d{2})$")) { handleDate(dateString); } ``` ```java Fix theme={"system"} if (dateString.matches("^\\d{1,2}([-/.])\\d{1,2}\\1\\d{1,4}$")) { String dateParts[] = dateString.split("[-/.]"); int day = Integer.parseInt(dateParts[0]); int month = Integer.parseInt(dateParts[1]); int year = Integer.parseInt(dateParts[2]); // Put logic to validate and process the date based on its integer parts here } ```

Jump statements such as return and continue let you change the default flow of program execution, but jump statements that direct the control flow to the original direction are just a waste of keystrokes.

```java Bad theme={"system"} public void foo() { while (condition1) { if (condition2) { continue; // Noncompliant } else { doTheThing(); } } return; // Noncompliant; this is a void method } ``` ```java Fix theme={"system"} public void foo() { while (condition1) { if (!condition2) { doTheThing(); } } } ```

Inappropriate casts are errors that will lead to bugs as the members are accessed. This includes casts from one unrelated type to another, as well as untested casts down an inheritance hierarchy.

```java Bad theme={"system"} public class S1944 { public static void main(String[] args) { List list = (List) getAttributes(); // Noncompliant; List return by getAttributes() is not be casted to List String s = list.get(0); // java.lang.ClassCastException will be raised here } private static List getAttributes() { List result = new ArrayList<>(); result.add(0); return result; } } ``` ```java Fix theme={"system"} public class S1944 { public static void main(String[] args) { List list = (List) getAttributes(); // Compliant String s = String.valueOf(list.get(0)); } private static List getAttributes() { List result = new ArrayList<>(); result.add(0); return result; } } ```

Storing data locally is a common task for mobile applications. Such data includes preferences or authentication tokens for external services, among other things. There are many convenient solutions that allow storing data persistently, for example SQLiteDatabase, SharedPreferences, and Realm. By default these systems store the data unencrypted, thus an attacker with physical access to the device can read them out easily. Access to sensitive data can be harmful for the user of the application, for example when the device gets stolen.

```java Bad theme={"system"} SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase("test.db", getKey(), null); ``` ```java Fix theme={"system"} String masterKeyAlias = new MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC); EncryptedSharedPreferences.create( "secret", masterKeyAlias, context, EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV, EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM ); ```

Regular expressions have their own syntax that is understood by regular expression engines. Those engines will throw an exception at runtime if they are given a regular expression that does not conform to that syntax.

To avoid syntax errors, special characters should be escaped with backslashes when they are intended to be matched literally and references to capturing groups should use the correctly spelled name or number of the group.

```java Bad theme={"system"} Pattern.compile("(["); str.matches("(["); str.replaceAll("([", "{"); str.matches("(\\w+-(\\d+)"); ``` ```java Fix theme={"system"} Pattern.compile("\\(\\["); Pattern.compile("([", Pattern.LITERAL); str.equals("(["); str.replace("([", "{"); str.matches("(\\w+)-(\\d+)"); ```

Operating systems have global directories where any user has write access. Those folders are mostly used as temporary storage areas like \`/tmp in Linux based systems. An application manipulating files from these folders is exposed to race conditions on filenames: a malicious user can try to create a file with a predictable name before the application does. A successful attack can result in other files being accessed, modified, corrupted or deleted. This risk is even higher if the application runs with elevated permissions.

In the past, it has led to the following vulnerabilities:

This rule raises an issue whenever it detects a hard-coded path to a publicly writable directory like /tmp (see examples bellow). It also detects access to environment variables that point to publicly writable directories, e.g., TMP and TMPDIR.

  • /tmp

  • /var/tmp

  • /usr/tmp

  • /dev/shm

  • /dev/mqueue

  • /run/lock

  • /var/run/lock

  • /Library/Caches

  • /Users/Shared

  • /private/tmp

  • /private/var/tmp

  • \Windows\Temp

  • \Temp

  • \TMP\`

```java Bad theme={"system"} new File("/myDirectory/myfile.txt"); // Compliant File.createTempFile("prefix", "suffix", new File("/mySecureDirectory")); // Compliant if(SystemUtils.IS_OS_UNIX) { FileAttribute> attr = PosixFilePermissions.asFileAttribute(PosixFilePermissions.fromString("rwx------")); Files.createTempFile("prefix", "suffix", attr); // Compliant } else { File f = Files.createTempFile("prefix", "suffix").toFile(); // Compliant f.setReadable(true, true); f.setWritable(true, true); f.setExecutable(true, true); } ``` ```java Fix theme={"system"} ```

Shared naming conventions allow teams to collaborate efficiently. This rule raises an issue when a test class name does not match the provided regular expression.

```java Bad theme={"system"} class Foo { // Noncompliant @Test void check() { } } class Bar { // Noncompliant @Nested class PositiveCase { @Test void check() { } } } ``` ```java Fix theme={"system"} class FooTest { @Test void check() { } } class BarIT { @Nested class PositiveCase { @Test void check() { } } } ```

WebViews can be used to display web content as part of a mobile application. A browser engine is used to render and display the content. Like a web application, a mobile application that uses WebViews can be vulnerable to Cross-Site Scripting if untrusted code is rendered.

If malicious JavaScript code in a WebView is executed this can leak the contents of sensitive files when access to local files is enabled.

```java Bad theme={"system"} import android.webkit.WebView; WebView webView = (WebView) findViewById(R.id.webview); webView.getSettings().setAllowFileAccess(true); // Sensitive webView.getSettings().setAllowContentAccess(true); // Sensitive ``` ```java Fix theme={"system"} import android.webkit.WebView; WebView webView = (WebView) findViewById(R.id.webview); webView.getSettings().setAllowFileAccess(false); webView.getSettings().setAllowContentAccess(false); ```

Sub-patterns can be wrapped by parentheses to build a group. This enables to restrict alternations, back reference the group or apply quantifier to the sub-pattern.

If this group should not be part of the match result or if no reference to this group is required, a non-capturing group can be created by adding ?: behind the opening parenthesis.

However, if this non-capturing group does not have a quantifier, or does not wrap an alternation, then imaging this group is redundant.

```java Bad theme={"system"} "(?:number)\\d{2}" ``` ```java Fix theme={"system"} "number\\d{2}" // it is anyway required "(?:number)?\\d{2}" // it is in fact optional ```

Curly brace quantifiers in regular expressions can be used to have a more fine-grained control over how many times the character or the sub-expression preceeding them should occur. They can be used to match an expression exactly n times with \`\{n}, between n and m times with \{n,m}, or at least n times with \{n,}. In some cases, using such a quantifier is superfluous for the semantic of the regular expression, and it can be removed to improve readability. This rule raises an issue when one of the following quantifiers is encountered:

  • \{1,1} or \{1}: they match the expression exactly once. The same behavior can be achieved without the quantifier.

  • \{0,0} or \{0}\`: they match the expression zero times. The same behavior can be achieved by removing the expression.

```java Bad theme={"system"} "ab{1,1}c" "ab{1}c" "ab{0,0}c" "ab{0}c" ``` ```java Fix theme={"system"} "abc" "ac" ```

Most of the regular expression engines use backtracking to try all possible execution paths of the regular expression when evaluating an input, in some cases it can cause performance issues, called catastrophic backtracking situations. In the worst case, the complexity of the regular expression is exponential in the size of the input, this means that a small carefully-crafted input (like 20 chars) can trigger catastrophic backtracking and cause a denial of service of the application. Super-linear regex complexity can lead to the same impact too with, in this case, a large carefully-crafted input (thousands chars).

This rule determines the runtime complexity of a regular expression and informs you of the complexity if it is not linear.

Note that, due to improvements to the matching algorithm, some cases of exponential runtime complexity have become impossible when run using JDK 9 or later. In such cases, an issue will only be reported if the project’s target Java version is 8 or earlier.

```java Bad theme={"system"} java.util.regex.Pattern.compile("(a+)++").matcher( "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"+ "aaaaaaaaaaaaaaa!").matches(); // Compliant java.util.regex.Pattern.compile("(h|h|ih(((i|a|c|c|a|i|i|j|b|a|i|b|a|a|j))+h)ahbfhba|c|i)*+").matcher( "hchcchicihcchciiicichhcichcihcchiihichiciiiihhcchi"+ "cchhcihchcihiihciichhccciccichcichiihcchcihhicchcciicchcccihiiihhihihihi"+ "chicihhcciccchihhhcchichchciihiicihciihcccciciccicciiiiiiiiicihhhiiiihchccch"+ "chhhhiiihchihcccchhhiiiiiiiicicichicihcciciihichhhhchihciiihhiccccccciciihh"+ "ichiccchhicchicihihccichicciihcichccihhiciccccccccichhhhihihhcchchihih"+ "iihhihihihicichihiiiihhhhihhhchhichiicihhiiiiihchccccchichci").matches(); // Compliant ``` ```java Fix theme={"system"} ```

The complexity of an expression is defined by the number of &&, || and condition ? ifTrue : ifFalse operators it contains.

A single expression’s complexity should not become too high to keep the code readable.

```java Bad theme={"system"} if (((condition1 && condition2) || (condition3 && condition4)) && condition5) { ... } ``` ```java Fix theme={"system"} if ( (myFirstCondition() || mySecondCondition()) && myLastCondition()) { ... } ```

A cross-site request forgery (CSRF) attack occurs when a trusted user of a web application can be forced, by an attacker, to perform sensitive actions that he didn’t intend, such as updating his profile or sending a message, more generally anything that can change the state of the application.

The attacker can trick the user/victim to click on a link, corresponding to the privileged action, or to visit a malicious web site that embeds a hidden web request and as web browsers automatically include cookies, the actions can be authenticated and sensitive.

```java Bad theme={"system"} @EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { // http.csrf().disable(); // Compliant } } ``` ```java Fix theme={"system"} ```

Type parameters that aren’t used are dead code, which can only distract and possibly confuse developers during maintenance. Therefore, unused type parameters should be removed.

```java Bad theme={"system"} int Add(int a, int b) // Noncompliant; is ignored { return a + b; } ``` ```java Fix theme={"system"} int Add(int a, int b) { return a + b; } ```

When executing an OS command and unless you specify the full path to the executable, then the locations in your application’s PATH environment variable will be searched for the executable. That search could leave an opening for an attacker if one of the elements in PATH is a directory under his control.

```java Bad theme={"system"} Runtime.getRuntime().exec("/usr/bin/make"); // Compliant Runtime.getRuntime().exec(new String[]{"~/bin/make"}); // Compliant ProcessBuilder builder = new ProcessBuilder("./bin/make"); // Compliant builder.command("../bin/make"); // Compliant builder.command(Arrays.asList("..\bin\make", "-j8")); // Compliant builder = new ProcessBuilder(Arrays.asList(".\make")); // Compliant builder.command(Arrays.asList("C:\bin\make", "-j8")); // Compliant builder.command(Arrays.asList("\\SERVER\bin\make")); // Compliant ``` ```java Fix theme={"system"} ```

When arithmetic is performed on integers, the result will always be an integer. You can assign that result to a \`long, double, or float with automatic type conversion, but having started as an int or long, the result will likely not be what you expect.

For instance, if the result of int division is assigned to a floating-point variable, precision will have been lost before the assignment. Likewise, if the result of multiplication is assigned to a long\`, it may have already overflowed before the assignment.

In either case, the result will not be what was expected. Instead, at least one operand should be cast or promoted to the final type before the operation takes place.

```java Bad theme={"system"} float twoThirds = 2/3; // Noncompliant; int division. Yields 0.0 long millisInYear = 1_000*3_600*24*365; // Noncompliant; int multiplication. Yields 1471228928 long bigNum = Integer.MAX_VALUE + 2; // Noncompliant. Yields -2147483647 long bigNegNum = Integer.MIN_VALUE-1; //Noncompliant, gives a positive result instead of a negative one. Date myDate = new Date(seconds * 1_000); //Noncompliant, won't produce the expected result if seconds > 2_147_483 ... public long compute(int factor){ return factor * 10_000; //Noncompliant, won't produce the expected result if factor > 214_748 } public float compute2(long factor){ return factor / 123; //Noncompliant, will be rounded to closest long integer } ``` ```java Fix theme={"system"} float twoThirds = 2f/3; // 2 promoted to float. Yields 0.6666667 long millisInYear = 1_000L*3_600*24*365; // 1000 promoted to long. Yields 31_536_000_000 long bigNum = Integer.MAX_VALUE + 2L; // 2 promoted to long. Yields 2_147_483_649 long bigNegNum = Integer.MIN_VALUE-1L; // Yields -2_147_483_649 Date myDate = new Date(seconds * 1_000L); ... public long compute(int factor){ return factor * 10_000L; } public float compute2(long factor){ return factor / 123f; } ```

Having a permissive Cross-Origin Resource Sharing policy is security-sensitive. It has led in the past to the following vulnerabilities:

Same origin policy in browsers prevents, by default and for security-reasons, a javascript frontend to perform a cross-origin HTTP request to a resource that has a different origin (domain, protocol, or port) from its own. The requested target can append additional HTTP headers in response, called CORS, that act like directives for the browser and change the access control policy / relax the same origin policy.

```java Bad theme={"system"} @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.setHeader("Content-Type", "text/plain; charset=utf-8"); resp.setHeader("Access-Control-Allow-Origin", "*"); // Sensitive resp.setHeader("Access-Control-Allow-Credentials", "true"); resp.setHeader("Access-Control-Allow-Methods", "GET"); resp.getWriter().write("response"); } ``` ```java Fix theme={"system"} @CrossOrigin // Sensitive @RequestMapping("") public class TestController { public String home(ModelMap model) { model.addAttribute("message", "ok "); return "view"; } } ```

The use of break and continue statements increases the complexity of the control flow and makes it harder to understand the program logic. In order to keep a good program structure, they should not be applied more than once per loop.

This rule reports an issue when there is more than one break or continue statement in a loop. The code should be refactored to increase readability if there is more than one.

```java Bad theme={"system"} for (int i = 1; i <= 10; i++) { // Noncompliant; two "continue" statements if (i % 2 == 0) { continue; } if (i % 3 == 0) { continue; } // ... } ``` ```java Fix theme={"system"} for (int i = 1; i <= 10; i++) { if (i % 2 == 0 || i % 3 == 0) { continue; } // ... } ```

Character classes in regular expressions are a convenient way to match one of several possible characters by listing the allowed characters or ranges of characters. If a character class contains only one character, the effect is the same as just writing the character without a character class.

Thus, having only one character in a character class is usually a simple oversight that remained after removing other characters of the class.

```java Bad theme={"system"} "a[b]c" "[\\^]" ``` ```java Fix theme={"system"} "abc" "\\^" "a[*]c" // Compliant, see Exceptions ```

Declaring a variable only to immediately return or throw it is considered a bad practice because it adds unnecessary complexity to the code. This practice can make the code harder to read and understand, as it introduces an extra step that doesn’t add any value. Instead of declaring a variable and then immediately returning or throwing it, it is generally better to return or throw the value directly. This makes the code cleaner, simpler, and easier to understand.

```java Bad theme={"system"} public long computeDurationInMilliseconds() { long duration = (((hours * 60) + minutes) * 60 + seconds) * 1000; return duration; } ``` ```java Fix theme={"system"} public long computeDurationInMilliseconds() { return (((hours * 60) + minutes) * 60 + seconds) * 1000; } ```

The use of a comparison operator outside of a boolean context is an error. At best it is meaningless code, and should be eliminated. However the far more likely scenario is that it is an assignment gone wrong, and should be corrected.

```java Bad theme={"system"} private void called(int foo) { foo==1; // Noncompliant if (foo==1) { System.out.println("foo\n"); } } public void caller(String [ ] args { called(2); return 0; } ``` ```java Fix theme={"system"} private void called(int foo) { foo=1; if (foo==1) { System.out.println("foo\n"); } } public void caller(String [ ] args { called(2); return 0; } ```

Development tools and frameworks usually have options to make debugging easier for developers. Although these features are useful during development, they should never be enabled for applications deployed in production. Debug instructions or error messages can leak detailed information about the system, like the application’s path or file names.

```java Bad theme={"system"} try { /* ... */ } catch(Exception e) { e.printStackTrace(); // Sensitive } ``` ```java Fix theme={"system"} import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; @Configuration @EnableWebSecurity(debug = true) // Sensitive public class WebSecurityConfig extends WebSecurityConfigurerAdapter { // ... } ```

In software development, logs serve as a record of events within an application, providing crucial insights for debugging. When logging, it is essential to ensure that the logs are:

  • easily accessible

  • uniformly formatted for readability

  • properly recorded

  • securely logged when dealing with sensitive data

Those requirements are not met if a program directly writes to the standard outputs (e.g., \{language\_std\_outputs}). That is why defining and using a dedicated logger is highly recommended.

```java Bad theme={"system"} class MyClass { public void doSomething() { System.out.println("My Message"); // Noncompliant, output directly to System.out without a logger } } ``` ```java Fix theme={"system"} import java.util.logging.Logger; class MyClass { Logger logger = Logger.getLogger(getClass().getName()); public void doSomething() { // ... logger.info("My Message"); // Compliant, output via logger // ... } } ```

Shadowing makes it impossible to use the type parameter from the outer scope. Also, it can be confusing to distinguish which type parameter is being used.

This rule raises an issue when a type parameter from an inner scope uses the same name as one in an outer scope.

```java Bad theme={"system"} public class TypeParameterHidesAnotherType { public class Inner { // Noncompliant //... } private T method() { // Noncompliant return null; } } ``` ```java Fix theme={"system"} public class NoTypeParameterHiding { public class Inner { // Compliant List listOfS; } private V method() { // Compliant return null; } } ```

Magic numbers make the code more complex to understand as it requires the reader to have knowledge about the global context to understand the number itself. Their usage may seem obvious when writing the code, but it may not be the case for another developer or later once the context faded away. -1, 0, and 1 are not considered magic numbers.

```java Bad theme={"system"} public static void doSomething() { for (int i = 0; i < 4; i++) { // Noncompliant, 4 is a magic number ... } } ``` ```java Fix theme={"system"} public static final int NUMBER_OF_CYCLES = 4; public static void doSomething() { for (int i = 0; i < NUMBER_OF_CYCLES ; i++) { // Compliant ... } } ```

This rule is meant to be used as a way to track code which is marked as being deprecated. Deprecated code should eventually be removed.

```java Bad theme={"system"} class Foo { /** * @deprecated */ public void foo() { // Noncompliant } @Deprecated // Noncompliant public void bar() { } public void baz() { // Compliant } } ``` ```java Fix theme={"system"} ```

Integer literals starting with a zero are octal rather than decimal values. While using octal values is fully supported, most developers do not have experience with them. They may not recognize octal values as such, mistaking them instead for decimal values.

```java Bad theme={"system"} int myNumber = 010; // Noncompliant. myNumber will hold 8, not 10 - was this really expected? ``` ```java Fix theme={"system"} int myNumber = 8; ```

Using pseudorandom number generators (PRNGs) is security-sensitive. For example, it has led in the past to the following vulnerabilities:

When software generates predictable values in a context requiring unpredictability, it may be possible for an attacker to guess the next value that will be generated, and use this guess to impersonate another user or access sensitive information.

```java Bad theme={"system"} SecureRandom random = new SecureRandom(); // Compliant for security-sensitive use cases byte bytes[] = new byte[20]; random.nextBytes(bytes); ``` ```java Fix theme={"system"} ```

Because it is easy to extract strings from an application source code or binary, secrets should not be hard-coded. This is particularly true for applications that are distributed or that are open-source.

In the past, it has led to the following vulnerabilities:

Secrets should be stored outside of the source code in a configuration file or a management service for secrets.

This rule detects variables/fields having a name matching a list of words (secret, token, credential, auth, api\[\_.-]?key) being assigned a pseudorandom hard-coded value. The pseudorandomness of the hard-coded value is based on its entropy and the probability to be human-readable. The randomness sensibility can be adjusted if needed. Lower values will detect less random values, raising potentially more false positives.

```java Bad theme={"system"} private static final String MY_SECRET = "47828a8dd77ee1eb9dde2d5e93cb221ce8c32b37"; public static void main(String[] args) { MyClass.callMyService(MY_SECRET); } ``` ```java Fix theme={"system"} import software.amazon.awssdk.services.secretsmanager.model.GetSecretValueRequest; import software.amazon.awssdk.services.secretsmanager.model.GetSecretValueResponse; public static void main(String[] args) { SecretsManagerClient secretsClient = ... MyClass.doSomething(secretsClient, "MY_SERVICE_SECRET"); } public static void doSomething(SecretsManagerClient secretsClient, String secretName) { GetSecretValueRequest valueRequest = GetSecretValueRequest.builder() .secretId(secretName) .build(); GetSecretValueResponse valueResponse = secretsClient.getSecretValue(valueRequest); String secret = valueResponse.secretString(); // do something with the secret MyClass.callMyService(secret); } ```

When exceptions occur, it is usually a bad idea to simply ignore them. Instead, it is better to handle them properly, or at least to log them.

```java Bad theme={"system"} public void doTheThing() { try { // ... catch (IOException e) { // Noncompliant } } ``` ```java Fix theme={"system"} public void doTheThing() throws IOException { // ... } ```

Whenever there are portions of code that are duplicated and do not depend on the state of their container class, they can be centralized inside a "utility class". A utility class is a class that only has static members, hence it should not be instantiated.

```java Bad theme={"system"} class StringUtils { // Noncompliant public static String concatenate(String s1, String s2) { return s1 + s2; } } ``` ```java Fix theme={"system"} class StringUtils { // Compliant private StringUtils() { throw new IllegalStateException("Utility class"); } public static String concatenate(String s1, String s2) { return s1 + s2; } } ```

Successful Zip Bomb attacks occur when an application expands untrusted archive files without controlling the size of the expanded data, which can lead to denial of service. A Zip bomb is usually a malicious archive file of a few kilobytes of compressed data but turned into gigabytes of uncompressed data. To achieve this extreme compression ratio, attackers will compress irrelevant data (eg: a long string of repeated bytes).

```java Bad theme={"system"} File f = new File("ZipBomb.zip"); ZipFile zipFile = new ZipFile(f); Enumeration entries = zipFile.entries(); int THRESHOLD_ENTRIES = 10000; int THRESHOLD_SIZE = 1000000000; // 1 GB double THRESHOLD_RATIO = 10; int totalSizeArchive = 0; int totalEntryArchive = 0; while(entries.hasMoreElements()) { ZipEntry ze = entries.nextElement(); InputStream in = new BufferedInputStream(zipFile.getInputStream(ze)); OutputStream out = new BufferedOutputStream(new FileOutputStream("./output_onlyfortesting.txt")); totalEntryArchive ++; int nBytes = -1; byte[] buffer = new byte[2048]; int totalSizeEntry = 0; while((nBytes = in.read(buffer)) > 0) { // Compliant out.write(buffer, 0, nBytes); totalSizeEntry += nBytes; totalSizeArchive += nBytes; double compressionRatio = totalSizeEntry / ze.getCompressedSize(); if(compressionRatio > THRESHOLD_RATIO) { // ratio between compressed and uncompressed data is highly suspicious, looks like a Zip Bomb Attack break; } } if(totalSizeArchive > THRESHOLD_SIZE) { // the uncompressed data size is too much for the application resource capacity break; } if(totalEntryArchive > THRESHOLD_ENTRIES) { // too much entries in this archive, can lead to inodes exhaustion of the system break; } } ``` ```java Fix theme={"system"} ```

An HTTP method is safe when used to perform a read-only operation, such as retrieving information. In contrast, an unsafe HTTP method is used to change the state of an application, for instance to update a user’s profile on a web application.

Common safe HTTP methods are GET, HEAD, or OPTIONS.

Common unsafe HTTP methods are POST, PUT and DELETE.

Allowing both safe and unsafe HTTP methods to perform a specific operation on a web application could impact its security, for example CSRF protections are most of the time only protecting operations performed by unsafe HTTP methods.

```java Bad theme={"system"} @RequestMapping("/delete_user", method = RequestMethod.POST) // Compliant public String delete1(String username) { // state of the application will be changed here } @RequestMapping(path = "/delete_user", method = RequestMethod.POST) // Compliant String delete2(@RequestParam("id") String id) { // state of the application will be changed here } ``` ```java Fix theme={"system"} ```

Nested code - blocks of code inside blocks of code - is eventually necessary, but increases complexity. This is why keeping the code as flat as possible, by avoiding unnecessary nesting, is considered a good practice.

Merging if statements when possible will decrease the nesting of the code and improve its readability.

```java Bad theme={"system"} if (condition1) { if (condition2) { // Noncompliant /* ... */ } } ``` ```java Fix theme={"system"} if (condition1 && condition2) { // Compliant /* ... */ } ```

An empty \{operationName} is generally considered bad practice and can lead to confusion, readability, and maintenance issues. Empty \{operationName}s bring no functionality and are misleading to others as they might think the \{operationName} implementation fulfills a specific and identified requirement.

There are several reasons for a \{operationName} not to have a body:

  • It is an unintentional omission, and should be fixed to prevent an unexpected behavior in production.

  • It is not yet, or never will be, supported. In this case an exception should be thrown.

  • The method is an intentionally-blank override. In this case a nested comment should explain the reason for the blank override.

```java Bad theme={"system"} public abstract class Animal { void speak() { // default implementation ignored } } ``` ```java Fix theme={"system"} public void shouldNotBeEmpty() { // Noncompliant - method is empty } public void notImplemented() { // Noncompliant - method is empty } @Override public void emptyOnPurpose() { // Noncompliant - method is empty } ```

One way to test for empty lines is to use the regex \`"^\$", which can be extremely handy when filtering out empty lines from collections of Strings, for instance. With regard to this, the Javadoc for Pattern (Line Terminators) states the following:

By default, the regular expressions ^ and $ignore line terminators and only match at the beginning and the end, respectively, of the entire input sequence. If MULTILINE mode is activated then ^ matches at the beginning of input and after any line terminator except at the end of input. When in MULTILINE mode$ matches just before a line terminator or the end of the input sequence.

As emphasized, ^ is not going to match at the end of an input, and the end of the input is necessarily included in the empty string, which might lead to completely missing empty lines, while it would be the initial reason for using such regex.

Therefore, when searching for empty lines using a multi-line regular expression, you should also check whether the string is empty.

This rule is raising an issue every time a pattern that can match the empty string is used with MULTILINE flag and without calling isEmpty()\` on the string.

```java Bad theme={"system"} static final Pattern p = Pattern.compile("^$", Pattern.MULTILINE); // Noncompliant // Alternatively static final Pattern p = Pattern.compile("(?m)^$"); // Noncompliant boolean containsEmptyLines(String str) { return p.matcher(str).find(); } // ... System.out.println(containsEmptyLines("a\n\nb")); // correctly prints 'true' System.out.println(containsEmptyLines("")); // incorrectly prints 'false' ``` ```java Fix theme={"system"} static final Pattern p = Pattern.compile("^$", Pattern.MULTILINE); boolean containsEmptyLines(String str) { return p.matcher(str).find() || str.isEmpty(); } // ... System.out.println(containsEmptyLines("a\n\nb")); // correctly prints 'true' System.out.println(containsEmptyLines("")); // also correctly prints 'true' ```

Using upper case literal suffixes removes the potential ambiguity between "1" (digit 1) and "l" (letter el) for declaring literals.

```java Bad theme={"system"} long long1 = 1l; // Noncompliant float float1 = 1.0f; // Noncompliant double double1 = 1.0d; // Noncompliant ``` ```java Fix theme={"system"} long long1 = 1L; float float1 = 1.0F; double double1 = 1.0D; ```

Lookahead assertions are a regex feature that makes it possible to look ahead in the input without consuming it. It is often used at the end of regular expressions to make sure that substrings only match when they are followed by a specific pattern.

For example, the following pattern will match an "a" only if it is directly followed by a "b". This does not consume the "b" in the process:

Unresolved directive in \ - include::\{lookahead}\[]

However, lookaheads can also be used in the middle (or at the beginning) of a regex. In that case there is the possibility that what comes after the lookahead contradicts the pattern inside the lookahead. Since the lookahead does not consume input, this makes the lookahead impossible to match and is a sign that there’s a mistake in the regular expression that should be fixed.

```java Bad theme={"system"} Pattern.compile("(?=a)b"); // Noncompliant, the same character can't be equal to 'a' and 'b' at the same time ``` ```java Fix theme={"system"} Pattern.compile("(?<=a)b"); Pattern.compile("a(?=b)"); ```

Clear-text protocols such as \`ftp, telnet, or http lack encryption of transported data, as well as the capability to build an authenticated connection. It means that an attacker able to sniff traffic from the network can read, modify, or corrupt the transported content. These protocols are not secure as they expose applications to an extensive range of risks:

  • sensitive data exposure

  • traffic redirected to a malicious endpoint

  • malware-infected software update or installer

  • execution of client-side code

  • corruption of critical information

Even in the context of isolated networks like offline environments or segmented cloud environments, the insider threat exists. Thus, attacks involving communications being sniffed or tampered with can still happen.

For example, attackers could successfully compromise prior security layers by:

  • bypassing isolation mechanisms

  • compromising a component of the network

  • getting the credentials of an internal IAM account (either from a service account or an actual person)

In such cases, encrypting communications would decrease the chances of attackers to successfully leak data or steal credentials from other network components. By layering various security practices (segmentation and encryption, for example), the application will follow the defense-in-depth principle.

Note that using the http\` protocol is being deprecated by major web browsers.

In the past, it has led to the following vulnerabilities:

```java Bad theme={"system"} TelnetClient telnet = new TelnetClient(); // Sensitive FTPClient ftpClient = new FTPClient(); // Sensitive SMTPClient smtpClient = new SMTPClient(); // Sensitive ``` ```java Fix theme={"system"} ConnectionSpec spec = new ConnectionSpec.Builder(ConnectionSpec.CLEARTEXT) // Sensitive .build(); ```

When a cookie is configured with the HttpOnly attribute set to true, the browser guaranties that no client-side script will be able to read it. In most cases, when a cookie is created, the default value of HttpOnly is false and it’s up to the developer to decide whether or not the content of the cookie can be read by the client-side script. As a majority of Cross-Site Scripting (XSS) attacks target the theft of session-cookies, the HttpOnly attribute can help to reduce their impact as it won’t be possible to exploit the XSS vulnerability to steal session-cookies.

```java Bad theme={"system"} Cookie c = new Cookie(COOKIENAME, sensitivedata); c.setHttpOnly(true); // Compliant: this sensitive cookie is protected against theft (HttpOnly=true) ``` ```java Fix theme={"system"} ```

Array designators should always be located on the type for better code readability. Otherwise, developers must look both at the type and the variable name to know whether or not a variable is an array.

```java Bad theme={"system"} int matrix[][]; // Noncompliant int[] matrix[]; // Noncompliant ``` ```java Fix theme={"system"} int[][] matrix; // Compliant ```

If a private field is declared but not used locally, its limited visibility makes it dead code.

This is either a sign that some logic is missing or that the code should be cleaned.

Cleaning out dead code decreases the size of the maintained codebase, making it easier to understand and preventing bugs from being introduced.

```java Bad theme={"system"} public class MyClass { private int foo = 42; // Noncompliant: foo is unused and should be removed public int compute(int a) { return a * 42; } } ``` ```java Fix theme={"system"} public class MyClass implements java.io.Serializable { private static final long serialVersionUID = 42L; // Compliant by exception } ```

Casting expressions are utilized to convert one data type to another, such as transforming an integer into a string. This is especially crucial in strongly typed languages like C, C++, C#, Java, Python, and others.

However, there are instances where casting expressions are not needed. These include situations like:

  • casting a variable to its own type

  • casting a subclass to a parent class (in the case of polymorphism)

  • the programming language is capable of automatically converting the given type to another

These scenarios are considered unnecessary casting expressions. They can complicate the code and make it more difficult to understand, without offering any advantages.

As a result, it’s generally advised to avoid unnecessary casting expressions. Instead, rely on the language’s type system to ensure type safety and code clarity.

```java Bad theme={"system"} class A {} class B extends A{} class C { void fun(A a){} void fun(B b){} void foo() { B b = new B(); fun(b); fun((A) b); // Compliant, required to call the first method so cast is not redundant. } } ``` ```java Fix theme={"system"} class Example { public void example(List list) { for (String item: (List) list) { // Noncompliant, Remove this unnecessary cast to "List". //... } } } ```

A regular expression is a sequence of characters that specifies a match pattern in text. Among the most important concepts are:

  • Character classes: defines a set of characters, any one of which can occur in an input string for a match to succeed.

  • Quantifiers: used to specify how many instances of a character, group, or character class must be present in the input for a match.

  • Wildcard (.): matches all characters except line terminators (also matches them if the s flag is set).

Many of these features include shortcuts of widely used expressions, so there is more than one way to construct a regular expression to achieve the same results. For example, to match a two-digit number, one could write \[0-9]\{2,2} or \d\{2}. The latter is not only shorter but easier to read and thus to maintain.

This rule recommends replacing some quantifiers and character classes with more concise equivalents:

  • \d for \[0-9] and \D for \[^0-9]

  • \w for \[A-Za-z0-9\_] and \W for \`\[^A-Za-z0-9\_]

  • . for character classes matching everything (e.g. \[\w\W], \[\d\D], or \[\s\S] with s flag)

  • x? for x\{0,1}, x\* for x\{0,}, x+ for x\{1,}, x\{N} for x\{N,N}\`

```java Bad theme={"system"} "[0-9]" // Noncompliant - same as "\\d" "[^0-9]" // Noncompliant - same as "\\D" "[A-Za-z0-9_]" // Noncompliant - same as "\\w" "[\\w\\W]" // Noncompliant - same as "." "a{0,}" // Noncompliant - same as "a*" ``` ```java Fix theme={"system"} "\\d" "\\D" "\\w" "." "a*" ```

Arbitrary OS command injection vulnerabilities are more likely when a shell is spawned rather than a new process, indeed shell meta-chars can be used (when parameters are user-controlled for instance) to inject OS commands.

```java Bad theme={"system"} Runtime.getRuntime().exec("/usr/bin/file.exe"); // Compliant ProcessBuilder pb = new ProcessBuilder("/usr/bin/file.exe"); // Compliant pb.command("/usr/bin/file.exe"; // Sensitive. CommandLine cmdLine = CommandLine.parse("/usr/bin/file.exe"); // Compliant DefaultExecutor executor = new DefaultExecutor(); executor.execute(cmdLine); ``` ```java Fix theme={"system"} ```

Even if it is legal, mixing case and non-case labels in the body of a switch statement is very confusing and can even be the result of a typing error.

```java Bad theme={"system"} switch (day) { case MONDAY: case TUESDAY: WEDNESDAY: // Noncompliant; syntactically correct, but behavior is not what's expected doSomething(); break; ... } switch (day) { case MONDAY: break; case TUESDAY: foo:for(int i = 0 ; i < X ; i++) { // Noncompliant; the code is correct and behaves as expected but is barely readable /* ... */ break foo; // this break statement doesn't relate to the nesting case TUESDAY /* ... */ } break; /* ... */ } ``` ```java Fix theme={"system"} switch (day) { case MONDAY: case TUESDAY: case WEDNESDAY: doSomething(); break; ... } switch (day) { case MONDAY: break; case TUESDAY: compute(args); // put the content of the labelled "for" statement in a dedicated method break; /* ... */ } ```

Using the same value on both sides of a binary operator is a code defect. In the case of logical operators, it is either a copy/paste error and, therefore, a bug, or it is simply duplicated code and should be simplified. In the case of bitwise operators and most binary mathematical operators, having the same value on both sides of an operator yields predictable results and should be simplified as well.

```java Bad theme={"system"} if ( a == a ) { // always true doZ(); } if ( a != a ) { // always false doY(); } if ( a == b && a == b ) { // if the first one is true, the second one is too doX(); } if ( a == b || a == b ) { // if the first one is true, the second one is too doW(); } int j = 5 / 5; //always 1 int k = 5 - 5; //always 0 c.equals(c); //always true ``` ```java Fix theme={"system"} float f; if(f != f) { //test for NaN value System.out.println("f is NaN"); } int i = 1 << 1; // Compliant int j = a << a; // Noncompliant ```

When either the equality operator in a null test or the logical operator that follows it is reversed, the code has the appearance of safely null-testing the object before dereferencing it. Unfortunately the effect is just the opposite - the object is null-tested and then dereferenced only if it is null, leading to a guaranteed null pointer dereference.

```java Bad theme={"system"} if (str == null && str.length() == 0) { System.out.println("String is empty"); } if (str != null || str.length() > 0) { System.out.println("String is not empty"); } ``` ```java Fix theme={"system"} if (str == null || str.length() == 0) { System.out.println("String is empty"); } if (str != null && str.length() > 0) { System.out.println("String is not empty"); } ```

Rejecting requests with significant content length is a good practice to control the network traffic intensity and thus resource consumption in order to prevent DoS attacks.

```java Bad theme={"system"} @Bean(name = "multipartResolver") public CommonsMultipartResolver multipartResolver() { CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(); multipartResolver.setMaxUploadSize(104857600); // Sensitive (100MB) return multipartResolver; } @Bean(name = "multipartResolver") public CommonsMultipartResolver multipartResolver() { CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(); // Sensitive, by default if maxUploadSize property is not defined, there is no limit and thus it's insecure return multipartResolver; } @Bean public MultipartConfigElement multipartConfigElement() { MultipartConfigFactory factory = new MultipartConfigFactory(); // Sensitive, no limit by default return factory.createMultipartConfig(); } ``` ```java Fix theme={"system"} @Bean(name = "multipartResolver") public CommonsMultipartResolver multipartResolver() { multipartResolver.setMaxUploadSize(8388608); // Compliant (8 MB) return multipartResolver; } ```

A common code smell that can hinder the clarity of source code is making assignments within sub-expressions. This practice involves assigning a value to a variable inside a larger expression, such as within a loop or a conditional statement.

This practice essentially gives a side-effect to a larger expression, thus making it less readable. This often leads to confusion and potential errors.

```java Bad theme={"system"} void processInput(BufferedReader br) { String line; while ((line = br.readLine()) != null) { processLine(line); } } Object foo; if ((foo = bar()) != null) { // do something with "foo" } ``` ```java Fix theme={"system"} int j, i = j = 0; int k = (j += 1); byte[] result, bresult; result = (bresult = new byte[len]); ```

A chain of if/else if statements is evaluated from top to bottom. At most, only one branch will be executed: the first one with a condition that evaluates to true.

Therefore, duplicating a condition automatically leads to dead code. Usually, this is due to a copy/paste error. At best, it’s simply dead code and at worst, it’s a bug that is likely to induce further bugs as the code is maintained, and obviously it could lead to unexpected behavior.

```java Bad theme={"system"} if (param == 1) openWindow(); else if (param == 2) closeWindow(); else if (param == 1) // Noncompliant moveWindowToTheBackground(); } ``` ```java Fix theme={"system"} if (param == 1) openWindow(); else if (param == 2) closeWindow(); else if (param == 3) moveWindowToTheBackground(); } ```

In regular expressions the boundaries \`^ and \A can only match at the beginning of the input (or, in case of ^ in combination with the MULTILINE flag, the beginning of the line) and \$, \Z and \z only at the end.

These patterns can be misused, by accidentally switching ^ and \$\` for example, to create a pattern that can never match.

```java Bad theme={"system"} // This can never match because $ and ^ have been switched around Pattern.compile("$[a-z]+^"); // Noncompliant ``` ```java Fix theme={"system"} Pattern.compile("^[a-z]+$"); ```

Formatted SQL queries can be difficult to maintain, debug and can increase the risk of SQL injection when concatenating untrusted values into the query. However, this rule doesn’t detect SQL injections (unlike rule S3649), the goal is only to highlight complex/formatted queries.

```java Bad theme={"system"} public User getUser(Connection con, String user) throws SQLException { Statement stmt1 = null; PreparedStatement pstmt = null; String query = "select FNAME, LNAME, SSN " + "from USERS where UNAME=?" try { stmt1 = con.createStatement(); ResultSet rs1 = stmt1.executeQuery("GETDATE()"); pstmt = con.prepareStatement(query); pstmt.setString(1, user); // Good; PreparedStatements escape their inputs. ResultSet rs2 = pstmt.executeQuery(); //... } } public User getUserHibernate(org.hibernate.Session session, String data) { org.hibernate.Query query = session.createQuery("FROM students where fname = ?"); query = query.setParameter(0,data); // Good; Parameter binding escapes all input org.hibernate.Query query2 = session.createQuery("FROM students where fname = " + data); // Sensitive // ... ``` ```java Fix theme={"system"} ```

A typical code smell known as unused function parameters refers to parameters declared in a function but not used anywhere within the function’s body. While this might seem harmless at first glance, it can lead to confusion and potential errors in your code. Disregarding the values passed to such parameters, the function’s behavior will be the same, but the programmer’s intention won’t be clearly expressed anymore. Therefore, removing function parameters that are not being utilized is considered best practice.

```java Bad theme={"system"} void doSomething(int a, int b) { // Noncompliant, "b" is unused compute(a); } ``` ```java Fix theme={"system"} void doSomething(int a) { compute(a); } ```

Public fields in public classes do not respect the encapsulation principle and have three main disadvantages:

  • Additional behavior such as validation cannot be added.

  • The internal representation is exposed, and cannot be changed afterwards.

  • Member values are subject to change from anywhere in the code and may not meet the programmer’s assumptions.

To prevent unauthorized modifications, private attributes and accessor methods (set and get) should be used.

```java Bad theme={"system"} public class MyClass { public static final int SOME_CONSTANT = 0; // Compliant - constants are not checked public String firstName; // Noncompliant } ``` ```java Fix theme={"system"} public class MyClass { public static final int SOME_CONSTANT = 0; // Compliant - constants are not checked private String firstName; public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } } ```

Storing data locally is a common task for mobile applications. Such data includes files among other things. One convenient way to store files is to use the external file storage which usually offers a larger amount of disc space compared to internal storage.

Files created on the external storage are globally readable and writable. Therefore, a malicious application having the permissions WRITE\_EXTERNAL\_STORAGE or READ\_EXTERNAL\_STORAGE could try to read sensitive information from the files that other applications have stored on the external storage.

External storage can also be removed by the user (e.g when based on SD card) making the files unavailable to the application.

```java Bad theme={"system"} import android.content.Context; public class AccessExternalFiles { public void accessFiles(Context context) { context.getFilesDir(); } } ``` ```java Fix theme={"system"} ```

When placing Unicode Grapheme Clusters (characters which require to be encoded in multiple Code Points) inside a character class of a regular expression, this will likely lead to unintended behavior.

For instance, the grapheme cluster c̈ requires two code points: one for 'c', followed by one for the umlaut modifier '\u\{0308}'. If placed within a character class, such as \[c̈], the regex will consider the character class being the enumeration \[c\u\{0308}] instead. It will, therefore, match every 'c' and every umlaut that isn’t expressed as a single codepoint, which is extremely unlikely to be the intended behavior.

This rule raises an issue every time Unicode Grapheme Clusters are used within a character class of a regular expression.

```java Bad theme={"system"} "cc̈d̈d".replaceAll("[c̈d̈]", "X"); // Noncompliant, print "XXXXXX" instead of expected "cXXd". ``` ```java Fix theme={"system"} "cc̈d̈d".replaceAll("c̈|d̈", "X"); // print "cXXd" ```

Shared naming conventions improve readability and allow teams to collaborate efficiently. This rule checks that all package names match a provided regular expression.

```java Bad theme={"system"} package org.exAmple; // Noncompliant ``` ```java Fix theme={"system"} package org.example; ```

Constructing arguments of system commands from user input is security-sensitive. It has led in the past to the following vulnerabilities:

Arguments of system commands are processed by the executed program. The arguments are usually used to configure and influence the behavior of the programs. Control over a single argument might be enough for an attacker to trigger dangerous features like executing arbitrary commands or writing files into specific directories.

```java Bad theme={"system"} String input = request.getParameter("input"); if (allowed.contains(input)) { String cmd[] = new String[] { "/usr/bin/find", input }; Runtime.getRuntime().exec(cmd); } ``` ```java Fix theme={"system"} ```

Hard-coding a URI makes it difficult to test a program for a variety of reasons:

  • path literals are not always portable across operating systems

  • a given absolute path may not exist in a specific test environment

  • a specified Internet URL may not be available when executing the tests

  • production environment filesystems usually differ from the development environment

In addition, hard-coded URIs can contain sensitive information, like IP addresses, and they should not be stored in the code.

For all those reasons, a URI should never be hard coded. Instead, it should be replaced by a customizable parameter.

Further, even if the elements of a URI are obtained dynamically, portability can still be limited if the path delimiters are hard-coded.

This rule raises an issue when URIs or path delimiters are hard-coded.

```java Bad theme={"system"} public class Foo { public Collection listUsers() { File userList = new File("/home/mylogin/Dev/users.txt"); // Noncompliant Collection users = parse(userList); return users; } } ``` ```java Fix theme={"system"} public class Foo { // Configuration is a class that returns customizable properties: it can be mocked to be injected during tests. private Configuration config; public Foo(Configuration myConfig) { this.config = myConfig; } public Collection listUsers() { // Find here the way to get the correct folder, in this case using the Configuration object String listingFolder = config.getProperty("myApplication.listingFolder"); // and use this parameter instead of the hard coded path File userList = new File(listingFolder, "users.txt"); // Compliant Collection users = parse(userList); return users; } } ```

This rule applies whenever an \`if statement is followed by one or more else if statements; the final else if should be followed by an else statement.

The requirement for a final else statement is defensive programming.

The else statement should either take appropriate action or contain a suitable comment as to why no action is taken. This is consistent with the requirement to have a final default clause in a switch\` statement.

```java Bad theme={"system"} if (x == 0) { doSomething(); } else if (x == 1) { doSomethingElse(); } ``` ```java Fix theme={"system"} if (x == 0) { doSomething(); } else if (x == 1) { doSomethingElse(); } else { throw new IllegalStateException(); } ```

To reduce the risk of cross-site scripting attacks, templating systems, such as \`Twig, Django, Smarty, Groovy's template engine, allow configuration of automatic variable escaping before rendering templates. When escape occurs, characters that make sense to the browser (eg: \) will be transformed/replaced with escaped/sanitized values (eg: & lt;a& gt; ).

Auto-escaping is not a magic feature to annihilate all cross-site scripting attacks, it depends on the strategy applied and the context, for example a "html auto-escaping" strategy (which only transforms html characters into html entities) will not be relevant when variables are used in a html attribute because ':’ character is not escaped and thus an attack as below is possible:

\link\ // myLink = javascript:alert(document.cookie)
        \link\ // JS injection (XSS attack)
```java Bad theme={"system"} Mustache.compiler().compile(template).execute(context); // Compliant, auto-escaping is enabled by default Mustache.compiler().escapeHTML(true).compile(template).execute(context); // Compliant ``` ```java Fix theme={"system"} freemarker.template.Configuration configuration = new freemarker.template.Configuration(); configuration.setAutoEscapingPolicy(ENABLE_IF_DEFAULT_AUTO_ESCAPING_POLICY); // Compliant ```

Multiple spaces in a regular expression can make it hard to tell how many spaces should be matched. It’s more readable to use only one space and then indicate with a quantifier how many spaces are expected.

```java Bad theme={"system"} Pattern.compile("hello world"); ``` ```java Fix theme={"system"} Pattern.compile("hello {3}world"); ```

User-provided data, such as URL parameters, POST data payloads, or cookies, should always be considered untrusted and tainted. Applications constructing HTTP response headers based on tainted data could allow attackers to change security sensitive headers like Cross-Origin Resource Sharing headers.

Web application frameworks and servers might also allow attackers to inject new line characters in headers to craft malformed HTTP response. In this case the application would be vulnerable to a larger range of attacks like HTTP Response Splitting/Smuggling. Most of the time this type of attack is mitigated by default modern web application frameworks but there might be rare cases where older versions are still vulnerable.

As a best practice, applications that use user-provided data to construct the response header should always validate the data first. Validation should be based on a whitelist.

```java Bad theme={"system"} protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { String value = req.getParameter("value"); resp.addHeader("X-Header", value); // Noncompliant } ``` ```java Fix theme={"system"} protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { String value = req.getParameter("value"); String whitelist = "safevalue1 safevalue2"; if (!whitelist.contains(value)) throw new IOException(); resp.addHeader("X-Header", value); // Compliant } ```

Android applications can receive broadcasts from the system or other applications. Receiving intents is security-sensitive. For example, it has led in the past to the following vulnerabilities:

Receivers can be declared in the manifest or in the code to make them context-specific. If the receiver is declared in the manifest Android will start the application if it is not already running once a matching broadcast is received. The receiver is an entry point into the application.

Other applications can send potentially malicious broadcasts, so it is important to consider broadcasts as untrusted and to limit the applications that can send broadcasts to the receiver.

Permissions can be specified to restrict broadcasts to authorized applications. Restrictions can be enforced by both the sender and receiver of a broadcast. If permissions are specified when registering a broadcast receiver, then only broadcasters who were granted this permission can send a message to the receiver.

This rule raises an issue when a receiver is registered without specifying any broadcast permission.

```java Bad theme={"system"} import android.content.BroadcastReceiver; import android.content.Context; import android.content.IntentFilter; import android.os.Build; import android.os.Handler; import android.support.annotation.RequiresApi; public class MyIntentReceiver { @RequiresApi(api = Build.VERSION_CODES.O) public void register(Context context, BroadcastReceiver receiver, IntentFilter filter, String broadcastPermission, Handler scheduler, int flags) { context.registerReceiver(receiver, filter, broadcastPermission, scheduler); context.registerReceiver(receiver, filter, broadcastPermission, scheduler, flags); } } ``` ```java Fix theme={"system"} ```

When a cookie is protected with the secure attribute set to true it will not be send by the browser over an unencrypted HTTP request and thus cannot be observed by an unauthorized person during a man-in-the-middle attack.

```java Bad theme={"system"} Cookie c = new Cookie(COOKIENAME, sensitivedata); c.setSecure(true); // Compliant: the sensitive cookie will not be send during an unencrypted HTTP request thanks to the secure flag set to true ``` ```java Fix theme={"system"} ```

If a label is declared but not used in the program, it can be considered as dead code and should therefore be removed.

This will improve maintainability as developers will not wonder what this label is used for.

```java Bad theme={"system"} void foo() { outer: //label is not used. for(int i = 0; i<10; i++) { break; } } ``` ```java Fix theme={"system"} void foo() { for(int i = 0; i<10; i++) { break; } } ```

Android comes with Android KeyStore, a secure container for storing key materials. It’s possible to define certain keys to be unlocked when users authenticate using biometric credentials. This way, even if the application process is compromised, the attacker cannot access keys, as presence of the authorized user is required.

These keys can be used, to encrypt, sign or create a message authentication code (MAC) as proof that the authentication result has not been tampered with. This protection defeats the scenario where an attacker with physical access to the device would try to hook into the application process and call the \`onAuthenticationSucceeded method directly. Therefore he would be unable to extract the sensitive data or to perform the critical operations protected by the biometric authentication.

Ask Yourself Whether

The application contains:

  • Cryptographic keys / sensitive information that need to be protected using biometric authentication.

There is a risk if you answered yes to this question.

Recommended Secure Coding Practices

It’s recommended to tie the biometric authentication to a cryptographic operation by using a CryptoObject\` during authentication.

```java Bad theme={"system"} // ... BiometricPrompt biometricPrompt = new BiometricPrompt(activity, executor, callback); // ... biometricPrompt.authenticate(promptInfo); // Noncompliant ``` ```java Fix theme={"system"} // ... BiometricPrompt biometricPrompt = new BiometricPrompt(activity, executor, callback); // ... biometricPrompt.authenticate(promptInfo, new BiometricPrompt.CryptoObject(cipher)); // Compliant ```

Why use named groups only to never use any of them later on in the code?

This rule raises issues every time named groups are:

  • defined but never called anywhere in the code through their name;

  • defined but called elsewhere in the code by their number instead;

  • referenced while not defined.

```java Bad theme={"system"} String date = "01/02"; Pattern datePattern = Pattern.compile("(?[0-9]{2})/(?[0-9]{2})"); Matcher dateMatcher = datePattern.matcher(date); if (dateMatcher.matches()) { checkValidity(dateMatcher.group(1), dateMatcher.group(2)); // Noncompliant - numbers instead of names of groups are used checkValidity(dateMatcher.group("day")); // Noncompliant - there is no group called "day" } // ... String score = "14:1"; Pattern scorePattern = Pattern.compile("(?[0-9]+):(?[0-9]+)"); // Noncompliant - named groups are never used Matcher scoreMatcher = scorePattern.matcher(score); if (scoreMatcher.matches()) { checkScore(score); } ``` ```java Fix theme={"system"} String date = "01/02"; Pattern datePattern = Pattern.compile("(?[0-9]{2})/(?[0-9]{2})"); Matcher dateMatcher = datePattern.matcher(date); if (dateMatcher.matches()) { checkValidity(dateMatcher.group("month"), dateMatcher.group("year")); } // ... String score = "14:1"; Pattern scorePattern = Pattern.compile("(?[0-9]+):(?[0-9]+)"); Matcher scoreMatcher = scorePattern.matcher(score); if (scoreMatcher.matches()) { checkScore(scoreMatcher.group("player1")); checkScore(scoreMatcher.group("player2")); } ```

Nested control flow statements such as if, for, while, switch, and try are often key ingredients in creating what’s known as "Spaghetti code". This code smell can make your program difficult to understand and maintain.

When numerous control structures are placed inside one another, the code becomes a tangled, complex web. This significantly reduces the code’s readability and maintainability, and it also complicates the testing process.

```java Bad theme={"system"} if (condition1) { // Compliant - depth = 1 /* ... */ if (condition2) { // Compliant - depth = 2 /* ... */ for (int i = 0; i < 10; i++) { // Compliant - depth = 3 /* ... */ if (condition4) { // Noncompliant - depth = 4, which exceeds the limit if (condition5) { // Depth = 5, exceeding the limit, but issues are only reported on depth = 4 /* ... */ } return; } } } } ``` ```java Fix theme={"system"} if (!condition1) { return; } /* ... */ if (!condition2) { return; } for (int i = 0; i < 10; i++) { /* ... */ if (condition4) { if (condition5) { /* ... */ } return; } } ```

There is no good reason to create a new object to not do anything with it. Most of the time, this is due to a missing piece of code and so could lead to an unexpected behavior in production.

If it was done on purpose because the constructor has side-effects, then that side-effect code should be moved into a separate method and called directly.

```java Bad theme={"system"} if (x < 0) new IllegalArgumentException("x must be nonnegative"); ``` ```java Fix theme={"system"} if (x < 0) throw new IllegalArgumentException("x must be nonnegative"); ```

A catch clause that only rethrows the caught exception has the same effect as omitting the catch altogether and letting it bubble up automatically.

Unresolved directive in \ - include::\{example}\[]

Such clauses should either be removed or populated with the appropriate logic.

Unresolved directive in \ - include::\{compliant}\[]

```java Bad theme={"system"} String readFirstLine(FileReader fileReader) throws IOException { try (BufferedReader br = new BufferedReader(fileReader)) { return br.readLine(); } catch (IOException e) { // Noncompliant throw e; } ``` ```java Fix theme={"system"} String readFirstLine(FileReader fileReader) throws IOException { try (BufferedReader br = new BufferedReader(fileReader)) { return br.readLine(); } } ```

Overriding a method just to call the same method from the super class without performing any other actions is useless and misleading. The only time this is justified is in final overriding methods, where the effect is to lock in the parent class behavior. This rule ignores such overrides of equals, hashCode and toString.

```java Bad theme={"system"} public void doSomething() { super.doSomething(); } @Override public boolean isLegal(Action action) { return super.isLegal(action); } ``` ```java Fix theme={"system"} @Override public boolean isLegal(Action action) { // Compliant - not simply forwarding the call return super.isLegal(new Action(/* ... */)); } @Id @Override public int getId() { // Compliant - there is annotation different from @Override return super.getId(); } ```

Duplicated string literals make the process of refactoring complex and error-prone, as any change would need to be propagated on all occurrences.

```java Bad theme={"system"} public void run() { prepare("action1"); // Noncompliant - "action1" is duplicated 3 times execute("action1"); release("action1"); } @SuppressWarning("all") // Compliant - annotations are excluded private void method1() { /* ... */ } @SuppressWarning("all") private void method2() { /* ... */ } public String printInQuotes(String a, String b) { return "'" + a + "'" + b + "'"; // Compliant - literal "'" has less than 5 characters and is excluded } ``` ```java Fix theme={"system"} private static final String ACTION_1 = "action1"; // Compliant public void run() { prepare(ACTION_1); // Compliant execute(ACTION_1); release(ACTION_1); } ```

Altering or bypassing the accessibility of classes, methods, or fields through reflection violates the encapsulation principle. This can break the internal contracts of the accessed target and lead to maintainability issues and runtime errors.

This rule raises an issue when reflection is used to change the visibility of a class, method or field, and when it is used to directly update a field value.

```java Bad theme={"system"} public void makeItPublic(String methodName) throws NoSuchMethodException { this.getClass().getMethod(methodName).setAccessible(true); // Noncompliant } public void setItAnyway(String fieldName, int value) { this.getClass().getDeclaredField(fieldName).setInt(this, value); // Noncompliant; bypasses controls in setter } ``` ```java Fix theme={"system"} ```

When the value of a private field is always assigned to in a class' methods before being read, then it is not being used to store class information. Therefore, it should become a local variable in the relevant methods to prevent any misunderstanding.

```java Bad theme={"system"} public class Foo { private int a; private int b; public void doSomething(int y) { a = y + 5; ... if(a == 0) { ... } ... } public void doSomethingElse(int y) { b = y + 3; ... } } ``` ```java Fix theme={"system"} public class Foo { public void doSomething(int y) { int a = y + 5; ... if(a == 0) { ... } } public void doSomethingElse(int y) { int b = y + 3; ... } } ```
# Java - 4 Source: https://docs.codeant.ai/antipattern-rules/Java/java4 Learn about Java Anti-Patterns and How they help you write better code, and avoid common pitfalls.

There are various String operations that take one or more character indexes as arguments and return a portion of the original string. Indexing in this context is zero-based, meaning that the first character’s index is 0. As a result, given a string myString, its last character is at index myString.length() - 1.

The String operation methods throw a StringIndexOutOfBoundsException when one of their index argument is smaller than 0 (E.G.: -1). String::substring also throws this exception when the beginIndex or endIndex argument is larger than myString.length(), and String::charAt when the index argument is larger than myString.length() - 1 For instance, it is not possible to use String::charAt to retrieve a value before the start or after the end of a string. Furthermore, it is not possible to use String::substring with beginIndex > endIndex to reverse the order of characters in a string.

This rule raises an issue when a negative literal or an index that is too large is passed as an argument to the String::substring, String::charAt, and related methods. It also raises an issue when the start index passed to String::substring is larger than the end index.

```java Bad theme={"system"} String speech = "Lorem ipsum dolor sit amet"; String substr1 = speech.substring(-1, speech.length()); // Noncompliant, -1 is out of bounds String substr2 = speech.substring(speech.length(), 0); // Noncompliant, the beginIndex must be smaller than or equal to the endIndex char ch = speech.charAt(speech.length()); // Noncompliant, speech.length() is out of bounds ``` ```java Fix theme={"system"} String speech = "Lorem ipsum dolor sit amet"; String substr1 = speech; // Compliant, no string operation used String substr2 = new StringBuilder(speech).reverse().toString(); // Compliant, the string can be reversed using StringBuilder::reverse() char ch = speech.charAt(speech.length() - 1); // Compliant, speech.length() - 1 is in bounds. ```

Executing a batch of SQL queries instead of individual queries improves performance by reducing communication overhead with the database.

Batching SQL statements is beneficial in common situations where a SQL statement is executed within a loop. In such cases, adding the statement to a batch and subsequently executing it reduces the number of interactions with the database. This results in improved efficiency and faster execution times.

The rule raises an issue when it detects a java.sql.Statement being executed within a loop instruction, such as for, while or the forEach method of java.lang.Iterable, java.util.Map and java.util.stream.Stream.

```java Bad theme={"system"} public void execute(Connection connection) { try { Statement statement = connection.createStatement(); for (int i = 0; i < 10; i++) { statement.execute("INSERT INTO myTable (column1, column2) VALUES (" + i + ", 'value" + i + "')"); // Noncompliant } statement.close(); connection.close(); } catch (SQLException e) { e.printStackTrace(); } } ``` ```java Fix theme={"system"} public void execute(Connection connection) { try { Statement statement = connection.createStatement(); for (int i = 0; i < 10; i++) { statement.addBatch("INSERT INTO myTable (column1, column2) VALUES (" + i + ", 'value" + i + "')"); // Compliant } statement.executeBatch(); statement.close(); connection.close(); } catch (SQLException e) { e.printStackTrace(); } } ```

When using the \`Stream API, call chains should be simplified as much as possible to improve readability and maintainability.

This rule raises an issue when one of the following substitution can be made:

Original Preferred

stream.collect(counting())

stream.count()

stream.collect(maxBy(comparator))

stream.max(comparator)

stream.collect(minBy(comparator))

stream.min(comparator)

stream.collect(mapping(mapper))

stream.map(mapper).collect()

stream.collect(reducing(...))

stream.reduce(...)

stream.collect(summingInt(mapper))

stream.mapToInt(mapper).sum()

stream.collect(summingLong(mapper))

stream.mapToLong(mapper).sum()

stream.collect(summingDouble(mapper))

stream.mapToDouble(mapper).sum()\`

```java Bad theme={"system"} int count = stream.collect(counting()); // Noncompliant ``` ```java Fix theme={"system"} int count = stream.count(); ```

Synchronization can be expensive in terms of time when multiple threads need to pass through the same bottleneck /\`synchronized piece of code.

If you have a piece of code calling a synchronized method once, then it only has to wait its turn to pass through the bottleneck once. But call it in a loop, and your code has to get back in line for the bottleneck over and over.

Instead, it would be better to get into the bottleneck, and then do the looping. I.e. consider refactoring the code to perform the loop inside the synchronized method.

This rule raises an issue when a synchronized\` method is called in a loop.

```java Bad theme={"system"} public void doSomething(int max) { for (int i = 0; i < max; i++) { doSynchronized(i); // Noncompliant } } public synchronized void doSynchronized(int val) { // ... } ``` ```java Fix theme={"system"} ```

It can be useful to use in-code notation to suppress issues, but when those suppressions are no longer relevant they become a potential source of confusion and should be removed.

```java Bad theme={"system"} @SuppressWarnings("squid:S4174") // Noncompliant public void doSomething() { final int LOCAL = 42; // S4174 is about naming of local constants but there's nothing wrong here ``` ```java Fix theme={"system"} public void doSomething() { final int LOCAL = 42; // S4174 is about naming of local constants but there's nothing wrong here ```

Optional acts as a container object that may or may not contain a non-null value. It is introduced in Java 8 to help avoid NullPointerException. It provides methods to check if a value is present and retrieve the value if it is present.

Optional is used instead of null values to make the code more readable and avoid potential errors.

It is a bad practice to use null with Optional because it is unclear whether a value is present or not, leading to confusion and potential NullPointerException errors.

```java Bad theme={"system"} public void doSomething () { Optional optional = getOptional(); if (optional != null) { // Noncompliant // do something with optional... } Optional text = null; // Noncompliant, a variable whose type is Optional should never itself be null // ... } @Nullable // Noncompliant public Optional getOptional() { // ... return null; // Noncompliant } ``` ```java Fix theme={"system"} public void doSomething () { Optional optional = getOptional(); optional.ifPresent( // do something with optional... ); Optional text = Optional.empty(); // ... } public Optional getOptional() { // ... return Optional.empty(); } ```

Fields, parameters and return values marked `@NotNull, @NonNull, or @Nonnull are assumed to have non-null values and are not typically null-checked before use. Therefore setting one of these values to null, or failing to set such a class field in a constructor, could cause NullPointerException`s at runtime.

```java Bad theme={"system"} public class MainClass { @Nonnull private String primary; private String secondary; public MainClass(String color) { if (color != null) { secondary = null; } primary = color; // Noncompliant; "primary" is Nonnull but could be set to null here } public MainClass() { // Noncompliant; "primary" is Nonnull but is not initialized } @Nonnull public String indirectMix() { String mix = null; return mix; // Noncompliant; return value is Nonnull, but null is returned. } ``` ```java Fix theme={"system"} ```

When a reluctant quantifier (such as \`\*? or +?) is followed by a pattern that can match the empty string or directly by the end of the regex, it will always match the empty string when used with methods that find partial matches (such as find, replaceAll, split etc.).

Similarly, when used with methods that find full matches, a reluctant quantifier that’s followed directly by the end of the regex (or a pattern that always matches the empty string, such as ()\`) behaves indistinguishably from a greedy quantifier while being less efficient.

This is likely a sign that the regex does not work as intended.

```java Bad theme={"system"} "start123endstart456".replaceAll("start\\w*?(end)?", "x"); // Noncompliant. In contrast to what one would expect, the result is not "xx". str.matches("\\d*?"); // Noncompliant. Matches the same as "\d*", but will backtrack in every position. ``` ```java Fix theme={"system"} "start123endstart456".replaceAll("start\\w*?(end|$)", "x"); // Result is "xx". str.matches("\\d*"); ```

A non-serializable Comparator can prevent an otherwise-Serializable ordered collection from being serializable. Since the overhead to make a Comparator serializable is usually low, doing so can be considered good defensive programming.

```java Bad theme={"system"} public class FruitComparator implements Comparator { // Noncompliant int compare(Fruit f1, Fruit f2) {...} boolean equals(Object obj) {...} } ``` ```java Fix theme={"system"} public class FruitComparator implements Comparator, Serializable { private static final long serialVersionUID = 1; int compare(Fruit f1, Fruit f2) {...} boolean equals(Object obj) {...} } ```

In Java, numeric promotions happen when two operands of an arithmetic expression have different sizes. More specifically, narrower operands get promoted to the type of wider operands. For instance, an operation between a byte and an int, will trigger a promotion of the byte operand, converting it into an int.

When this happens, the sequence of 8 bits that represents the byte will need to be extended to match the 32-bit long sequence that represents the int operand. Since Java uses two’s complement notation for signed number types, the promotion will fill the missing leading bits with zeros or ones, depending on the sign of the value. For instance, the byte 0b1000\_0000 (equal to -128 in decimal notation), when promoted to int, will become 0b1111\_1111\_1111\_1111\_1111\_1111\_1000\_0000.

When performing shifting or bitwise operations without considering that bytes are signed, the bits added during the promotion may have unexpected effects on the final result of the operations.

```java Bad theme={"system"} public static void main(String[] args) { byte[] bytes12 = BigInteger.valueOf(12).toByteArray(); // This byte array will be simply [12] System.out.println(intFromBuffer(bytes12)); // In this case, the bytes promotion will not cause any issues, and "12" will be printed. // Here the bytes will be [2, -128] since 640 in binary is represented as 0b0000_0010_1000_0000 // which is equivalent to the concatenation of 2 bytes: 0b0000_0010 = 2, and 0b1000_0000 = -128 byte[] bytes640 = BigInteger.valueOf(640).toByteArray(); // In this case, the shifting operation combined with the bitwise OR, will produce the wrong binary string and "-128" will be printed. System.out.println(intFromBuffer(bytes640)); } static int intFromBuffer(byte[] bytes) { int originalInt = 0; for (int i = 0; i < bytes.length; i++) { // Here the right operand of the bitwise OR, which is a byte, will be promoted to an `int` // and if its value was negative, the added ones in front of the binary string will alter the value of the `originalInt` originalInt = (originalInt << 8) | bytes[i]; // Noncompliant } return originalInt; } ``` ```java Fix theme={"system"} public static void main(String[] args) { byte[] bytes12 = BigInteger.valueOf(12).toByteArray(); // This byte array will be simply [12] System.out.println(intFromBuffer(bytes12)); // In this case, the bytes promotion will not cause any issues, and "12" will be printed. // Here the bytes will be [2, -128] since 640 in binary is represented as 0b0000_0010_1000_0000 // which is equivalent to the concatenation of 2 bytes: 0b0000_0010 = 2, and 0b1000_0000 = -128 byte[] bytes640 = BigInteger.valueOf(640).toByteArray(); // This will correctly print "640" now. System.out.println(intFromBuffer(bytes640)); } static int intFromBuffer(byte[] bytes) { int originalInt = 0; for (int i = 0; i < bytes.length; i++) { originalInt = (originalInt << 8) | Byte.toUnsignedInt(bytes[i]); // Compliant, only the relevant 8 least significant bits will affect the bitwise OR } return originalInt; } ```

Naming conventions play a crucial role in maintaining code clarity and readability. The uniqueness of bean names in Spring configurations is vital to the clarity and readability of the code. When two beans share the same name within a configuration, it is not obvious to the reader which bean is being referred to. This leads to potential misunderstandings and errors.

```java Bad theme={"system"} @Configuration class Config { @Bean public User user() { return currentUser(); } @Bean public User user(AuthService auth) { // Noncompliant return auth.user(); } } ``` ```java Fix theme={"system"} @Configuration class Config { @Bean public User user() { return currentUser(); } @Bean public User userFromAuth(AuthService auth) { return auth.user(); } } ```

When @Overrides of synchronized methods are not themselves synchronized, the result can be improper synchronization as callers rely on the thread-safety promised by the parent class.

```java Bad theme={"system"} public class Parent { synchronized void foo() { //... } } public class Child extends Parent { @Override public void foo () { // Noncompliant // ... super.foo(); } } ``` ```java Fix theme={"system"} public class Parent { synchronized void foo() { //... } } public class Child extends Parent { @Override synchronized void foo () { // ... super.foo(); } } ```

In a multithreaded environment, the Object.wait(…​), as well as Condition.await(…​) and similar methods are used to pause the execution of a thread until the thread is awakened. A thread is typically awakened when it is notified, signaled, or interrupted, usually because of an event in another thread requiring some subsequent action by the waiting thread.

However, a thread may be awakened despite the desired condition not being met or the desired event not having happened. This is referred to as "spurious wakeups" and may be caused by underlying platform semantics. In other words, a thread may be awakened due to reasons that have nothing to do with the business logic. Hence, the assumption that the desired condition is met or the desired event occurred after a thread is awakened does not always hold.

According to the documentation of the Java Condition interface \[1]:

When waiting upon a Condition, a "spurious wakeup" is permitted to occur, in general, as a concession to the underlying platform semantics. This has little practical impact on most application programs as a Condition should always be waited upon in a loop, testing the state predicate that is being waited for. An implementation is free to remove the possibility of spurious wakeups but it is recommended that applications programmers always assume that they can occur and so always wait in a loop.

The same advice is also found for the Object.wait(…​) method \[2]:

\[…​] waits should always occur in loops, like this one:

synchronized (obj) \{
            while (\)\{
            obj.wait(timeout);
            }
            ... // Perform action appropriate to condition
            }
```java Bad theme={"system"} synchronized (obj) { if (!suitableCondition()){ obj.wait(timeout); // Noncompliant, the thread can be awakened even though the condition is still false } ... // Perform some logic that is appropriate for when the condition is true } ``` ```java Fix theme={"system"} synchronized (obj) { while (!suitableCondition()){ obj.wait(timeout); // Compliant, the condition is checked in a loop, so the action below will only occur if the condition is true } ... // Perform some logic that is appropriate for when the condition is true } ```

The use of unnecessary types makes the eye stumble, and inhibits the smooth reading of code.

```java Bad theme={"system"} public void doSomething() { foo("blah"); // Noncompliant; is inferred } public void foo(T t) { // ... } ``` ```java Fix theme={"system"} public void doSomething() { foo("blah"); } public void foo(T t) { // ... } ```

The underlying implementation of \`String::replaceAll calls the java.util.regex.Pattern.compile() method each time it is called even if the first argument is not a regular expression. This has a significant performance cost and therefore should be used with care.

When String::replaceAll is used, the first argument should be a real regular expression. If it’s not the case, String::replace does exactly the same thing as String::replaceAll without the performance drawback of the regex.

This rule raises an issue for each String::replaceAll used with a String\` as first parameter which doesn’t contains special regex character or pattern.

```java Bad theme={"system"} String init = "Bob is a Bird... Bob is a Plane... Bob is Superman!"; String changed = init.replaceAll("Bob is", "It's"); // Noncompliant changed = changed.replaceAll("\\.\\.\\.", ";"); // Noncompliant ``` ```java Fix theme={"system"} String init = "Bob is a Bird... Bob is a Plane... Bob is Superman!"; String changed = init.replace("Bob is", "It's"); changed = changed.replace("...", ";"); ```

Before it reclaims storage from an object that is no longer referenced, the garbage collector calls finalize() on the object.

But there is no guarantee that this method will be called as soon as the last references to the object are removed.

It can be few microseconds to few minutes later.

For this reason relying on overriding the finalize() method to release resources or to update the state of the program is highly discouraged.

```java Bad theme={"system"} public class MyClass { @Override protected void finalize() { // Noncompliant releaseSomeResources(); } } ``` ```java Fix theme={"system"} ```

Creating an object for the sole purpose of calling getClass on it is a waste of memory and cycles. Instead, simply use the class’s .class property.

```java Bad theme={"system"} MyObject myOb = new MyObject(); // Noncompliant Class c = myOb.getClass(); ``` ```java Fix theme={"system"} Class c = MyObject.class; ```

Thread.yield is intended to hint to the processor that the current thread is willing to suspended in favor of another thread. Unfortunately, it doesn’t have the same results across platforms, thus marring the cross-platform compatibility of any application that uses it.

```java Bad theme={"system"} public void doSomething() { // ... Thread.yield(); // Noncompliant // ... } ``` ```java Fix theme={"system"} ```

Java 21 introduces the new Sequenced Collections API, which is applicable to all collections with a defined sequence on their elements, such as LinkedList, TreeSet, and others (see JEP 431). For projects using Java 21 and onwards, this API should be used instead of workaround implementations that were necessary prior to Java 21.

This rule identifies instances where a workaround is used to add or remove the first or last element of a collection where the addFirst, addLast, removeFirst or removeLast method in the java.util.SequencedCollection class should have been used instead.

```java Bad theme={"system"} void push(List list, String element) { list.add(list.size()-1, element); // Noncompliant } ``` ```java Fix theme={"system"} void push(List list, String element) { list.addLast(element); // Compliant } ```

instanceof operators that always return true or false are either useless or the result of a misunderstanding which could lead to unexpected behavior in production.

```java Bad theme={"system"} public boolean isSuitable(Integer param) { ... String name = null; if (name instanceof String) { // Noncompliant; always false since name is null //... } if(param instanceof Number) { // Noncompliant; always true unless param is null, because param is an Integer doSomething(); } ... } ``` ```java Fix theme={"system"} public boolean isSuitable(Integer param) { ... doSomething(); ... } ```

Shared coding conventions allow teams to collaborate efficiently. This rule checks that all local, final, initialized, primitive variables, have names that match a provided regular expression.

```java Bad theme={"system"} public void doSomething() { final int local = 42; ... } ``` ```java Fix theme={"system"} public void doSomething() { final int LOCAL = 42; ... } ```

A Spring @Controller that uses @SessionAttributes is designed to handle a stateful / multi-post form. Such @Controllers use the specified @SessionAttributes to store data on the server between requests. That data should be cleaned up when the session is over, but unless setComplete() is called on the SessionStatus object from a @RequestMapping method, neither Spring nor the JVM will know it’s time to do that. Note that the SessionStatus object must be passed to that method as a parameter.

```java Bad theme={"system"} @Controller @SessionAttributes("hello") // Noncompliant; this doesn't get cleaned up public class HelloWorld { @RequestMapping("/greet", method = GET) public String greet(String greetee) { return "Hello " + greetee; } } ``` ```java Fix theme={"system"} @Controller @SessionAttributes("hello") public class HelloWorld { @RequestMapping("/greet", method = GET) public String greet(String greetee) { return "Hello " + greetee; } @RequestMapping("/goodbye", method = POST) public String goodbye(SessionStatus status) { //... status.setComplete(); } } ```

Spring \`@Controllers, @Services, and @Repositorys have singleton scope by default, meaning only one instance of the class is ever instantiated in the application. Defining any other scope for one of these class types will result in needless churn as new instances are created and destroyed. In a busy web application, this could cause a significant amount of needless additional load on the server.

This rule raises an issue when the @Scope annotation is applied to a @Controller, @Service, or @Repository with any value but "singleton". @Scope("singleton")\` is redundant, but ignored.

```java Bad theme={"system"} @Scope("prototype") // Noncompliant @Controller public class HelloWorld { ``` ```java Fix theme={"system"} @Controller public class HelloWorld { ```

Java 8 introduced \`ThreadLocal.withInitial which is a simpler alternative to creating an anonymous inner class to initialise a ThreadLocal instance.

This rule raises an issue when a ThreadLocal anonymous inner class can be replaced by a call to ThreadLocal.withInitial\`.

```java Bad theme={"system"} ThreadLocal> myThreadLocal = new ThreadLocal>() { // Noncompliant @Override protected List initialValue() { return new ArrayList(); } }; ``` ```java Fix theme={"system"} ThreadLocal> myThreadLocal = ThreadLocal.withInitial(ArrayList::new); ```

java.util.concurrent.locks.Lock offers far more powerful and flexible locking operations than are available with synchronized blocks. So synchronizing on a Lock instance throws away the power of the object, as it overrides its better locking mechanisms. Instead, such objects should be locked and unlocked using one of their lock and unlock method variants.

```java Bad theme={"system"} Lock lock = new MyLockImpl(); synchronized(lock) { // Noncompliant // ... } ``` ```java Fix theme={"system"} Lock lock = new MyLockImpl(); if (lock.tryLock()) { try { // ... } finally { lock.unlock(); } } ```

Floating point math is imprecise because of the challenges of storing such values in a binary representation. Even worse, floating point math is not associative; push a \`float or a double through a series of simple mathematical operations and the answer will be different based on the order of those operation because of the rounding that takes place at each step.

Even simple floating point assignments are not simple:

float f = 0.1; // 0.100000001490116119384765625
        double d = 0.1; // 0.1000000000000000055511151231257827021181583404541015625

(Results will vary based on compiler and compiler settings);

Therefore, the use of the equality (==) and inequality (!=) operators on float or double values is almost always an error. Instead the best course is to avoid floating point comparisons altogether. When that is not possible, you should consider using one of Java’s float-handling Numbers such as BigDecimal which can properly handle floating point comparisons. A third option is to look not for equality but for whether the value is close enough. I.e. compare the absolute value of the difference between the stored value and the expected value against a margin of acceptable error. Note that this does not cover all cases (NaN and Infinity\` for instance).

This rule checks for the use of direct and indirect equality/inequailty tests on floats and doubles.

```java Bad theme={"system"} float myNumber = 3.146; if ( myNumber == 3.146f ) { //Noncompliant. Because of floating point imprecision, this will be false // ... } if ( myNumber != 3.146f ) { //Noncompliant. Because of floating point imprecision, this will be true // ... } if (myNumber < 4 || myNumber > 4) { // Noncompliant; indirect inequality test // ... } float zeroFloat = 0.0f; if (zeroFloat == 0) { // Noncompliant. Computations may end up with a value close but not equal to zero. } ``` ```java Fix theme={"system"} float f; double d; if(f != f) { // Compliant; test for NaN value System.out.println("f is NaN"); } else if (f != d) { // Noncompliant // ... } ```

Persistence annotations should be marked either on fields or on getters but not on both. Mix the two and the annotated fields will be ignored. The potential results are that your database tables are not created or not populated (and read) correctly.

```java Bad theme={"system"} @Entity public class Person { // Noncompliant; both fields and getters annotated @Id private Long id; private String fname; public Long getId() { ... } @Column(name="name") public String getFname() { ... } ``` ```java Fix theme={"system"} @Entity public class Person { @Id private Long id; @Column(name="name") private String fname; public Long getId() { ... } public String getFname() { ... } ```

AssertJ contains many assertions methods specific to common types. Both versions will test the same things, but the dedicated one will provide a better error message, simplifying the debugging process.

This rule reports an issue when an assertion can be simplified to a dedicated one.

The array below gives a non-exhaustive list of assertion reported by the rule. Code behaving similarly, or with a negation will also be reported.

Original Dedicated

Related to Object

\`assertThat(getObject()).isEqualTo(null)

assertThat(getObject()).isNull()

assertThat(getBoolean()).isEqualTo(true)

assertThat(getBoolean()).isTrue()

assertThat(getBoolean()).isEqualTo(false)

assertThat(getBoolean()).isFalse()

assertThat(x.equals(y)).isTrue()

assertThat(x).isEqualTo(y)

```java Bad theme={"system"} assertThat(getObject()).isEqualTo(null); // Noncompliant assertThat(getObject()).isNotEqualTo(null); // Noncompliant - not listed above but also supported assertThat(getString().trim()).isEmpty(); assertThat(getFile().canRead()).isTrue(); assertThat(getPath().getParent()).isNull(); ``` ```java Fix theme={"system"} assertThat(getObject()).isNull(); assertThat(getObject()).isNotNull(); assertThat(getString()).isBlank(); assertThat(getFile()).canRead(); assertThat(getPath()).hasNoParentRaw(); ```

@Configuration is a class-level annotation indicating that an object is a source of bean definitions. @Configuration classes declare beans through @Bean-annotated methods. Calls to @Bean methods on @Configuration classes can also be used to define inter-bean dependencies. The @Bean annotation indicates that a method instantiates, configures, and initializes a new object to be managed by the Spring IoC container.

Annotating a method of a bean with @Async will make it execute in a separate thread. In other words, the caller will not wait for the completion of the called method.

The @Async annotation is not supported on methods declared within a @Configuration class. This is because @Async methods are typically used for asynchronous processing, and they require certain infrastructure to be set up, which may not be available or appropriate in a @Configuration class.

```java Bad theme={"system"} @EnableAsync @Configuration public class MyConfiguration { @Async // Noncompliant - This is not allowed public void asyncMethod() { // ... } } ``` ```java Fix theme={"system"} @EnableAsync @Configuration public class MyConfiguration { public void method() { // ... } } ```

The purpose of the hashCode method is to return a hash code based on the contents of the object. Similarly, the purpose of the toString method is to provide a textual representation of the object’s contents.

Calling hashCode() and toString() directly on array instances should be avoided because the default implementations provided by the Object class do not provide meaningful results for arrays. hashCode() returns the array’s "identity hash code", and toString() returns nearly the same value. Neither method’s output reflects the array’s contents.

```java Bad theme={"system"} public static void main(String[] args) { String argStr = args.toString(); // Noncompliant int argHash = args.hashCode(); // Noncompliant } ``` ```java Fix theme={"system"} public static void main(String[] args) { String argStr = Arrays.toString(args); // Compliant int argHash = Arrays.hashCode(args); // Compliant } ```

When boxed type java.lang.Boolean is used as an expression to determine the control flow (as described in Java Language Specification §4.2.5 The boolean Type and boolean Values) it will throw a NullPointerException if the value is null (as defined in Java Language Specification §5.1.8 Unboxing Conversion).

It is safer to avoid such conversion altogether and handle the null value explicitly.

Note, however, that no issues will be raised for Booleans that have already been null-checked.

```java Bad theme={"system"} Boolean b = getBoolean(); if (b) { // Noncompliant, it will throw NPE when b == null foo(); } else { bar(); } ``` ```java Fix theme={"system"} Boolean b = getBoolean(); if (Boolean.TRUE.equals(b)) { foo(); } else { bar(); // will be invoked for both b == false and b == null } Boolean b = getBoolean(); if(b != null){ String test = b ? "test" : ""; } ```

The java.util.Iterator.next() method must throw a NoSuchElementException when there are no more elements in the iteration. Any other behavior is non-compliant with the API contract and may cause unexpected behavior for users.

```java Bad theme={"system"} public class MyIterator implements Iterator { public String next() { if (!hasNext()) { return null; } // ... } } ``` ```java Fix theme={"system"} public class MyIterator implements Iterator { public String next() { if (!hasNext()) { throw new NoSuchElementException(); } // ... } } ```

A serialVersionUID field is required in a Serializable class. In a non-Serializable, it’s just confusing.

```java Bad theme={"system"} public class MyClass { private static final long serialVersionUID = -1L; // Noncompliant } ``` ```java Fix theme={"system"} ```

Method references are specialized lambda expressions for methods that already have a name. They take the form of objectReference::methodName or ClassName::methodName. When a lambda does nothing but call an existing method, it can be much clearer to use a method reference instead.

```java Bad theme={"system"} Set roster = transferElements(rosterSource, () -> { return new HashSet<>(); } // Noncompliant ); ``` ```java Fix theme={"system"} Set roster = transferElements(rosterSource, HashSet::new); ```

Recursion is a technique to solve a computational problem by splitting it into smaller problems. A method is recursive, if it splits its input into smaller instances and calls itself on these instances. This continues until a smallest input, a base case, is reached that can not be split further. Similarly, recursion can also occur when multiple methods invoke each other.

Recursion is a useful tool, but it must be used carefully. Recursive methods need to detect base cases and end recursion with a return statement. When this is not the case, recursion will continue until the stack overflows and the program crashes due to a StackOverflowError.

```java Bad theme={"system"} int myPow(int num, int exponent) { num = num * myPow(num, exponent - 1); // Noncompliant: myPow unconditionally calls itself. return num; // this is never reached } ``` ```java Fix theme={"system"} int myPow(int num, int exponent) { if (exponent == 0) { // <- termination condition return 1; } if (exponent < 0) { throw new IllegalArgumentException("Negative exponents are not supported."); } num = num * myPow(num, exponent - 1); return num; } ```

Just as there is little justification for writing your own String class, there is no good reason to re-define one of the existing, standard functional interfaces.

Doing so may seem tempting, since it would allow you to specify a little extra context with the name. But in the long run, it will be a source of confusion, because maintenance programmers will wonder what is different between the custom functional interface and the standard one.

```java Bad theme={"system"} @FunctionalInterface public interface MyInterface { // Noncompliant double toDouble(int a); } @FunctionalInterface public interface ExtendedBooleanSupplier { // Noncompliant boolean get(); default boolean isFalse() { return !get(); } } public class MyClass { private int a; public double myMethod(MyInterface instance){ return instance.toDouble(a); } } ``` ```java Fix theme={"system"} @FunctionalInterface public interface ExtendedBooleanSupplier extends BooleanSupplier { // Compliant, extends java.util.function.BooleanSupplier default boolean isFalse() { return !getAsBoolean(); } } public class MyClass { private int a; public double myMethod(IntToDoubleFunction instance){ return instance.applyAsDouble(a); } } ```

The use of Unicode escape sequences should be reserved for characters that would otherwise be ambiguous, such as unprintable characters.

This rule ignores sequences composed entirely of Unicode characters, but otherwise raises an issue for each Unicode character that represents a printable character.

```java Bad theme={"system"} String prefix = "n\u00E9e"; // Noncompliant ``` ```java Fix theme={"system"} String prefix = "née"; ```

The use of factory methods lets you abstract the job you need to do from the specific tool implementations needed to do it with, and helps insulate you from changes.

This rule raises an issue when instances of these are instantiated directly:

  • \`javax.xml.parsers.DocumentBuilder

  • javax.xml.parsers.SAXParser

  • javax.xml.transform.Transformer

  • org.xml.sax.XMLReader

  • org.xml.sax.XMLFilter

  • org.w3c.dom.\*\`

```java Bad theme={"system"} DocumentBuilder builder = new DocumentBuilderImpl(); // Noncompliant ``` ```java Fix theme={"system"} DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); ```

Empty implementations of the \`X509TrustManager interface are often created to allow connection to a host that is not signed by a root certificate authority. Such an implementation will accept any certificate, which leaves the application vulnerable to Man-in-the-middle attacks. The correct solution is to provide an appropriate trust store.

This rule raises an issue when an implementation of X509TrustManager\` never throws exception.

```java Bad theme={"system"} class TrustAllManager implements X509TrustManager { @Override public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException { // Noncompliant, nothing means trust any client } @Override public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException { // Noncompliant, this method never throws exception, it means trust any client LOG.log(Level.SEVERE, ERROR_MESSAGE); } @Override public X509Certificate[] getAcceptedIssuers() { return null; } } ``` ```java Fix theme={"system"} ```

The Spring dependency injection mechanism cannot identify which constructor to use for auto-wiring when multiple constructors are present in a class. This ambiguity can cause the application to crash at runtime, and it makes the code less clear to understand and more complex to extend and maintain.

```java Bad theme={"system"} @Component public class ExampleClass { // Noncompliant, multiple constructors present and no @Autowired annotation to specify which one to use private final DependencyClass1 dependency1; public ExampleClass() { throw new UnsupportedOperationException("Not supported yet."); } public ExampleClass(DependencyClass1 dependency1) { this.dependency1 = dependency1; } // ... } ``` ```java Fix theme={"system"} @Component public class ExampleClass { private final DependencyClass1 dependency1; public ExampleClass() { throw new UnsupportedOperationException("Not supported yet."); } @Autowired public ExampleClass(DependencyClass1 dependency1) { this.dependency1 = dependency1; } // ... } ```

In Java 10 Local-Variable Type Inference was introduced. It allows you to omit the expected type of a variable by declaring it with the \`var keyword.

While it is not always possible or cleaner to use this new way of declaring a variable, when the type on the left is the same as the one on the right in an assignment, using the var\` will result in a more concise code.

This rule reports an issue when the expected type of the variable is the same as the returned type of assigned expression and the type can be easily inferred by the reader, either when the type is already mentioned in the name or the initializer, or when the expression is self-explanatory.

```java Bad theme={"system"} MyClass myClass = new MyClass(); int i = 10; // Type is self-explanatory MyClass something = MyClass.getMyClass(); // Type is already mentioned in the initializer MyClass myClass = get(); // Type is already mentioned in the name ``` ```java Fix theme={"system"} var myClass = new MyClass(); var i = 10; var something = MyClass.getMyClass(); var myClass = get(); ```

It is very common to pass a collection constructor reference as an argument, for example \`Collectors.toCollection(ArrayList::new) takes the ArrayList::new constructor. When the method expects a java.util.function.Supplier it is perfectly fine. However when the method argument type is java.util.function.Function it means that an argument will be passed to the constructor.

The first argument of Collections constructors is usually an integer representing its "initial capacity". This is generally not what the developer expects, but the memory allocation is not visible at first glance.

This rule raises an issue when a collection constructor is passed by reference as a java.util.function.Function\` argument.

```java Bad theme={"system"} Arrays.asList(1, 2, 54000).stream().collect(Collectors.toMap(Function.identity(), ArrayList::new)); // Noncompliant, "ArrayList::new" unintentionally refers to "ArrayList(int initialCapacity)" instead of "ArrayList()" ``` ```java Fix theme={"system"} Arrays.asList(1, 2, 54000).stream().collect(Collectors.toMap(Function.identity(), id -> new ArrayList<>())); // Compliant, explicitly show the usage of "id -> new ArrayList<>()" or "id -> new ArrayList<>(id)" ```

Superfluous exceptions within throws clauses have negative effects on the readability and maintainability of the code. An exception in a throws clause is superfluous if it is:

  • listed multiple times

  • a subclass of another listed exception

  • not actually thrown by any execution path of the method

```java Bad theme={"system"} void foo() throws MyException, MyException {} // Noncompliant; should be listed once void bar() throws Throwable, Exception {} // Noncompliant; Exception is a subclass of Throwable void boo() throws IOException { // Noncompliant; IOException cannot be thrown System.out.println("Hi!"); } ``` ```java Fix theme={"system"} void foo() throws MyException {} void bar() throws Throwable {} void boo() { System.out.println("Hi!"); } ```

If the \`suite method in a JUnit 3 TestCase is not declared correctly, it will not be used. Such a method must be named "suite", have no arguments, be public static, and must return either a junit.framework.Test or a junit.framework.TestSuite.

Similarly, setUp and tearDown\` methods that aren’t properly capitalized will also be ignored.

```java Bad theme={"system"} Test suite() { ... } // Noncompliant; must be public static public static boolean suite() { ... } // Noncompliant; wrong return type public static Test suit() { ... } // Noncompliant; typo in method name public static Test suite(int count) { ... } // Noncompliant; must be no-arg public void setup() { ... } // Noncompliant; should be setUp public void tearDwon() { ... } // Noncompliant; should be tearDown ``` ```java Fix theme={"system"} public static Test suite() { ... } public void setUp() { ... } public void tearDown() { ... } ```

In Java 8 Streams were introduced to support chaining of operations over collections in a functional style. The most common way to save a result of such chains is to save them to some collection (usually List). To do so there is a terminal method collect that can be used with a library of Collectors. The key problem is that .collect(Collectors.toList()) actually returns a mutable kind of List while in the majority of cases unmodifiable lists are preferred. In Java 10 a new collector appeared to return an unmodifiable list: toUnmodifiableList(). This does the trick but results in verbose code. Since Java 16 there is now a better variant to produce an unmodifiable list directly from a stream: Stream.toList().

This rule raises an issue when "collect" is used to create a list from a stream.

```java Bad theme={"system"} List list1 = Stream.of("A", "B", "C") .collect(Collectors.toList()); // Noncompliant List list2 = Stream.of("A", "B", "C") .collect(Collectors.toUnmodifiableList()); // Noncompliant ``` ```java Fix theme={"system"} List list1 = Stream.of("A", "B", "C").toList(); // Compliant List list2 = Stream.of("A", "B", "C") .collect(Collectors.toList()); // Compliant, the list2 needs to be mutable list2.add("X"); ```

There are several reasons that a class might have a method that throws an \`UnsupportedOperationException. The method may be required by an interface or an abstract superclass but not actually needed in the class. Or it may be that the class itself is intended as a superclass, and the method may optionally be implemented by subclasses but not invoked on the superclass. Finally, it could be that the method has been stubbed into the code but not implemented yet.

Whatever the reason, methods that throw UnsupportedOperationException\` should not be called.

```java Bad theme={"system"} public class Callee { public int doTheThing() { throw new UnsupportedOperationException("Not implemented"); } } public class Caller { public void accomplishStuff() { //... Callee callee = new Callee(); callee.doTheThing(); // Noncompliant ``` ```java Fix theme={"system"} ```

The rules of operator precedence are complicated and can lead to errors. For this reason, parentheses should be used for clarification in complex statements. However, this does not mean that parentheses should be gratuitously added around every operation.

This rule raises issues when \`&& and || are used in combination, when assignment and equality or relational operators are used together in a condition, and for other operator combinations according to the following table:

+, -, \*, /, % \<\<, >>, >>> & ^ |

+, -, \*, /, %

x

x

x

x

\<\<, >>, >>>

x

x

x

x

&

x

x

x

x

^

x

x

x

x

|\`

x

x

x

x

This rule also raises an issue when the "true" or "false" expression of a ternary operator is not trivial and not wrapped inside parentheses.

```java Bad theme={"system"} x = a + b - c; x = a + 1 << b; // Noncompliant y = a == b ? a * 2 : a + b; // Noncompliant if ( a > b || c < d || a == d) {...} if ( a > b && c < d || a == b) {...} // Noncompliant if (a = f(b,c) == 1) { ... } // Noncompliant; == evaluated first ``` ```java Fix theme={"system"} x = a + b - c; x = (a + 1) << b; y = a == b ? (a * 2) : (a + b); if ( a > b || c < d || a == d) {...} if ( (a > b && c < d) || a == b) {...} if ( (a = f(b,c)) == 1) { ... } ```

There’s no reason to use literal boolean values or nulls in assertions. Instead of using them with assertEquals, assertNotEquals and similar methods, you should be using assertTrue, assertFalse, assertNull or assertNotNull instead (or isNull etc. when using Fest). Using them with assertions unrelated to equality (such as assertNull) is most likely a bug.

Supported frameworks:

  • JUnit3

  • JUnit4

  • JUnit5

  • Fest assert

```java Bad theme={"system"} Assert.assertTrue(true); // Noncompliant assertThat(null).isNull(); // Noncompliant assertEquals(true, something()); // Noncompliant assertNotEquals(null, something()); // Noncompliant ``` ```java Fix theme={"system"} assertTrue(something()); assertNotNull(something()); ```

In Records serialization is not done the same way as for ordinary serializable or externalizable classes. Records serialization does not rely on the \`serialVersionUID field, because the requirement to have this field equal is waived for record classes. By default, all records will have this field equal to 0L and there is no need to specify this field with 0L value and it is possible to specify it with some custom value to support serialization/deserialization involving ordinary classes.

This rule raises an issue when there is a private static final long serialVersionUID field which is set to 0L\` in a Record class.

```java Bad theme={"system"} record Person(String name, int age) implements Serializable { @Serial private static final long serialVersionUID = 0L; // Noncompliant } ``` ```java Fix theme={"system"} record Person(String name, int age) implements Serializable {} // Compliant record Person(String name, int age) implements Serializable { @Serial private static final long serialVersionUID = 42L; // Compliant } ```

The Java Persistence API specification imposes only a conditional requirement that \`@Entity classes be Serializable:

If an entity instance is to be passed by value as a detached object (e.g., through a remote interface), the entity class must implement the Serializable interface.

But it’s best practice to make all such classes Serializable from the start. So this rule raises an issue when an @Entity does not implement Serializable\`.

```java Bad theme={"system"} @Entity pubic class Person { // Noncompliant private String fname; // ... ``` ```java Fix theme={"system"} @Entity pubic class Person implements Serializable { private String fname; // ... ```

Synchronization is a mechanism used when multithreading in Java to ensure that only one thread executes a given block of code at a time. This is done to avoid bugs that can occur when multiple threads share a given state and try to manipulate simultaneously.

Object serialization is not thread-safe by default. In a multithreaded environment, one option is to mark writeObject with synchronized to improve thread safety. It is highly suspicious, however, if writeObject is the only synchronized method in a class. It may indicate that serialization is not required, as multithreading is not used. Alternatively, it could also suggest that other methods in the same class have been forgotten to be made thread-safe.

```java Bad theme={"system"} public class RubberBall implements Serializable { private Color color; private int diameter; public RubberBall(Color color, int diameter) { // ... } public void bounce(float angle, float velocity) { // ... } private synchronized void writeObject(ObjectOutputStream stream) throws IOException { // Noncompliant, "writeObject" is the only synchronized method in this class // ... } } ``` ```java Fix theme={"system"} public class RubberBall implements Serializable { private Color color; private int diameter; public RubberBall(Color color, int diameter) { // ... } public void bounce(float angle, float velocity) { // ... } private void writeObject(ObjectOutputStream stream) throws IOException { // Compliant, no methods in this class are synchronized // ... } } ```

When a back reference in a regex refers to a capturing group that hasn’t been defined yet (or at all), it can never be matched. Named back references throw a \`PatternSyntaxException in that case; numeric back references fail silently when they can’t match, simply making the match fail.

When the group is defined before the back reference but on a different control path (like in (.)|\1\` for example), this also leads to a situation where the back reference can never match.

```java Bad theme={"system"} Pattern.compile("\\1(.)"); // Noncompliant, group 1 is defined after the back reference Pattern.compile("(.)\\2"); // Noncompliant, group 2 isn't defined at all Pattern.compile("(.)|\\1"); // Noncompliant, group 1 and the back reference are in different branches Pattern.compile("(?.)|\\k"); // Noncompliant, group x and the back reference are in different branches ``` ```java Fix theme={"system"} Pattern.compile("(.)\\1"); Pattern.compile("(?.)\\k"); ```

The compiler automatically initializes class fields to their default values before setting them with any initialization values, so there is no need to explicitly set a field to its default value. Further, under the logic that cleaner code is better code, it’s considered poor style to do so.

```java Bad theme={"system"} public class MyClass { int count = 0; // Noncompliant // ... } ``` ```java Fix theme={"system"} public class MyClass { int count; // ... } ```

All classes extend Object implicitly. Doing so explicitly is redundant.

Further, declaring the implementation of an interface and one if its parents is also redundant. If you implement the interface, you also implicitly implement its parents and there’s no need to do so explicitly.

```java Bad theme={"system"} public interface MyFace { // ... } public interface MyOtherFace extends MyFace { // ... } public class Foo extends Object // Noncompliant implements MyFace, MyOtherFace { // Noncompliant //... } ``` ```java Fix theme={"system"} public interface MyFace { // ... } public interface MyOtherFace extends MyFace { // ... } public class Foo implements MyOtherFace { //... } ```

According to its JavaDocs, the intermediate Stream operation \`java.util.Stream.peek() “exists mainly to support debugging” purposes.

A key difference with other intermediate Stream operations is that the Stream implementation is free to skip calls to peek() for optimization purpose. This can lead to peek() being unexpectedly called only for some or none of the elements in the Stream.

As a consequence, relying on peek()\` without careful consideration can lead to error-prone code.

This rule raises an issue for each use of peek() to be sure that it is challenged and validated by the team to be meant for production debugging/logging purposes.

```java Bad theme={"system"} Stream.of("one", "two", "three", "four") .filter(e -> e.length() > 3) .peek(e -> System.out.println("Filtered value: " + e)); // Noncompliant ``` ```java Fix theme={"system"} Stream.of("one", "two", "three", "four") .filter(e -> e.length() > 3) .foreach(e -> System.out.println("Filtered value: " + e)); ```

Using high power consumption modes for Bluetooth operations can drain the device battery faster and may not be suitable for scenarios where power efficiency is crucial.

This rule identifies instances where high power consumption Bluetooth operations are used, specifically when requestConnectionPriority or setAdvertiseMode methods are invoked with arguments other than those promoting low power consumption.

```java Bad theme={"system"} public class BluetoothExample { private final BluetoothGattCallback gattCallback = new BluetoothGattCallback() { @Override public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) { // ... } @Override public void onServicesDiscovered(BluetoothGatt gatt, int status) { if (status == BluetoothGatt.GATT_SUCCESS) { gatt.requestConnectionPriority(BluetoothGatt.CONNECTION_PRIORITY_HIGH); // Noncompliant } } }; } ``` ```java Fix theme={"system"} public class BluetoothExample { private final BluetoothGattCallback gattCallback = new BluetoothGattCallback() { @Override public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) { // ... } @Override public void onServicesDiscovered(BluetoothGatt gatt, int status) { if (status == BluetoothGatt.GATT_SUCCESS) { gatt.requestConnectionPriority(BluetoothGatt.CONNECTION_PRIORITY_LOW_POWER); // Compliant } } }; } ```

It is very easy to write incomplete assertions when using some test frameworks. This rule enforces complete assertions in the following cases:

  • Fest: \`assertThat is not followed by an assertion invocation

  • AssertJ: assertThat is not followed by an assertion invocation

  • Mockito: verify is not followed by a method invocation

  • Truth: assertXXX\` is not followed by an assertion invocation

In such cases, what is intended to be a test doesn’t actually verify anything

```java Bad theme={"system"} // Fest boolean result = performAction(); // let's now check that result value is true assertThat(result); // Noncompliant; nothing is actually checked, the test passes whether "result" is true or false // Mockito List mockedList = Mockito.mock(List.class); mockedList.add("one"); mockedList.clear(); // let's check that "add" and "clear" methods are actually called Mockito.verify(mockedList); // Noncompliant; nothing is checked here, oups no call is chained to verify() ``` ```java Fix theme={"system"} // Fest boolean result = performAction(); // let's now check that result value is true assertThat(result).isTrue(); // Mockito List mockedList = Mockito.mock(List.class); mockedList.add("one"); mockedList.clear(); // let's check that "add" and "clear" methods are actually called Mockito.verify(mockedList).add("one"); Mockito.verify(mockedList).clear(); ```

Regardless of the logging framework in use (logback, log4j, commons-logging, java.util.logging, …​), loggers should be:

  • \`private: never be accessible outside of its parent class. If another class needs to log something, it should instantiate its own logger.

  • static: not be dependent on an instance of a class (an object). When logging something, contextual information can of course be provided in the messages but the logger should be created at class level to prevent creating a logger along with each object.

  • final\`: be created once and only once per class.

```java Bad theme={"system"} public Logger logger = LoggerFactory.getLogger(Foo.class); // Noncompliant ``` ```java Fix theme={"system"} private static final Logger LOGGER = LoggerFactory.getLogger(Foo.class); ```

Using a type parameter when you don’t have to simply obfuscates the code. Inserting an unnecessary type parameter in an unparameterized method call will compile, but confuse maintainers.

```java Bad theme={"system"} void doTheThing() { // ... } //... this.doTheThing(); // Noncompliant ``` ```java Fix theme={"system"} void doTheThing() { // ... } //... this.doTheThing(); ```

Prior to Java 7, the type argument had to be provided explicitly for every occurrence where generics were used. This often caused redundancy, as the type argument would have to be provided both when a field is declared and initialized.

Java 7 introduced the diamond operator (\<>) to reduce the code’s verbosity in some situations. The type argument between the angular brackets should be omitted if the compiler can infer it.

Since the diamond operator was only introduced in Java 7, this rule is automatically disabled when the project’s sonar.java.source is lower than 7.

```java Bad theme={"system"} List strings = new ArrayList(); // Noncompliant, the compiler can infer the type argument of the constructor invocation Map> map = new HashMap>(); // Noncompliant, the compiler can also infer complex type arguments ``` ```java Fix theme={"system"} List strings = new ArrayList<>(); // Compliant, the compiler will infer the type argument Map> map = new HashMap<>(); // Compliant, the compiler will infer the type argument ```

There’s no point in having a public member in a non-public class because objects that can’t access the class will never have the chance to access the member.

This rule raises an issue when classes has methods, fields, or inner classes with higher visibility than the class itself has.

```java Bad theme={"system"} class MyClass { public static final float PI = 3.14; // Noncompliant public int getOne() { // Noncompliant return 1; } protected class InnerClass { // Noncompliant; outer class is package-protected public boolean flipCoin() { // Noncompliant; owning class is protected return false; } // ... } } ``` ```java Fix theme={"system"} public class MyClass { // Class visibility upgrade makes members compliant public static final float PI = 3.14; public int getOne() { return 1; } protected class InnerClass { protected boolean flipCoin() { // visibility changed to match class return false; } // ... } } ```

The Object.wait(…​), Object.notify() and Object.notifyAll() methods are used in multithreaded environments to coordinate interdependent tasks that are performed by different threads. These methods are not thread-safe and by contract, they require the invoking Thread to own the object’s monitor. If a thread invokes one of these methods without owning the object’s monitor an IllegalMonitorStateException is thrown.

```java Bad theme={"system"} private void performSomeAction(Object syncValue) { while (!suitableCondition()){ syncValue.wait(); // Noncompliant, not being inside a `synchronized` block, this will raise an IllegalMonitorStateException } ... // Perform some action } ``` ```java Fix theme={"system"} private void performSomeAction(Object syncValue) { synchronized(syncValue) { while (!suitableCondition()){ syncValue.wait(); // Compliant, the `synchronized` block guarantees ownership of syncValue's monitor } ... // Perform some action } } ```

Instances of a Serializable class can be saved out to file and rehydrated at leisure. But that only works when all the values in the class instance are themselves Serializable (or transient). Storing a non-serializable value in a Serializable class will prevent the serialization of that class.

```java Bad theme={"system"} interface Fruit extends Serializable {...} class Gooseberry implements Fruit { // Nonserializable because of Thread field Thread thread; } class Bowl implements Serializable { private static final long serialVersionUID = 1; private Fruit fruit = new Gooseberry(); //Non-Compliant } ``` ```java Fix theme={"system"} interface Fruit implements Serializable {...} class Gooseberry implements Fruit {...} //Serializable class Bowl implements Serializable { private static final long serialVersionUID = 1; private Fruit fruit = new Gooseberry(); //Compliant, Gooseberry is serializable } ```

In Java 15 Text Blocks are official and can be used just like an ordinary String. However, when they are used to represent a big chunk of text, they should not be used directly in complex expressions, as it decreases the readability. In this case, it is better to extract the text block into a variable or a field.

This rule reports an issue when a text block longer than a number of lines given as a parameter is directly used within a lambda expression.

```java Bad theme={"system"} listOfString.stream() .map(str -> !""" 4.0.0 com.mycompany.app my-app 1 com.mycompany.app my-module 1 """.equals(str)); ``` ```java Fix theme={"system"} String myTextBlock = """ 4.0.0 com.mycompany.app my-app 1 com.mycompany.app my-module 1 """; listOfString.stream() .map(str -> !myTextBlock.equals(str)); ```

Double-checked locking can be used for lazy initialization of volatile fields, but only if field assignment is the last step in the synchronized block. Otherwise you run the risk of threads accessing a half-initialized object.

```java Bad theme={"system"} public class MyClass { private volatile List strings; public List getStrings() { if (strings == null) { // check#1 synchronized(MyClass.class) { if (strings == null) { strings = new ArrayList<>(); // Noncompliant strings.add("Hello"); //When threadA gets here, threadB can skip the synchronized block because check#1 is false strings.add("World"); } } } return strings; } } ``` ```java Fix theme={"system"} public class MyClass { private volatile List strings; public List getStrings() { if (strings == null) { // check#1 synchronized(MyClass.class) { if (strings == null) { List tmpList = new ArrayList<>(); tmpList.add("Hello"); tmpList.add("World"); strings = tmpList; } } } return strings; } } ```

According to the documentation,

A program may produce unpredictable results if it attempts to distinguish two references to equal values of a value-based class, whether directly via reference equality or indirectly via an appeal to synchronization…​

This is because value-based classes are intended to be wrappers for value types, which will be primitive-like collections of data (similar to \`structs in other languages) that will come in future versions of Java.

Instances of a value-based class …​

  • do not have accessible constructors, but are instead instantiated through factory methods which make no commitment as to the identity of returned instances;

This means that you can’t be sure you’re the only one trying to lock on any given instance of a value-based class, opening your code up to contention and deadlock issues.

Under Java 8 breaking this rule may not actually break your code, but there are no guarantees of the behavior beyond that.

This rule raises an issue when a known value-based class is used for synchronization. That includes all the classes in the java.time package except Clock; the date classes for alternate calendars, HijrahDate, JapaneseDate, MinguoDate, ThaiBuddhistDate; and the optional classes: Optional, OptionalDouble, OptionalLong, OptionalInt.

Note that this rule is automatically disabled when the project’s sonar.java.source is lower than 8\`.

```java Bad theme={"system"} Optional fOpt = doSomething(); synchronized (fOpt) { // Noncompliant // ... } ``` ```java Fix theme={"system"} ```

Callers of a Boolean method may be expecting to receive true or false in response. But Boolean objects can take null as a possible value. Boolean methods should not return null unless the code is annotated appropriately. With the proper annotation, the caller is aware that the returned value could be null.

```java Bad theme={"system"} public Boolean isUsable() { // ... return null; // Noncompliant } public void caller() { if (isUsable()) { // A NullPointerException might occur here // ... } } ``` ```java Fix theme={"system"} @javax.annotation.Nullable public Boolean isUsable() { // ... return null; } @javax.annotation.CheckForNull public Boolean isUsable() { // ... return null; } public void caller() { if (Boolean.True.equals(isUsable())) { // This caller knows to check and avoid ambiguity // ... } } ```

Non-encoded control characters and whitespace characters are often injected in the source code because of a bad manipulation. They are either invisible or difficult to recognize, which can result in bugs when the string is not what the developer expects. If you actually need to use a control character use their encoded version (ex: ASCII \`\n,\t,…​ or Unicode U+000D, U+0009,…​).

This rule raises an issue when the following characters are seen in a literal string:

No issue will be raised on the simple space character. Unicode U+0020\`, ASCII 32.

```java Bad theme={"system"} String tabInside = "A B"; // Noncompliant, contains a tabulation String zeroWidthSpaceInside = "foo​bar"; // Noncompliant, it contains a U+200B character inside char tab = ' '; ``` ```java Fix theme={"system"} String tabInside = "A\tB"; // Compliant, uses escaped value String zeroWidthSpaceInside = "foo\u200Bbar"; // Compliant, uses escaped value char tab = '\t'; ```

Serializing a non-\`static inner class will result in an attempt at serializing the outer class as well. If the outer class is actually serializable, then the serialization will succeed but possibly write out far more data than was intended.

Making the inner class static (i.e. "nested") avoids this problem, therefore inner classes should be static if possible. However, you should be aware that there are semantic differences between an inner class and a nested one:

  • an inner class can only be instantiated within the context of an instance of the outer class.

  • a nested (static\`) class can be instantiated independently of the outer class.

```java Bad theme={"system"} public class Raspberry implements Serializable { // ... public class Drupelet implements Serializable { // Noncompliant; output may be too large // ... } } ``` ```java Fix theme={"system"} public class Raspberry implements Serializable { // ... public static class Drupelet implements Serializable { // ... } } ```

Classes without public static members cannot be used without being instantiated, but classes with only private constructors cannot be instantiated. When a class has only private constructors and no static members, it is useless and should be removed or refactored.

```java Bad theme={"system"} public class MyClass { // Noncompliant private MyClass () { } public double getPi(){ return 3.14; } } ``` ```java Fix theme={"system"} public class MyClass { public MyClass () { } public double getPi(){ return 3.14; } } ```

According to the specification:

Nonfinal \`static class fields are disallowed in EJBs because such fields make an enterprise bean difficult or impossible to distribute.

Therefore, all static fields in an EJB should also be final\`.

```java Bad theme={"system"} @Stateless public class MyEjb { private static String message; // Noncompliant } ``` ```java Fix theme={"system"} ```

When directly subclassing \`java.io.OutputStream or java.io.FilterOutputStream, the only requirement is that you implement the method write(int). However most uses for such streams don’t write a single byte at a time and the default implementation for write(byte\[],int,int) will call write(int) for every single byte in the array which can create a lot of overhead and is utterly inefficient. It is therefore strongly recommended that subclasses provide an efficient implementation of write(byte\[],int,int).

This rule raises an issue when a direct subclass of java.io.OutputStream or java.io.FilterOutputStream doesn’t provide an override of write(byte\[],int,int)\`.

```java Bad theme={"system"} public class MyStream extends OutputStream { // Noncompliant private FileOutputStream fout; public MyStream(File file) throws IOException { fout = new FileOutputStream(file); } @Override public void write(int b) throws IOException { fout.write(b); } @Override public void close() throws IOException { fout.write("\n\n".getBytes()); fout.close(); super.close(); } } ``` ```java Fix theme={"system"} public class MyStream extends OutputStream { private FileOutputStream fout; public MyStream(File file) throws IOException { fout = new FileOutputStream(file); } @Override public void write(int b) throws IOException { fout.write(b); } @Override public void write(byte[] b, int off, int len) throws IOException { fout.write(b, off, len); } @Override public void close() throws IOException { fout.write("\n\n".getBytes()); fout.close(); super.close(); } } ```

Specifying the default value for an annotation parameter is redundant. Such values should be omitted in the interests of readability.

```java Bad theme={"system"} @MyAnnotation(arg = "def") // Noncompliant public class MyClass { // ... } public @interface MyAnnotation { String arg() default "def"; } ``` ```java Fix theme={"system"} @MyAnnotation public class MyClass { // ... } public @interface MyAnnotation { String arg() default "def"; } ```

\`Throwable.printStackTrace(...) prints a Throwable and its stack trace to some stream. By default that stream System.Err, which could inadvertently expose sensitive information.

Loggers should be used instead to print Throwables, as they have many advantages:

  • Users are able to easily retrieve the logs.

  • The format of log messages is uniform and allow users to browse the logs easily.

This rule raises an issue when printStackTrace\` is used without arguments, i.e. when the stack trace is printed to the default stream.

```java Bad theme={"system"} try { /* ... */ } catch(Exception e) { e.printStackTrace(); // Noncompliant } ``` ```java Fix theme={"system"} try { /* ... */ } catch(Exception e) { LOGGER.log("context", e); } ```

PreparedStatement is an object that represents a precompiled SQL statement, that can be used to execute the statement multiple times efficiently.

ResultSet is the Java representation of the result set of a database query obtained from a Statement object. A default ResultSet object is not updatable and has a cursor that moves forward only.

The parameters in PreparedStatement and ResultSet are indexed beginning at 1, not 0. When an invalid index is passed to the PreparedStatement or ResultSet methods, an IndexOutOfBoundsException is thrown. This can cause the program to crash or behave unexpectedly, leading to a poor user experience.

This rule raises an issue for the get methods in PreparedStatement and the set methods in ResultSet.

```java Bad theme={"system"} PreparedStatement ps = con.prepareStatement("SELECT fname, lname FROM employees where hireDate > ? and salary < ?"); ps.setDate(0, date); // Noncompliant ps.setDouble(3, salary); // Noncompliant ResultSet rs = ps.executeQuery(); while (rs.next()) { String fname = rs.getString(0); // Noncompliant // ... } ``` ```java Fix theme={"system"} PreparedStatement ps = con.prepareStatement("SELECT fname, lname FROM employees where hireDate > ? and salary < ?"); ps.setDate(1, date); ps.setDouble(2, salary); ResultSet rs = ps.executeQuery(); while (rs.next()) { String fname = rs.getString(1); // ... } ```

The problem with invoking \`Thread.start() in a constructor is that you’ll have a confusing mess on your hands if the class is ever extended because the superclass' constructor will start the thread before the child class has truly been initialized.

This rule raises an issue any time start is invoked in the constructor of a non-final\` class.

```java Bad theme={"system"} public class MyClass { Thread thread = null; public MyClass(Runnable runnable) { thread = new Thread(runnable); thread.start(); // Noncompliant } } ``` ```java Fix theme={"system"} ```

The Spring framework provides the annotation Async to mark a method (or all methods of a type) as a candidate for asynchronous execution.

Asynchronous methods do not necessarily, by their nature, return the result of their calculation immediately. Hence, it is unexpected and in clear breach of the Async contract for such methods to have a return type that is neither void nor a Future type.

```java Bad theme={"system"} @Async public String asyncMethod() { ... } ``` ```java Fix theme={"system"} @Async public Future asyncMethod() { ... } ```

Spring framework 4.3 introduced variants of the @RequestMapping annotation to better represent the semantics of the annotated methods. The use of @GetMapping, @PostMapping, @PutMapping, @PatchMapping and @DeleteMapping should be preferred to the use of the raw @RequestMapping(method = RequestMethod.XYZ).

```java Bad theme={"system"} @RequestMapping(path = "/greeting", method = RequestMethod.GET) // Noncompliant public Greeting greeting(@RequestParam(value = "name", defaultValue = "World") String name) { ... } ``` ```java Fix theme={"system"} @GetMapping(path = "/greeting") // Compliant public Greeting greeting(@RequestParam(value = "name", defaultValue = "World") String name) { ... } ```

Using toLowerCase() or toUpperCase() to make case insensitive comparisons is inefficient because it requires the creation of temporary, intermediate String objects.

```java Bad theme={"system"} private void compareStrings(String foo, String bar){ boolean result1 = foo.toUpperCase().equals(bar); // Noncompliant boolean result2 = foo.equals(bar.toUpperCase()); // Noncompliant boolean result3 = foo.toLowerCase().equals(bar.toLowerCase()); // Noncompliant } ``` ```java Fix theme={"system"} private void compareStrings(String foo, String bar){ boolean result1 = foo.equalsIgnoreCase(bar); // Compliant } ```

Swing interfaces should be constructed and shown from the Swing event dispatch thread. Doing so from any other thread, such as from \`main risks deadlocks since you run the risk of multiple threads accessing things which are inherently not thread-safe.

Instead, use SwingUtilities.invokeLater or SwingUtilities.invokeAndWait to kick off a new Runnable\` that handles your GUI creation.

```java Bad theme={"system"} public static void main(String args[]) { makeGui(); // Noncompliant } public void makeGui() { JFrame frame = new JFrame(); // ... frame.show(); } ``` ```java Fix theme={"system"} public static void main(String args[]) { SwingUtilities.invokeAndWait(new Runnable() { public void run() { makeGui(); } } } public void makeGui() { JFrame frame = new JFrame(); // ... frame.show(); } ```

When creating a \`DateTimeFormatter using the WeekFields.weekBasedYear() temporal field, the resulting year number may be off by 1 at the beginning of a new year (when the date to format is in a week that is shared by two consecutive years).

Using this year number in combination with an incompatible week temporal field yields a result that may be confused with the first week of the previous year.

Instead, when paired with a week temporal field, the week-based year should only be used with the week of week-based year temporal field WeekFields.weekOfWeekBasedYear().

Alternatively the temporal field ChronoField.ALIGNED\_WEEK\_OF\_YEAR\` can be used together with a regular year (but not the week based year).

```java Bad theme={"system"} new DateTimeFormatterBuilder() .appendValue(ChronoField.YEAR, 4) // Noncompliant: using week of week-based year with regular year .appendLiteral('-') .appendValue(WeekFields.ISO.weekOfWeekBasedYear(), 2) .toFormatter(); new DateTimeFormatterBuilder() .appendValue(ChronoField.YEAR_OF_ERA, 4) // Noncompliant: using week of week-based year with regular year .appendLiteral('-') .appendValue(WeekFields.ISO.weekOfWeekBasedYear(), 2) .toFormatter(); new DateTimeFormatterBuilder() .appendValue(WeekFields.ISO.weekBasedYear(), 4) // Noncompliant: using aligned week of year with week-based year .appendLiteral('-') .appendValue(ChronoField.ALIGNED_WEEK_OF_YEAR, 2) .toFormatter(); ``` ```java Fix theme={"system"} new DateTimeFormatterBuilder() .appendValue(WeekFields.ISO.weekBasedYear(), 4) .appendLiteral('-') .appendValue(WeekFields.ISO.weekOfWeekBasedYear(), 2) .toFormatter(); new DateTimeFormatterBuilder() .appendValue(ChronoField.YEAR, 4) .appendLiteral('-') .appendValue(ChronoField.ALIGNED_WEEK_OF_YEAR, 2) .toFormatter(); new DateTimeFormatterBuilder() .appendValue(ChronoField.YEAR_OF_ERA, 4) .appendLiteral('-') .appendValue(ChronoField.ALIGNED_WEEK_OF_YEAR, 2) .toFormatter(); ```

The use of escape sequences is mostly unnecessary in text blocks.

```java Bad theme={"system"} String textBlock = """ \"\"\" this \nis text block! !!!! """; ``` ```java Fix theme={"system"} String textBlock = """ \""" this is text block! !!!! """; ```

Spring Expression Language (SpEL) is an expression language used in the Spring Framework for evaluating and manipulating objects, properties, and conditions within Spring-based applications.

org.springframework.ui.Model is an interface in the Spring Framework that represents a container for data that can be passed between a controller and a view in a Spring MVC web application, allowing for data sharing during the request-response cycle.

Attributes added to the org.springframework.ui.Model should follow the Java identifier naming convention, which means they must start with a letter a-z, A-Z, underscore \_, or a dollar sign \$ and may be followed by letters, digits, underscores, or dollar signs.

Failure to do so may result in SpEL parsing errors when using these attributes in template engines.

```java Bad theme={"system"} model.addAttribute(" a", 100); // Noncompliant (starts with a space) model.addAttribute("a-b", 7); // Noncompliant (contains a hyphen) model.addAttribute("1c", 42); // Noncompliant (starts with a digit) ``` ```java Fix theme={"system"} model.addAttribute("a", 100); model.addAttribute("b", 42); model.addAttribute("_c", 7); model.addAttribute("$d", 8); ```

Calling \`Class.newInstance invokes the class' default constructor. Unfortunately, since it’s not a direct call to the constructor, compile-time checking will be unable to detect the possibility. This means that your code will compile even if you haven’t put the invocation in a try block.

On the other hand, Construtor.newInstance handles exceptions by wrapping them in an InvocationTargetException and explicitly throwing them.

This rule raises an issue when Class.newInstance\` is used to invoke a constructor that throws checked exceptions.

```java Bad theme={"system"} Foo f = Foo.class.newInstance(); // Noncompliant ``` ```java Fix theme={"system"} Foo f = Foo.class.getConstructor().newInstance(); ```

Calling constructors for String, BigInteger, BigDecimal and the objects used to wrap primitives is less efficient and less clear than relying on autoboxing or valueOf.

Consider simplifying when possible for more efficient and cleaner code.

```java Bad theme={"system"} String empty = new String(); // Noncompliant; yields essentially "", so just use that. String nonempty = new String("Hello world"); // Noncompliant Double myDouble = new Double(1.1); // Noncompliant; use valueOf Integer integer = new Integer(1); // Noncompliant Boolean bool = new Boolean(true); // Noncompliant BigInteger bigInteger1 = new BigInteger("3"); // Noncompliant BigInteger bigInteger2 = new BigInteger("9223372036854775807"); // Noncompliant BigInteger bigInteger3 = new BigInteger("111222333444555666777888999"); // Compliant, greater than Long.MAX_VALUE BigDecimal bigDecimal = new BigDecimal("42.0"); // Compliant (see Exceptions section) ``` ```java Fix theme={"system"} String empty = ""; String nonempty = "Hello world"; Double myDouble = 1.1; Integer integer = 1; Boolean bool = true; BigInteger bigInteger1 = BigInteger.valueOf(3); BigInteger bigInteger2 = BigInteger.valueOf(9223372036854775807L); BigInteger bigInteger3 = new BigInteger("111222333444555666777888999"); BigDecimal bigDecimal = new BigDecimal("42.0"); ```

SpEL is used in Spring annotations and is parsed by the Spring framework, not by the Java compiler. This means that invalid SpEL expressions are not detected during Java compile time. They will cause exceptions during runtime instead, or even fail silently with the expression string interpreted as a simple string literal by Spring.

```java Bad theme={"system"} @Value("#{systemProperties['user.region'}") // Noncompliant, unclosed "[" private String region; ``` ```java Fix theme={"system"} @Value("#{'${listOfValues}' split(',')}") // Noncompliant, missing operator private List valuesList; ```

To ensure EJB portability, the EJB specification forbids the use of functionality in the \`java.io package. Instead of reading and writing files, EJB’s should use some other means of data storage and retrieval, such as JDBC.

This rule raises an issue for the first java.io\` method call in each method.

```java Bad theme={"system"} public class MyBean implements BeanInterface { private File baseline = null; private void readBaseline () { try { baseline = new File(Constants.INTEREST_RATE_FILE); // Noncompliant. if (baseline.exists()) { //... } } catch (IOException e) { //... } } private void writeBaseline() { try { FileWriter fw = new FileWriter(baseline.getAbsoluteFile()); // Noncompliant BufferedWriter bw = new BufferedWriter(fw); bw.write(content); bw.close(); } catch (IOException e) { //... } } } ``` ```java Fix theme={"system"} ```

Importing a class statically allows you to use its public static members without qualifying them with the class name. That can be handy, but if you import too many classes statically, your code can become confusing and difficult to maintain.

```java Bad theme={"system"} import static java.lang.Math.*; import static java.util.Collections.*; import static com.myco.corporate.Constants.*; import static com.myco.division.Constants.*; import static com.myco.department.Constants.*; // Noncompliant ``` ```java Fix theme={"system"} ```

Non-overridable methods (private or final) that don’t access instance data can be static to prevent any misunderstanding about the contract of the method.

```java Bad theme={"system"} class Utilities { private static String magicWord = "magic"; private String getMagicWord() { // Noncompliant return magicWord; } private void setMagicWord(String value) { // Noncompliant magicWord = value; } } ``` ```java Fix theme={"system"} class Utilities { private static String magicWord = "magic"; private static String getMagicWord() { return magicWord; } private static void setMagicWord(String value) { magicWord = value; } } ```

Classes with only private constructors should be marked final to prevent any mistaken extension attempts.

```java Bad theme={"system"} public class PrivateConstructorClass { // Noncompliant private PrivateConstructorClass() { // ... } public static int magic(){ return 42; } } ``` ```java Fix theme={"system"} public final class PrivateConstructorClass { // Compliant private PrivateConstructorClass() { // ... } public static int magic(){ return 42; } } ```

Because a subclass instance may be cast to and treated as an instance of the superclass, overriding methods should uphold the aspects of the superclass contract that relate to the Liskov Substitution Principle. Specifically, if the parameters or return type of the superclass method are marked with any of the following: @Nullable, @CheckForNull, @NotNull, @NonNull, and @Nonnull, then subclass parameters are not allowed to tighten the contract, and return values are not allowed to loosen it.

```java Bad theme={"system"} public class Fruit { private Season ripe; private String color; public void setRipe(@Nullable Season ripe) { this.ripe = ripe; } public @NotNull Integer getProtein() { return 12; } } public class Raspberry extends Fruit { public void setRipe(@NotNull Season ripe) { // Noncompliant: the ripe argument annotated as @Nullable in parent class this.ripe = ripe; } public @Nullable Integer getProtein() { // Noncompliant: the return type annotated as @NotNull in parent class return null; } } ``` ```java Fix theme={"system"} public class Fruit { private Season ripe; private String color; public void setRipe(@Nullable Season ripe) { this.ripe = ripe; } public @NotNull Integer getProtein() { return 12; } } public class Raspberry extends Fruit { public void setRipe(@Nullable Season ripe) { this.ripe = ripe; } public @NotNull Integer getProtein() { return 12; } } ```

Spring \`@Component, @Controller, @RestController,@Service, and @Repository classes are singletons by default, meaning only one instance of the class is ever instantiated in the application. Typically such a class might have a few static members, such as a logger, but all non-static members should be managed by Spring.

This rule raises an issue when a singleton @Component, @Controller, @RestController, @Service, or @Repository, not annotated with @ConfigurationProperties, has non-static members that are not annotated with one of:

  • org.springframework.beans.factory.annotation.Autowired

  • org.springframework.beans.factory.annotation.Value

  • javax.annotation.Inject

  • javax.annotation.Resource\`

```java Bad theme={"system"} @Controller public class HelloWorld { private String name = null; @RequestMapping("/greet", method = GET) public String greet(String greetee) { if (greetee != null) { this.name = greetee; } return "Hello " + this.name; // if greetee is null, you see the previous user's data } } ``` ```java Fix theme={"system"} ```

Java 21 introduces the new Sequenced Collections API, which applies to all collections with a defined sequence on their elements, such as LinkedList, TreeSet, and others (see JEP 431). For projects using Java 21 and onwards, use this API instead of workaround implementations that were necessary before Java 21. One of the features of the new Sequenced Collections API is SequencedCollection.reversed() which returns a lightweight view of the original collection, in the reverse order.

This rule reports when reverse view would have been sufficient instead of a reverse copy of a sequenced collection created using a list constructor plus a Collections.reverse(collection); call.

If feasible, a view should be preferred over a copy because a view is a lightweight iterator without modification of the list itself.

```java Bad theme={"system"} void foo() { var list = new ArrayList(); list.add("A"); list.add("B"); Collections.reverse(list); // Noncompliant for (var e : list) { // ... } } ``` ```java Fix theme={"system"} void foo() { var list = new ArrayList(); list.add("A"); list.add("B"); for (var e : list.reversed()) { // Compliant // ... } } ```

Sharing some naming conventions is a key point to make it possible for a team to efficiently collaborate. This rule allows to check that all abstract class names match a provided regular expression. If a non-abstract class match the regular expression, an issue is raised to suggest to either make it abstract or to rename it.

```java Bad theme={"system"} abstract class MyClass { // Noncompliant } class AbstractLikeClass { // Noncompliant } ``` ```java Fix theme={"system"} abstract class AbstractClass { } class LikeClass { } ```

While the Singleton pattern can be useful in certain situations, overusing it can have several drawbacks:

  • Tight coupling: The Singleton pattern can create tight coupling between the Singleton class and other classes that use it, making the code difficult to maintain and modify.

  • Global state: The Singleton pattern can create a global state, making it difficult to manage the state of the application and leading to unexpected behavior.

  • Testing: The Singleton pattern can make it difficult to test classes that depend on the Singleton, as the Singleton cannot be easily substituted with a mock object.

  • Scalability: The Singleton pattern can make it difficult to scale an application, as it can create a bottleneck if multiple threads try to access the Singleton concurrently.

  • Dependency injection: The Singleton pattern can make it difficult to use dependency injection frameworks, as the Singleton instance is usually created statically.

In general, the Singleton pattern should be used sparingly and only in situations where it provides a clear benefit over other patterns or approaches. It is important to consider the drawbacks and tradeoffs of using the Singleton pattern before incorporating it into an application.

```java Bad theme={"system"} public enum EnumSingleton { INSTANCE; private EnumSingleton() { // Initialization code here... } } ``` ```java Fix theme={"system"} public class BillPughSingleton { private BillPughSingleton(){} private static class SingletonHelper { private static final BillPughSingleton INSTANCE = new BillPughSingleton(); } public static BillPughSingleton getInstance() { return SingletonHelper.INSTANCE; } } ```

Some API, like the AWS SDK, heavily rely on the builder pattern to create different data structures. Despite all the benefits, this pattern can become really verbose, especially when dealing with nested structures. In order to reach a more concise code, "Consumer Builders", also called "Consumer Interface" are often introduced.

The idea is to overload the methods taking others structures in a Builder with a Consumer of Builder instead. This enables to use a lambda instead of nesting another Builder, resulting in more concise and readable code.

This rule reports an issue when the Consumer Builder methods could be used instead of the classical ones.

```java Bad theme={"system"} SendEmailRequest.builder() .destination(Destination.builder() .toAddresses("to-email@domain.com") .bccAddresses("bcc-email@domain.com") .build()) .build(); ``` ```java Fix theme={"system"} SendEmailRequest.builder() .destination(d -> d.toAddresses("to-email@domain.com").bccAddresses("bcc-email@domain.com")) .build(); ```

Lambda expressions with only one argument with an inferred type (i.e., no explicit type declaration) can be written without parentheses around that single parameter. This syntax is simpler, more compact and readable than using parentheses and is therefore preferred.

This rule is automatically disabled when the project’s sonar.java.source is lower than 8, as lambda expressions were introduced in Java 8.

```java Bad theme={"system"} (x) -> x * 2 ``` ```java Fix theme={"system"} x -> x * 2 ```

This rule raises an issue when a configured Java package or class is used.

```java Bad theme={"system"} import java.sql.*; // Noncompliant java.util.ArrayList clients; // Noncompliant java.lang.String name // Compliant ``` ```java Fix theme={"system"} ```

The \`instanceof construction is a preferred way to check whether a variable can be cast to some type statically because a compile-time error will occur in case of incompatible types. The method isInstance() from java.lang.Class works differently and does type check at runtime only, incompatible types will therefore not be detected early in the development, potentially resulting in dead code. The isInstance() method should only be used in dynamic cases when the instanceof operator can’t be used.

This rule raises an issue when isInstance() is used and could be replaced with an instanceof\` check.

```java Bad theme={"system"} int f(Object o) {   if (String.class.isInstance(o)) {  // Noncompliant     return 42;   }   return 0; } int f(Number n) {   if (String.class.isInstance(n)) {  // Noncompliant     return 42;   }   return 0; } ``` ```java Fix theme={"system"} int f(Object o) {   if (o instanceof String) {  // Compliant     return 42;   }   return 0; } int f(Number n) {   if (n instanceof String) {  // Compile-time error     return 42;   }   return 0; } boolean fun(Object o, String c) throws ClassNotFoundException { return Class.forName(c).isInstance(o); // Compliant, can't use instanceof operator here } ```

The Java language authors have been quite frank that \`Optional was intended for use only as a return type, as a way to convey that a method may or may not return a value.

And for that, it’s valuable but using Optional on the input side increases the work you have to do in the method without really increasing the value. With an Optional parameter, you go from having 2 possible inputs: null and not-null, to three: null, non-null-without-value, and non-null-with-value. Add to that the fact that overloading has long been available to convey that some parameters are optional, and there’s really no reason to have Optional parameters.

The rule also checks for Guava’s Optional, as it was the inspiration for the JDK Optional. Although it is different in some aspects (serialization, being recommended for use as collection elements), using it as a parameter type causes exactly the same problems as for JDK Optional\`.

```java Bad theme={"system"} public String sayHello(Optional name) { // Noncompliant if (name == null || !name.isPresent()) { return "Hello World"; } else { return "Hello " + name; } } ``` ```java Fix theme={"system"} public String sayHello(String name) { if (name == null) { return "Hello World"; } else { return "Hello " + name; } } ```

The Java Collections framework defines interfaces such as java.util.List or java.util.Map. Several implementation classes are provided for each of those interfaces to fill different needs: some of the implementations guarantee a few given performance characteristics, some others ensure a given behavior, for example immutability.

Among the methods defined by the interfaces of the Collections framework, some are declared as "optional": an implementation class may choose to throw an UnsupportedOperationException when one of those methods is called. For example, java.util.Collections.emptyList() returns an implementation of java.util.List which is documented as "immutable". Calling the add method on this object triggers an UnsupportedOperationException.

```java Bad theme={"system"} List list = Collections.emptyList(); // The list implementation returned here is unmodifiable. if (someCondition) { list.add("hello"); // Noncompliant; throws an UnsupportedOperationException } return list; ``` ```java Fix theme={"system"} List list = new ArrayList<>(); if (someCondition) { list.add("hello"); } return list; ```

This issue is raised when Sonar considers that a method is a 'Brain Method'. A Brain Method is a method that tends to centralize its owner’s class logic and generally performs too many operations. This can include checking too many conditions, using lots of variables, and ultimately making it difficult to understand, maintain and reuse. It is characterized by high LOC number, high cyclomatic and cognitive complexity, and a large number of variables being used.

```java Bad theme={"system"} void farmDailyRoutine() { Crops southEastCrops = getCrops(1, -1); Crops eastCrops = getCrops(1, 0); WaterContainer waterContainer = new WaterContainer(); List bottles = new ArrayList<>(); for(int i = 0; i < 10; i++) { var bottle = new Bottle(); bottle.addWater(10L); bottle.putCap(); bottle.shake(2); bottles.add(bottle); } waterContainer.store(bottles); Truck t1 = new Truck(Truck.Type.TRANSPORT); t1.load(waterContainer); if(Weather.current != Weather.RAINY) { WaterContainer extraWaterContainer = new WaterContainer(); List extraBottles = new ArrayList<>(); if(southEastCrops.isDry()) { for(LandSlot ls : southEastCrops.lands()) { Bottle b = new Bottle(); b.addWater(10L); b.putCap(); extraBottles.add(b); } } else { extraBottles.add(new Bottle()); } if(eastCrops.isDry()) { for(LandSlot ls : southEastCrops.lands()) { Bottle b = new Bottle(); b.addWater(10L); b.putCap(); extraBottles.add(b); } } else { extraBottles.add(new Bottle()); } extraWaterContainer.store(extraBottles); t1.load(extraWaterContainer); } else { WaterContainer extraWaterContainer = WaterSource.clone(waterContainer); t1.load(extraWaterContainer) } } ``` ```java Fix theme={"system"} void farmDailyRoutine() { // Compliant: Simpler method, making use of extracted and distributed logic Crops southEastCrops = getCrops(1, -1); Crops eastCrops = getCrops(1, 0); WaterContainer waterContainer = new WaterContainer(); List bottles = getWaterBottles(10, 10L, true); waterContainer.store(bottles); Truck t1 = new Truck(Truck.Type.TRANSPORT); t1.load(waterContainer); if(Weather.current != Weather.RAINY) { WaterContainer extraWaterContainer = new WaterContainer(); fillContainerForCrops(extraWaterContainer, southEastCrops); fillContainerForCrops(extraWaterContainer, eastCrops); t1.load(extraWaterContainer); } else { WaterContainer extraWaterContainer = WaterSource.clone(waterContainer); t1.load(extraWaterContainer) } } private fillContainerForCrops(WaterContainer wc, Crops crops) { // Compliant: extracted readable and reusable method if(crops.isDry()) { wc.store(getWaterBottles(crops.lands().size(), 10L, false)); } else { wc.store(Collections.singleton(new Bottle())); } } private List getWaterBottles(int qt, long liquid, boolean shake){ // Compliant: extracted readable and reusable method List bottles = new ArrayList<>(); for(int i = 0; i < qt; i++) { Bottle b = new Bottle(); b.addWater(liquid); b.putCap(); if(shake) { b.shake(); } bottles.add(b); } return bottles; } ```

Two "hash" classes, Hashtable, and ConcurrentHashMap offer contains methods. One might naively assume that the contains method searches both keys and values for its argument. And one would be wrong. Because these legacy methods search only values, they are likely to mislead maintainers even if the original coder understood precisely what’s going on.

```java Bad theme={"system"} Hashtable ht = new Hashtable<>(); // ... if (ht.contains(foo)) { // Noncompliant // ... } ``` ```java Fix theme={"system"} Hashtable ht = new Hashtable<>(); // ... if (ht.containsValue(foo)) { // ... } ```

It’s a common pattern to test the result of a \`java.util.Map.get() against null or calling java.util.Map.containsKey() before proceeding with adding or changing the value in the map. However the java.util.Map API offers a significantly better alternative in the form of the computeIfPresent() and computeIfAbsent() methods. Using these instead leads to cleaner and more readable code.

Note that this rule is automatically disabled when the project’s sonar.java.source\` is not 8.

```java Bad theme={"system"} V value = map.get(key); if (value == null) { // Noncompliant value = V.createFor(key); if (value != null) { map.put(key, value); } } if (!map.containsKey(key)) { // Noncompliant value = V.createFor(key); if (value != null) { map.put(key, value); } } return value; ``` ```java Fix theme={"system"} return map.computeIfAbsent(key, k -> V.createFor(k)); ```

When iterating over an Iterable with a for loop, the iteration variable could have the same type as the type returned by the iterator (the item type of the Iterable). This rule reports when a supertype of the item type is used for the variable instead, but the variable is then explicitly downcast in the loop body.

Using explicit type casts instead of leveraging the language’s type system is a bad practice. It disables static type checking by the compiler for the cast expressions, but potential errors will throw a ClassCastException during runtime instead.

```java Bad theme={"system"} for (Object item : getPersons()) { // Noncompliant, iteration element is implicitly upcast here Person person = (Person) item; // Noncompliant, item is explicitly downcast here person.getAddress(); } ``` ```java Fix theme={"system"} for (Person person : getPersons()) { // Compliant person.getAddress(); } ```

In Java 21 the java.lang.Math class was updated with the static method Math.clamp, to clamp a numerical value between a min and a max value.

Using this built-in method is now the preferred way to restrict to a given interval, as it is more readable and less error-prone.

```java Bad theme={"system"} int clampedValue = value > max ? max : value < min ? min : value; // Noncompliant; Replace with "Math.clamp" ``` ```java Fix theme={"system"} int clampedValue = Math.max(min, Math.min(max, value)); // Noncompliant; Replace with "Math.clamp" ```

Class members that are not assigned a default value and are not initialized in a constructor will be set to null by the compiler. Even if code exists to properly set those members, there is a risk that they will be dereferenced before it is called, resulting in a NullPointerException.

Because you cannot guarantee that such classes will always be used properly, class members should always be initialized.

This rule flags members which have no default value and which are left uninitialized by at least one class constructor, but which are unconditionally dereferenced somewhere in the code.

```java Bad theme={"system"} public class Team { int limit = 30; List roster; // Noncompliant; no default & not initialized by constructor Person coach; public Team (Person coach) { // roster is left uninitialized this.coach = coach; } public void add(Player p) { if (roster == null) { roster = new ArrayList(); } roster.add(p); } public boolean isFull() { // NPE if called before add() return roster.size() < limit; } } ``` ```java Fix theme={"system"} public class Team { int limit = 30; List roster = new ArrayList(); Person coach; public Team (Person coach) { this.coach = coach; } public void add(Player p) { roster.add(p); } // ... ```

Some method calls can effectively be "no-ops", meaning that the invoked method does nothing, based on the application’s configuration (eg: debug logs in production). However, even if the method effectively does nothing, its arguments may still need to evaluated before the method is called.

Passing message arguments that require further evaluation into a Guava com.google.common.base.Preconditions check can result in a performance penalty. That is because whether or not they’re needed, each argument must be resolved before the method is actually called.

Similarly, passing concatenated strings into a logging method can also incur a needless performance hit because the concatenation will be performed every time the method is called, whether or not the log level is low enough to show the message.

Instead, you should structure your code to pass static or pre-computed values into Preconditions conditions check and logging calls.

Specifically, the built-in string formatting should be used instead of string concatenation, and if the message is the result of a method call, then Preconditions should be skipped altogether, and the relevant exception should be conditionally thrown instead.

```java Bad theme={"system"} logger.log(Level.DEBUG, "Something went wrong: " + message); // Noncompliant; string concatenation performed even when log level too high to show DEBUG messages logger.fine("An exception occurred with message: " + message); // Noncompliant LOG.error("Unable to open file " + csvPath, e); // Noncompliant Preconditions.checkState(a > 0, "Arg must be positive, but got " + a); // Noncompliant. String concatenation performed even when a > 0 Preconditions.checkState(condition, formatMessage()); // Noncompliant. formatMessage() invoked regardless of condition Preconditions.checkState(condition, "message: %s", formatMessage()); // Noncompliant ``` ```java Fix theme={"system"} logger.log(Level.DEBUG, "Something went wrong: {0} ", message); // String formatting only applied if needed logger.log(Level.SEVERE, () -> "Something went wrong: " + message); // since Java 8, we can use Supplier , which will be evaluated lazily logger.fine("An exception occurred with message: {}", message); // SLF4J, Log4j LOG.error("Unable to open file {0}", csvPath, e); if (LOG.isDebugEnabled()) { LOG.debug("Unable to open file " + csvPath, e); // this is compliant, because it will not evaluate if log level is above debug. } Preconditions.checkState(arg > 0, "Arg must be positive, but got %d", a); // String formatting only applied if needed if (!condition) { throw new IllegalStateException(formatMessage()); // formatMessage() only invoked conditionally } if (!condition) { throw new IllegalStateException("message: " + formatMessage()); } ```

"equals" has a special place as a method name: it is expected to override boolean Object.equals(Object). Using the name for a method with some other signature is a recipe for confusion.

```java Bad theme={"system"} public void equals(MyObject o) { // Noncompliant //... } public bool equals(MyObject left, MyObject right) { // Noncompliant // ... } ``` ```java Fix theme={"system"} ```

There’s no need to null test in conjunction with an instanceof test. null is not an instanceof anything, so a null check is redundant.

```java Bad theme={"system"} if (x != null && x instanceof MyClass) { ... } // Noncompliant if (x == null || ! x instanceof MyClass) { ... } // Noncompliant ``` ```java Fix theme={"system"} if (x instanceof MyClass) { ... } if (! x instanceof MyClass) { ... } ```

Before records appeared in Java 16, there was a common way to represent getters for private fields of a class:  a method named "get" with a capitalized field name. For example, for a \`String field named "myField" the signature of the getter method will be: public String getMyField()

In records, getters are named differently. Getters created by default do not contain the "get" prefix. So for a record’s String field "myField" the getter method will be: public String myField()\`

This means that if you want to override the default getter behavior it is better to use the method provided by records instead of creating a new one. Otherwise, this will bring confusion to the users of the record as two getters will be available and even leads to bugs if the behavior is different from the default one.

This rule raises an issue when a record contains a getter named "get" with a capitalized field name that is not behaving the same as the default one.

```java Bad theme={"system"} record Person(String name, int age) { public String getName() { // Noncompliant return name.toUpperCase(Locale.ROOT); } } ``` ```java Fix theme={"system"} record Person(String name, int age) { @Override public String name() { // Compliant return name.toUpperCase(Locale.ROOT); } } record Person(String name, int age) { public String getNameUpperCase() { // Compliant return name.toUpperCase(Locale.ROOT); } } record Person(String name, int age) { public String getName() { // Compliant, is equivalent to 'name()' return name; } } record Person(String name, int age) { @Override public String name() { // Compliant return name.toUpperCase(Locale.ROOT); } public String getName() { // Compliant, equal to 'name()' return name.toUpperCase(Locale.ROOT); } } ```

Consistent naming of beans is important for the readability and maintainability of the code. More precisely, according to the Spring documentation:

Naming beans consistently makes your configuration easier to read and understand, and if you are using Spring AOP it helps a lot when applying advice to a set of beans related by name.

Not following accepted conventions can introduce inconsistent naming, especially when multiple developers work on the same project, leading to technical debt.

The spring documentation establishes a naming convention that consists of camel-cased names with a leading lowercase letter.

This rule raises an issue when a bean name defined in one of the following annotations does not adhere to the naming convention:

  • @Bean

  • @Configuration

  • @Controller

  • @Component

  • @Qualifier

  • @Repository

  • @Service

```java Bad theme={"system"} @Bean(name = "MyBean") // Noncompliant, the first letter of the name should be lowercase public MyBean myBean() { ... ``` ```java Fix theme={"system"} @Bean(name = "myBean") // Compliant public MyBean myBean() { ... ```

There is no need to declare the same dependency or plugin twice in a project. In fact, doing so is likely to cause errors in the future when maintainers try to change or upgrade the plugin or dependency.

```java Bad theme={"system"} com.mygroup myartifact 1.0 runtime com.mygroup myartifact 1.0 jar ``` ```java Fix theme={"system"} ```

Using checked exceptions forces method callers to deal with errors, either by propagating them or by handling them. Throwing exceptions makes them fully part of the API of the method.

But to keep the complexity for callers reasonable, methods should not throw more than one kind of checked exception.

```java Bad theme={"system"} public void delete() throws IOException, SQLException { // Noncompliant /* ... */ } ``` ```java Fix theme={"system"} public void delete() throws SomeApplicationLevelException { /* ... */ } ```

A cast operation allows an object to be "converted" from one type to another. The compiler raises an error if it can determine that the target type is incompatible with the declared type of the object, otherwise it accepts the cast. However, depending on the actual runtime type of the object, a cast operation may fail at runtime. When a cast operation fails, a ClassCastException is thrown.

```java Bad theme={"system"} String hexString(Object o) { return Integer.toHexString((Integer) o); // Noncompliant if hexString is called with a String for example } ``` ```java Fix theme={"system"} String hexString(Integer i) { return Integer.toHexString(i); } ```

In Java, an enum is a special data type that allows you to define a set of constants. Nested enum types, also known as inner enum types, are enum types that are defined within another class or interface.

Nested enum types are implicitly static, so there is no need to declare them static explicitly.

```java Bad theme={"system"} public class Flower { static enum Color { // Noncompliant; static is redundant here RED, YELLOW, BLUE, ORANGE } // ... } ``` ```java Fix theme={"system"} public class Flower { enum Color { // Compliant RED, YELLOW, BLUE, ORANGE } // ... } ```

JNI (Java Native Interface) code should be used only as a last resort, since part of the point of using Java is to make applications portable, and by definition the use of JNI can reduce portability.

```java Bad theme={"system"} System.loadLibrary("nativeStringLib"); // Noncompliant ``` ```java Fix theme={"system"} ```

Marking an array \`volatile means that the array itself will always be read fresh and never thread cached, but the items in the array will not be. Similarly, marking a mutable object field volatile means the object reference is volatile but the object itself is not, and other threads may not see updates to the object state.

This can be salvaged with arrays by using the relevant AtomicArray class, such as AtomicIntegerArray, instead. For mutable objects, the volatile\` should be removed, and some other method should be used to ensure thread-safety, such as synchronization, or ThreadLocal storage.

```java Bad theme={"system"} private volatile int [] vInts; // Noncompliant private volatile MyObj myObj; // Noncompliant ``` ```java Fix theme={"system"} private AtomicIntegerArray vInts; private MyObj myObj; ```

Collection classes from the \`java.util.concurrent package have their own concurrency control mechanisms. A concurrent collection is thread-safe, but not governed by a single exclusion lock, therefore using an instance of such a class for synchronization is, at best unnecessary and at worst likely to have unintended consequences.

This rule raises an issue when a synchronization lock is used on an instance of one of the collection classes from the java.util.concurrent\` package.

```java Bad theme={"system"} public class Foo { private ConcurrentHashMap map = new ConcurrentHashMap<>(); public void bar() { synchronized(map) { // Noncompliant map.put("foo", "bar"); } // Do something ... } } ``` ```java Fix theme={"system"} public class Foo { private ConcurrentHashMap map = new ConcurrentHashMap<>(); public void bar() { map.put("foo", "bar"); // Do something ... } } ```

The Collection object returned by Map.entrySet(), Map.keySet() and Map.values(), and SequencedMap.sequencedEntrySet(), SequencedMap.sequencedKeySet() and SequencedMap.sequencedValues(), do not support the .add() and .addAll() methods, and they will throw an UnsupportedOperationException when invoked.

This rule raises an issue whenever .add() or .addAll() are invoked on collections that were retrieved this way.

```java Bad theme={"system"} Map map = new HashMap<>(); map.keySet().add(2); // Noncompliant, will throw UnsupportedOperationException map.keySet().addAll(List.of(1, 2, 3)); // Noncompliant, will throw UnsupportedOperationException SequencedMap sequencedMap = new LinkedHashMap<>(); sequencedMap.sequencedValues().add("1"); // Noncompliant, will throw UnsupportedOperationException sequencedMap.sequencedValues().addAll(List.of("1", "2", "3")); // Noncompliant, will throw UnsupportedOperationException ``` ```java Fix theme={"system"} ```

Java’s `import mechanism allows the use of simple class names. Therefore, using a class' fully qualified name in a file that import`s the class is redundant and confusing.

```java Bad theme={"system"} import java.util.List; import java.sql.Timestamp; //... java.util.List myList; // Noncompliant java.sql.Timestamp tStamp; // Noncompliant ``` ```java Fix theme={"system"} import java.util.List; import java.sql.Timestamp; //... List myList; Timestamp tStamp; ```

The @Value annotation does not guarantee that the property is defined. Particularly if a field or parameter is annotated as nullable, it indicates that the developer assumes that the property may be undefined.

An undefined property may lead to runtime exceptions when the Spring framework tries to inject the autowired dependency during bean creation.

This rule raises an issue when a nullable field or parameter is annotated with @Value and no default value is provided.

```java Bad theme={"system"} @Nullable @Value("${my.property}") // Noncompliant, no default value is provided, even though the field is nullable private String myProperty; ``` ```java Fix theme={"system"} @Nullable @Value("${my.property:#{null}}") // Compliant, a default value is provided private String myProperty; ```

An Iterable should not implement the Iterator interface or return this as an Iterator. The reason is that Iterator represents the iteration process itself, while Iterable represents the object we want to iterate over.

The Iterator instance encapsulates state information of the iteration process, such as the current and next element. Consequently, distinct iterations require distinct Iterator instances, for which Iterable provides the factory method Iterable.iterator().

This rule raises an issue when the Iterable.iterator() of a class implementing both Iterable and Iterator returns this.

```java Bad theme={"system"} class FooIterator implements Iterator, Iterable { private Foo[] seq; private int idx = 0; public boolean hasNext() { return idx < seq.length; } public Foo next() { return seq[idx++]; } public Iterator iterator() { return this; // Noncompliant } // ... } ``` ```java Fix theme={"system"} class FooSequence implements Iterable { private Foo[] seq; public Iterator iterator() { return new Iterator() { // Compliant private int idx = 0; public boolean hasNext() { return idx < seq.length; } public Foo next() { return seq[idx++]; } }; } // ... } ```

Shadowing parent class static methods by creating methods in child classes with the same signatures can result in seemingly strange behavior if an instance of the child class is cast to the parent class and the static method is invoked using a reference to the child class. In such cases, the parent class' code will be executed instead of the code in the child class, confusing callers and potentially causing hard-to-find bugs. Instead the child class method should be renamed.

```java Bad theme={"system"} public class Fruit { public static Double getCost() { return 3.5; } } public class Raspberry extends Fruit { public static Double GetCost() // Noncompliant { return 7.5; } } // ... var r = new Raspberry(); var f = (Fruit) r; System.out.println(r.GetCost()); // prints 7.5 System.out.println(f.GetCost()); // prints 3.5; there's only one instance but different code executes depending on cast ``` ```java Fix theme={"system"} public class Fruit { public static DoubleGetCost() { return 3.5; } } public class Raspberry extends Fruit { public static Double GetInflatedCost() { return 7.5; } } // ... var r = new Raspberry(); var f = (Fruit) r; System.out.println(r.GetCost()); // prints 3.5, Raspberry.GetCost() would be even better System.out.println(f.GetCost()); // prints 3.5; same code executes every time System.out.println(r.GetInflatedCost()); // prints 7.5, Raspberry.GetInflatedCost() would be even better ```

In Java 16 records represent a brief notation for immutable data structures. Records have autogenerated implementations for constructors with all parameters, getters, equals, hashcode and toString. Although these methods can still be overridden inside records, there is no use to do so if no special logic is required.

This rule reports an issue on empty compact constructors, trivial canonical constructors and simple getter methods with no additional logic.

```java Bad theme={"system"} record Person(String name, int age) { Person(String name, int age) { // Noncompliant, already autogenerated this.name = name; this.age = age; } } record Person(String name, int age) { Person { // Noncompliant, no need for empty compact constructor } public String name() { // Noncompliant, already autogenerated return name; } } ``` ```java Fix theme={"system"} record Person(String name, int age) { } // Compliant record Person(String name, int age) { Person(String name, int age) { // Compliant this.name = name.toLowerCase(Locale.ROOT); this.age = age; } } record Person(String name, int age) { Person { // Compliant if (age < 0) { throw new IllegalArgumentException("Negative age"); } } public String name() { // Compliant return name.toUpperCase(Locale.ROOT); } } ```

The Advanced Encryption Standard (AES) encryption algorithm can be used with various modes. Some combinations are not secured:

  • Electronic Codebook (ECB) mode: Under a given key, any given plaintext block always gets encrypted to the same ciphertext block. Thus, it does not hide data patterns well. In some senses, it doesn’t provide serious message confidentiality, and it is not recommended for use in cryptographic protocols at all.

  • Cipher Block Chaining (CBC) with PKCS#5 padding (or PKCS#7) is susceptible to padding oracle attacks.

In both cases, Galois/Counter Mode (GCM) with no padding should be preferred.

This rule raises an issue when a Cipher instance is created with either ECB or CBC/PKCS5Padding mode.

```java Bad theme={"system"} Cipher c1 = Cipher.getInstance("AES/ECB/NoPadding"); // Noncompliant Cipher c2 = Cipher.getInstance("AES/CBC/PKCS5Padding"); // Noncompliant ``` ```java Fix theme={"system"} Cipher c = Cipher.getInstance("AES/GCM/NoPadding"); ```

Whether the valid value ranges for \`Date fields start with 0 or 1 varies by field. For instance, month starts at 0, and day of month starts at 1. Enter a date value that goes past the end of the valid range, and the date will roll without error or exception. For instance, enter 12 for month, and you’ll get January of the following year.

This rule checks for bad values used in conjunction with java.util.Date, java.sql.Date, and java.util.Calendar\`. Specifically, values outside of the valid ranges:

Field Valid

month

0-11

date (day)

0-31

hour

0-23

minute

0-60

second

0-61

Note that this rule does not check for invalid leap years, leap seconds (second = 61), or invalid uses of the 31st day of the month.

```java Bad theme={"system"} Date d = new Date(); d.setDate(25); d.setYear(2014); d.setMonth(12); // Noncompliant; rolls d into the next year Calendar c = new GregorianCalendar(2014, 12, 25); // Noncompliant if (c.get(Calendar.MONTH) == 12) { // Noncompliant; invalid comparison // ... } ``` ```java Fix theme={"system"} Date d = new Date(); d.setDate(25); d.setYear(2014); d.setMonth(11); Calendar c = new Gregorian Calendar(2014, 11, 25); if (c.get(Calendar.MONTH) == 11) { // ... } ```

When the code under test in a unit test throws an exception, the test itself fails. Therefore, there is no need to surround the tested code with a \`try-catch structure to detect failure. Instead, you can simply move the exception type to the method signature.

This rule raises an issue when there is a fail assertion inside a catch\` block.

Supported frameworks:

  • JUnit3

  • JUnit4

  • JUnit5

  • Fest assert

  • AssertJ

```java Bad theme={"system"} @Test public void testMethod() { try { // Some code } catch (MyException e) { Assert.fail(e.getMessage()); // Noncompliant } } ``` ```java Fix theme={"system"} @Test public void testMethod() throws MyException { // Some code } ```

When multiple tests differ only by a few hardcoded values they should be refactored as a single "parameterized" test. This reduces the chances of adding a bug and makes them more readable. Parameterized tests exist in most test frameworks (JUnit, TestNG, etc…​).

The right balance needs of course to be found. There is no point in factorizing test methods when the parameterized version is a lot more complex than initial tests.

This rule raises an issue when at least 3 tests could be refactored as one parameterized test with less than 4 parameters. Only test methods which have at least one duplicated statement are considered.

```java Bad theme={"system"} import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; public class AppTest { @Test void test_not_null1() { // Noncompliant. The 3 following tests differ only by one hardcoded number. setupTax(); assertNotNull(getTax(1)); } @Test void test_not_null2() { setupTax(); assertNotNull(getTax(2)); } @Test void test_not_nul3l() { setupTax(); assertNotNull(getTax(3)); } @Test void testLevel1() { // Noncompliant. The 3 following tests differ only by a few hardcoded numbers. setLevel(1); runGame(); assertEquals(playerHealth(), 100); } @Test void testLevel2() { // Similar test setLevel(2); runGame(); assertEquals(playerHealth(), 200); } @Test void testLevel3() { // Similar test setLevel(3); runGame(); assertEquals(playerHealth(), 300); } } ``` ```java Fix theme={"system"} import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvSource; public class AppTest { @ParameterizedTest @ValueSource(ints = {1, 2, 3}) void test_not_null(int arg) { setupTax(); assertNotNull(getTax(arg)); } @ParameterizedTest @CsvSource({ "1, 100", "2, 200", "3, 300", }) void testLevels(int level, int health) { setLevel(level); runGame(); assertEquals(playerHealth(), health); } } ```

The Collection.toArray() method returns an Object\[] when no arguments are provided to it. This can lead to a ClassCastException at runtime if you try to cast the returned array to an array of a specific type. Instead, use this method by providing an array of the desired type as the argument.

Note that passing a new T\[0] array of length zero as the argument is more efficient than a pre-sized array new T\[size].

```java Bad theme={"system"} public String [] getStringArray(List strings) { return (String []) strings.toArray(); // Noncompliant, a ClassCastException will be thrown here } ``` ```java Fix theme={"system"} public String [] getStringArray(List strings) { return strings.toArray(new String[0]); // Compliant, the toArray method will return an array of the desired type, and we can remove the casting operation } public String [] getPresizedStringArray(List strings) { return strings.toArray(new String[strings.size()]); // Compliant, but slightly less efficient than the previous example } ```

The Java regex engine uses recursive method calls to implement backtracking. Therefore when a repetition inside a regular expression contains multiple paths (i.e. the body of the repetition contains an alternation (\`|), an optional element or another repetition), trying to match the regular expression can cause a stack overflow on large inputs. This does not happen when using a possessive quantifier (such as *+ instead of *) or when using a character class inside a repetition (e.g. \[ab]* instead of (a|b)*).

The size of the input required to overflow the stack depends on various factors, including of course the stack size of the JVM. One thing that significantly increases the size of the input that can be processed is if each iteration of the repetition goes through a chain of multiple constant characters because such consecutive characters will be matched by the regex engine without invoking any recursion.

For example, on a JVM with a stack size of 1MB, the regex (?:a|b)\* will overflow the stack after matching around 6000 characters (actual numbers may differ between JVM versions and even across multiple runs on the same JVM) whereas (?:abc|def)\* can handle around 15000 characters.

Since often times stack growth can’t easily be avoided, this rule will only report issues on regular expressions if they can cause a stack overflow on realistically sized inputs. You can adjust the maxStackConsumptionFactor\` parameter to adjust this.

```java Bad theme={"system"} Pattern.compile("(a|b)*"); // Noncompliant Pattern.compile("(.|\n)*"); // Noncompliant Pattern.compile("(ab?)*"); // Noncompliant ``` ```java Fix theme={"system"} Pattern.compile("[ab]*"); // Character classes don't cause recursion the way that '|' does Pattern.compile("(?s).*"); // Enabling the (?s) flag makes '.' match line breaks, so '|\n' isn't necessary Pattern.compile("(ab?)*+"); // Possessive quantifiers don't cause recursion because they disable backtracking ```
2 ActionSupport is security-sensitive. For example, their use has led in the past to the following vulnerabilities:

All classes extending com.opensymphony.xwork2.ActionSupport are potentially remotely reachable. An action class extending ActionSupport will receive all HTTP parameters sent and these parameters will be automatically mapped to the setters of the Struts 2 action class. One should review the use of the fields set by the setters, to be sure they are used safely. By default, they should be considered as untrusted inputs.

```java Bad theme={"system"} public class AccountBalanceAction extends ActionSupport { private static final long serialVersionUID = 1L; private Integer accountId; // this setter might be called with user input public void setAccountId(Integer accountId) { this.accountId = accountId; } @Override public String execute() throws Exception { // call a service to get the account's details and its balance [...] return SUCCESS; } } ``` ```java Fix theme={"system"} ```

This rule allows you to track the usage of the @SuppressWarnings mechanism.

```java Bad theme={"system"} @SuppressWarnings("unused") @SuppressWarnings("unchecked") // Noncompliant ``` ```java Fix theme={"system"} ```

Assuming that a comparator or compareTo method always returns -1 or 1 if the first operand is less than or greater than the second is incorrect.

The specifications for both methods, Comparator.compare and Comparable.compareTo, state that their return value is "a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object." Even if a specific comparator always returns -1, 0, or 1, this is only an implementation detail, not the API contract developers can rely on.

```java Bad theme={"system"} public class Main { boolean isAGreaterThanB(Comparable a, Integer b) { return a.compareTo(b) == 1; // Noncompliant, check for constant return value } public static void main(String[] args) { ByteComparator comparator = new ByteComparator(); if (comparator.compare((byte) 23, (byte) 42) == -1) { // Noncompliant, check for constant return value System.out.println("23 < 42"); } else { System.out.println("23 >= 42"); } } static class ByteComparator implements Comparator { @Override public int compare(Byte a, Byte b) { return a - b; } } } ``` ```java Fix theme={"system"} public class Main { boolean isAGreaterThanB(Comparable a, Integer b) { return a.compareTo(b) > 0; // Compliant, check for positive return value } public static void main(String[] args) { ByteComparator comparator = new ByteComparator(); if (comparator.compare((byte) 23, (byte) 42) < 0) { // Compliant, check for negative return value System.out.println("23 < 42"); } else { System.out.println("23 >= 42"); } } static class ByteComparator implements Comparator { @Override public int compare(Byte a, Byte b) { return a - b; } } } ```

Correctly updating a \`static field from a non-static method is tricky to get right and could easily lead to bugs if there are multiple class instances and/or multiple threads in play. Ideally, static fields are only updated from synchronized static methods.

This rule raises an issue each time a static\` field is updated from a non-static method.

```java Bad theme={"system"} public class MyClass { private static int count = 0; public void doSomething() { //... count++; // Noncompliant } } ``` ```java Fix theme={"system"} ```

When an object is marked as static, it means that it belongs to the class rather than any class instance. This means there is only one copy of the static object in memory, regardless of how many class instances are created. Static objects are shared among all instances of the class and can be accessed using the class name rather than an instance of the class.

A data type is considered thread-safe if it can be used correctly by multiple threads, regardless of how those threads are executed, without requiring additional coordination from the calling code. In other words, a thread-safe data type can be accessed and modified by multiple threads simultaneously without causing any issues or requiring extra work from the programmer to ensure correct behavior.

Non-thread-safe objects are objects that are not designed to be used in a multi-threaded environment and can lead to race conditions and data inconsistencies when accessed by multiple threads simultaneously. Using them in a multi-threaded manner is highly likely to cause data problems or exceptions at runtime.

When a non-thread-safe object is marked as static in a multi-threaded environment, it can cause issues because the non-thread-safe object will be shared across different instances of the containing class.

This rule raises an issue when any of the following instances and their subtypes are marked as static:

  • java.util.Calendar,

  • java.text.DateFormat,

  • javax.xml.xpath.XPath, or

  • javax.xml.validation.SchemaFactory.

```java Bad theme={"system"} public class MyClass { private static Calendar calendar = Calendar.getInstance(); // Noncompliant private static SimpleDateFormat format = new SimpleDateFormat("HH-mm-ss"); // Noncompliant } ``` ```java Fix theme={"system"} public class MyClass { private Calendar calendar = Calendar.getInstance(); private SimpleDateFormat format = new SimpleDateFormat("HH-mm-ss"); } ```

There is no requirement that class names be unique, only that they be unique within a package. Therefore trying to determine an object’s type based on its class name is an exercise fraught with danger. One of those dangers is that a malicious user will send objects of the same name as the trusted class and thereby gain trusted access.

Instead, the instanceof operator or the Class.isAssignableFrom() method should be used to check the object’s underlying type.

```java Bad theme={"system"} package computer; class Pear extends Laptop { ... } package food; class Pear extends Fruit { ... } class Store { public boolean hasSellByDate(Object item) { if ("Pear".equals(item.getClass().getSimpleName())) { // Noncompliant return true; // Results in throwing away week-old computers } return false; } public boolean isList(Class valueClass) { if (List.class.getName().equals(valueClass.getName())) { // Noncompliant return true; } return false; } } ``` ```java Fix theme={"system"} class Store { public boolean hasSellByDate(Object item) { if (item instanceof food.Pear) { return true; } return false; } public boolean isList(Class valueClass) { if (valueClass.isAssignableFrom(List.class)) { return true; } return false; } } ```

"A rose by any other name would smell as sweet," but main by any other name would not. Just because a method has the name "main", that doesn’t make it the entry point to an application. It must also have the correct signature. Specifically, it must be public static void and accept a single String \[] as an argument.

```java Bad theme={"system"} public void main(String arg) { // Noncompliant // ... } ``` ```java Fix theme={"system"} public static void main(String [] args) { // ... } ```

When the modulus of a negative number is calculated, the result will either be negative or zero. Thus, comparing the modulus of a variable for equality with a positive number (or a negative one) could result in unexpected results.

```java Bad theme={"system"} public boolean isOdd(int x) { return x % 2 == 1; // Noncompliant; if x is an odd negative, x % 2 == -1 } ``` ```java Fix theme={"system"} public boolean isOdd(int x) { return x % 2 != 0; } ```

Disclosure of version information, usually overlooked by developers but disclosed by default by the systems and frameworks in use, can pose a significant security risk depending on the production environement.

Once this information is public, attackers can use it to identify potential security holes or vulnerabilities specific to that version.

Furthermore, if the published version information indicates the use of outdated or unsupported software, it becomes easier for attackers to exploit known vulnerabilities. They can search for published vulnerabilities related to that version and launch attacks that specifically target those vulnerabilities.

```java Bad theme={"system"} @GetMapping(value = "/example") public ResponseEntity example() { HttpHeaders responseHeaders = new HttpHeaders(); responseHeaders.set("x-powered-by", "myproduct"); // Sensitive return new ResponseEntity( "example", responseHeaders, HttpStatus.CREATED); } ``` ```java Fix theme={"system"} ```

In object-oriented programming, inappropriately accessing static members of a base class via derived types is considered a code smell.

Static members are associated with the class itself, not with any specific instance of the class or its children classes. Accessing through the wrong type suggests a misunderstanding of the ownership and role of this member. This can make the maintenance of the code more complicated.

Therefore, the access should be done directly through the base class to maintain clarity and avoid potential misunderstandings.

```java Bad theme={"system"} class Parent { public static int counter; } class Child extends Parent { public Child() { Child.counter++; // Noncompliant } } ``` ```java Fix theme={"system"} class Parent { public static int counter; } class Child extends Parent { public Child() { Parent.counter++; } } ```

Code is sometimes annotated as deprecated by developers maintaining libraries or APIs to indicate that the method, class, or other programming element is no longer recommended for use. This is typically due to the introduction of a newer or more effective alternative. For example, when a better solution has been identified, or when the existing code presents potential errors or security risks.

Deprecation is a good practice because it helps to phase out obsolete code in a controlled manner, without breaking existing software that may still depend on it. It is a way to warn other developers not to use the deprecated element in new code, and to replace it in existing code when possible.

Deprecated classes, interfaces, and their members should not be used, inherited or extended because they will eventually be removed. The deprecation period allows you to make a smooth transition away from the aging, soon-to-be-retired technology.

Check the documentation or the deprecation message to understand why the code was deprecated and what the recommended alternative is.

```java Bad theme={"system"} /** * @deprecated As of release 1.3, replaced by {@link #Foo} */ @Deprecated public class Fum { ... } public class Foo { /** * @deprecated As of release 1.7, replaced by {@link #newMethod()} */ @Deprecated public void oldMethod() { ... } public void newMethod() { ... } } public class Bar extends Foo { public void oldMethod() { ... } // Noncompliant; don't override a deprecated method } public class Baz extends Fum { // Noncompliant; Fum is deprecated public void myMethod() { Foo foo = new Foo(); foo.oldMethod(); // Noncompliant; oldMethod method is deprecated } } ``` ```java Fix theme={"system"} ```

User enumeration refers to the ability to guess existing usernames in a web application database. This can happen, for example, when using "sign-in/sign-on/forgot password" functionalities of a website.

When an user tries to "sign-in" to a website with an incorrect username/login, the web application should not disclose that the username doesn’t exist with a message similar to "this username is incorrect", instead a generic message should be used like "bad credentials", this way it’s not possible to guess whether the username or password was incorrect during the authentication.

If a user-management feature discloses information about the existence of a username, attackers can use brute force attacks to retrieve a large amount of valid usernames that will impact the privacy of corresponding users and facilitate other attacks (phishing, password guessing etc …​).

```java Bad theme={"system"} public String authenticate(String username, String password) throws AuthenticationException { Details user = null; try { user = loadUserByUsername(username); } catch (UsernameNotFoundException | DataAccessException e) { // Hide this exception reason to not disclose that the username doesn't exist } if (user == null || !user.isPasswordCorrect(password)) { // User should not be able to guess if the bad credentials message is related to the username or the password throw new BadCredentialsException("Bad credentials"); } } ``` ```java Fix theme={"system"} DaoAuthenticationProvider daoauth = new DaoAuthenticationProvider(); daoauth.setUserDetailsService(new MyUserDetailsService()); daoauth.setPasswordEncoder(new BCryptPasswordEncoder()); daoauth.setHideUserNotFoundExceptions(true); // Compliant builder.authenticationProvider(daoauth); ```

WebViews can be used to display web content as part of a mobile application. A browser engine is used to render and display the content. Like a web application, a mobile application that uses WebViews can be vulnerable to Cross-Site Scripting if untrusted code is rendered. In the context of a WebView, JavaScript code can exfiltrate local files that might be sensitive or even worse, access exposed functions of the application that can result in more severe vulnerabilities such as code injection. Thus JavaScript support should not be enabled for WebViews unless it is absolutely necessary and the authenticity of the web resources can be guaranteed.

```java Bad theme={"system"} import android.webkit.WebView; WebView webView = (WebView) findViewById(R.id.webview); webView.getSettings().setJavaScriptEnabled(true); // Sensitive ``` ```java Fix theme={"system"} import android.webkit.WebView; WebView webView = (WebView) findViewById(R.id.webview); webView.getSettings().setJavaScriptEnabled(false); ```

This rule verifies that single-line comments are not located at the ends of lines of code. The main idea behind this rule is that in order to be really readable, trailing comments would have to be properly written and formatted (correct alignment, no interference with the visual structure of the code, not too long to be visible) but most often, automatic code formatters would not handle this correctly: the code would end up less readable. Comments are far better placed on the previous empty line of code, where they will always be visible and properly formatted.

```java Bad theme={"system"} int a1 = b + c; // This is a trailing comment that can be very very long ``` ```java Fix theme={"system"} // This very long comment is better placed before the line of code int a2 = b + c; ```

While it is possible to access static members from a class instance, it’s bad form, and considered by most to be misleading because it implies to the readers of your code that there’s an instance of the member per class instance.

```java Bad theme={"system"} public class A { public static int counter = 0; } public class B { private A first = new A(); private A second = new A(); public void runUpTheCount() { first.counter ++; // Noncompliant second.counter ++; // Noncompliant. A.counter is now 2, which is perhaps contrary to expectations } } ``` ```java Fix theme={"system"} public class A { public static int counter = 0; } public class B { private A first = new A(); private A second = new A(); public void runUpTheCount() { A.counter ++; // Compliant A.counter ++; // Compliant } } ```

Hardcoding IP addresses is security-sensitive. It has led in the past to the following vulnerabilities:

Today’s services have an ever-changing architecture due to their scaling and redundancy needs. It is a mistake to think that a service will always have the same IP address. When it does change, the hardcoded IP will have to be modified too. This will have an impact on the product development, delivery, and deployment:

  • The developers will have to do a rapid fix every time this happens, instead of having an operation team change a configuration file.

  • It misleads to use the same address in every environment (dev, sys, qa, prod).

Last but not least it has an effect on application security. Attackers might be able to decompile the code and thereby discover a potentially sensitive address. They can perform a Denial of Service attack on the service, try to get access to the system, or try to spoof the IP address to bypass security checks. Such attacks can always be possible, but in the case of a hardcoded IP address solving the issue will take more time, which will increase an attack’s impact.

```java Bad theme={"system"} String ip = System.getenv("IP_ADDRESS"); // Compliant Socket socket = new Socket(ip, 6667); ``` ```java Fix theme={"system"} ```

A cookie’s domain specifies which websites should be able to read it. Left blank, browsers are supposed to only send the cookie to sites that exactly match the sending domain. For example, if a cookie was set by lovely.dream.com, it should only be readable by that domain, and not by nightmare.com or even strange.dream.com. If you want to allow sub-domain access for a cookie, you can specify it by adding a dot in front of the cookie’s domain, like so: .dream.com. But cookie domains should always use at least two levels.

Cookie domains can be set either programmatically or via configuration. This rule raises an issue when any cookie domain is set with a single level, as in .com.

```java Bad theme={"system"} Cookie myCookie = new Cookie("name", "val"); // Compliant; by default, cookies are only returned to the server that sent them. // or Cookie myCookie = new Cookie("name", "val"); myCookie.setDomain(".myDomain.com"); // Compliant java.net.HttpCookie myOtherCookie = new java.net.HttpCookie("name", "val"); myOtherCookie.setDomain(".myDomain.com"); // Compliant ``` ```java Fix theme={"system"} ```

Developers often use TODO tags to mark areas in the code where additional work or improvements are needed but are not implemented immediately. However, these TODO tags sometimes get overlooked or forgotten, leading to incomplete or unfinished code. This rule aims to identify and address unattended TODO tags to ensure a clean and maintainable codebase. This description explores why this is a problem and how it can be fixed to improve the overall code quality.

```java Bad theme={"system"} void doSomething() { // TODO } ``` ```java Fix theme={"system"} ```

Storing files locally is a common task for mobile applications. Files that are stored unencrypted can be read out and modified by an attacker with physical access to the device. Access to sensitive data can be harmful for the user of the application, for example when the device gets stolen.

```java Bad theme={"system"} String masterKeyAlias = MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC); File file = new File(context.getFilesDir(), "secret_data"); EncryptedFile encryptedFile = EncryptedFile.Builder( file, context, masterKeyAlias, EncryptedFile.FileEncryptionScheme.AES256_GCM_HKDF_4KB ).build(); // write to the encrypted file FileOutputStream encryptedOutputStream = encryptedFile.openFileOutput(); ``` ```java Fix theme={"system"} ```

Character classes in regular expressions are a convenient way to match one of several possible characters by listing the allowed characters or ranges of characters. If the same character is listed twice in the same character class or if the character class contains overlapping ranges, this has no effect.

Thus duplicate characters in a character class are either a simple oversight or a sign that a range in the character class matches more than is intended or that the author misunderstood how character classes work and wanted to match more than one character. A common example of the latter mistake is trying to use a range like \[0-99] to match numbers of up to two digits, when in fact it is equivalent to \[0-9]. Another common cause is forgetting to escape the - character, creating an unintended range that overlaps with other characters in the character class.

```java Bad theme={"system"} str.matches("[0-99]") // Noncompliant, this won't actually match strings with two digits str.matches("[0-9.-_]") // Noncompliant, .-_ is a range that already contains 0-9 (as well as various other characters such as capital letters) ``` ```java Fix theme={"system"} str.matches("[0-9]{1,2}") str.matches("[0-9.\\-_]") ```

Nested code blocks create new scopes where variables declared within are inaccessible from the outside, and their lifespan ends with the block.

Although this may appear beneficial, their usage within a function often suggests that the function is overloaded. Thus, it may violate the Single Responsibility Principle, and the function needs to be broken down into smaller functions.

The presence of nested blocks that don’t affect the control flow might suggest possible mistakes in the code.

```java Bad theme={"system"} class Example { private final Deque stack = new LinkedList<>(); public void evaluate(int operator) { switch (operator) { case ADD: { /* ... */ { // Noncompliant - Extract this nested code block into a method int a = stack.pop(); int b = stack.pop(); int result = a + b; stack.push(result); } /* ... */ break; } /* ... */ } } } ``` ```java Fix theme={"system"} class Example { private final Deque stack = new LinkedList<>(); public void evaluate(int operator) { switch (operator) { case ADD: { /* ... */ evaluateAdd(); /* ... */ break; } /* ... */ } } private void evaluateAdd() { int a = stack.pop(); int b = stack.pop(); int result = a + b; stack.push(result); } } ```

If an alternative in a regular expression only matches things that are already matched by another alternative, that alternative is redundant and serves no purpose.

In the best case this means that the offending subpattern is merely redundant and should be removed. In the worst case it’s a sign that this regex does not match what it was intended to match and should be reworked.

```java Bad theme={"system"} "[ab]|a" // Noncompliant: the "|a" is redundant because "[ab]" already matches "a" ".*|a" // Noncompliant: .* matches everything, so any other alternative is redundant ``` ```java Fix theme={"system"} "[ab]" ".*" ```

Shared naming conventions make it possible for a team to collaborate efficiently. Following the established convention of single-letter type parameter names helps users and maintainers of your code quickly see the difference between a type parameter and a poorly named class.

This rule check that all type parameter names match a provided regular expression. The following code snippets use the default regular expression.

```java Bad theme={"system"} public class MyClass { // Noncompliant void method(TYPE t) { // Noncompliant } } ``` ```java Fix theme={"system"} public class MyClass { void method(T t) { } } ```

A naming convention in software development is a set of guidelines for naming code elements like variables, functions, and classes.

The goal of a naming convention is to make the code more readable and understandable, which makes it easier to maintain and debug. It also ensures consistency in the code, especially when multiple developers are working on the same project.

This rule checks that field names match a provided regular expression.

```java Bad theme={"system"} class MyClass { private int my_field; } ``` ```java Fix theme={"system"} class MyClass { private int myField; } ```

This rule raises an issue when a \{visibility} \{operationName} is never referenced in the code.

```java Bad theme={"system"} public class Foo implements Serializable { public static void doSomething() { Foo foo = new Foo(); ... } private void unusedPrivateMethod() {...} private void writeObject(ObjectOutputStream s) {...} //Compliant, relates to the java serialization mechanism private void readObject(ObjectInputStream in) {...} //Compliant, relates to the java serialization mechanism } ``` ```java Fix theme={"system"} public class Foo implements Serializable { public static void doSomething(){ Foo foo = new Foo(); ... } private void writeObject(ObjectOutputStream s) {...} //Compliant, relates to the java serialization mechanism private void readObject(ObjectInputStream in) {...} //Compliant, relates to the java serialization mechanism } ```

There is no good excuse for an empty class. If it’s being used simply as a common extension point, it should be replaced with an interface. If it was stubbed in as a placeholder for future development it should be fleshed-out. In any other case, it should be eliminated.

```java Bad theme={"system"} public interface Nothing { } ``` ```java Fix theme={"system"} @Configuration @EnableWebMvc public final class ApplicationConfiguration { } ```

In Unix file system permissions, the "`others`" category refers to all users except the owner of the file system resource and the members of the group assigned to this resource.

Granting permissions to this category can lead to unintended access to files or directories that could allow attackers to obtain sensitive information, disrupt services or elevate privileges.

```java Bad theme={"system"} public void setPermissionsSafe(String filePath) throws IOException { Set perms = new HashSet(); // user permission perms.add(PosixFilePermission.OWNER_READ); perms.add(PosixFilePermission.OWNER_WRITE); perms.add(PosixFilePermission.OWNER_EXECUTE); // group permissions perms.add(PosixFilePermission.GROUP_READ); perms.add(PosixFilePermission.GROUP_EXECUTE); // others permissions removed perms.remove(PosixFilePermission.OTHERS_READ); // Compliant perms.remove(PosixFilePermission.OTHERS_WRITE); // Compliant perms.remove(PosixFilePermission.OTHERS_EXECUTE); // Compliant Files.setPosixFilePermissions(Paths.get(filePath), perms); } ``` ```java Fix theme={"system"} ```

There’s no point in forcing the overhead of a method call for a method that always returns the same constant value. Even worse, the fact that a method call must be made will likely mislead developers who call the method thinking that something more is done. Declare a constant instead.

This rule raises an issue if on methods that contain only one statement: the return of a constant value.

```java Bad theme={"system"} static final int BEST_NUMBER = 12; ``` ```java Fix theme={"system"} ```

Empty statements represented by a semicolon ; are statements that do not perform any operation. They are often the result of a typo or a misunderstanding of the language syntax. It is a good practice to remove empty statements since they don’t add value and lead to confusion and errors.

```java Bad theme={"system"} void doSomething() { ; // Noncompliant - was used as a kind of TODO marker } void doSomethingElse() { System.out.println("Hello, world!");; // Noncompliant - double ; // ... } ``` ```java Fix theme={"system"} void doSomething() {} void doSomethingElse() { System.out.println("Hello, world!"); // ... for (int i = 0; i < 3; i++) ; // Compliant if unique statement of a loop // ... } ```

Security through obscurity is no security at all, and the use of Base64 encoding to obscure a password will only slow an attacker down for seconds, at the most. Instead, passwords should be encrypted with private keys that are at least 128 bits in length.

This rule checks for the use of Base64 decoding on values that are then used in database and LDAP connections.

```java Bad theme={"system"} String password = Base64.decode(retrievePassword()); DriverManager.getConnection(url, usr, password); // Noncompliant ``` ```java Fix theme={"system"} Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithMD5AndMGF1Padding"); cipher.init(Cipher.DECRYPT_MODE, privateKey); // key management out of scope for this example cipher.doFinal(retrievePassword())); ```

Having a variable with the same name in two unrelated classes is fine, but do the same thing within a class hierarchy and you’ll get confusion at best, chaos at worst.

```java Bad theme={"system"} public class Fruit { protected Season ripe; protected Color flesh; // ... } public class Raspberry extends Fruit { private boolean ripe; // Noncompliant private static Color FLESH; // Noncompliant } ``` ```java Fix theme={"system"} public class Fruit { protected Season ripe; protected Color flesh; // ... } public class Raspberry extends Fruit { private boolean ripened; private static Color FLESH_COLOR; } ```

When the execution is not explicitly terminated at the end of a switch case, it continues to execute the statements of the following case. While this is sometimes intentional, it often is a mistake which leads to unexpected behavior.

```java Bad theme={"system"} switch (myVariable) { case 0: // Empty case used to specify the same behavior for a group of cases. case 1: doSomething(); break; case 2: // Use of a fallthrough comment // fallthrough case 3: // Use of return statement return; case 4: // Use of throw statement throw new IllegalStateException(); case 5: // Use of continue statement continue; default: // For the last case, use of break statement is optional doSomethingElse(); } ``` ```java Fix theme={"system"} ```

Testing for loop termination using an equality operator (== and !=) is dangerous, because it could set up an infinite loop. Using a broader relational operator instead casts a wider net, and makes it harder (but not impossible) to accidentally write an infinite loop.

```java Bad theme={"system"} for (int i = 1; i != 10; i += 2) // Noncompliant. Infinite; i goes from 9 straight to 11. { //... } ``` ```java Fix theme={"system"} for (int i = 1; i <= 10; i += 2) // Compliant { //... } ```

Enabling runFinalizersOnExit is unsafe as it might result in erratic behavior and deadlocks on application exit.

Indeed, finalizers might be force-called on live objects while other threads are concurrently manipulating them.

Instead, if you want to execute something when the virtual machine begins its shutdown sequence, you should attach a shutdown hook.

```java Bad theme={"system"} public static void main(String [] args) { System.runFinalizersOnExit(true); // Noncompliant } protected void finalize(){ doShutdownOperations(); } ``` ```java Fix theme={"system"} public static void main(String [] args) { Thread myThread = new Thread( () -> { doShutdownOperations(); }); Runtime.getRuntime().addShutdownHook(myThread); } ```

Although they don’t affect the runtime behavior of the application after compilation, removing them will:

  • Improve the readability and maintainability of the code.

  • Help avoid potential naming conflicts.

  • Improve the build time, as the compiler has fewer lines to read and fewer types to resolve.

  • Reduce the number of items the code editor will show for auto-completion, thereby showing fewer irrelevant suggestions.

```java Bad theme={"system"} package myapp.helpers; import java.io.IOException; import java.nio.file.*; import java.nio.file.*; // Noncompliant - package is imported twice import java.lang.Runnable; // Noncompliant - java.lang is imported by default public class FileHelper { public static String readFirstLine(String filePath) throws IOException { return Files.readAllLines(Paths.get(filePath)).get(0); } } ``` ```java Fix theme={"system"} package myapp.helpers; import java.io.IOException; import java.nio.file.*; public class FileHelper { public static String readFirstLine(String filePath) throws IOException { return Files.readAllLines(Paths.get(filePath)).get(0); } } ```

Files with no lines of code clutter a project and should be removed.

```java Bad theme={"system"} //package org.foo; // //public class Bar {} ``` ```java Fix theme={"system"} ```

Cryptographic hash algorithms such as MD2, MD4, MD5, MD6, HAVAL-128, HMAC-MD5, DSA (which uses SHA-1), RIPEMD, RIPEMD-128, RIPEMD-160, HMACRIPEMD160 and SHA-1 are no longer considered secure, because it is possible to have collisions (little computational effort is enough to find two or more different inputs that produce the same hash).

```java Bad theme={"system"} MessageDigest md1 = MessageDigest.getInstance("SHA-512"); // Compliant ``` ```java Fix theme={"system"} ```

Ternary expressions, while concise, can often lead to code that is difficult to read and understand, especially when they are nested or complex. Prioritizing readability fosters maintainability and reduces the likelihood of bugs. Therefore, they should be removed in favor of more explicit control structures, such as if/else statements, to improve the clarity and readability of the code.

```java Bad theme={"system"} System.out.println(i>10?"yes":"no"); // Noncompliant ``` ```java Fix theme={"system"} if (i > 10) { System.out.println("yes"); } else { System.out.println("no"); } ```

The \`catch block of a checked exception "E" may be hidden because the corresponding try block only throws exceptions derived from E.

These derived exceptions are handled in dedicated catch blocks prior to the catch block of the base exception E.

The catch\` block of E is unreachable and should be considered dead code. It should be removed, or the entire try-catch structure should be refactored.

It is also possible that a single exception type in a multi-catch block may be hidden while the catch block itself is still reachable. In that case it is enough to only remove the hidden exception type or to replace it with another type.

```java Bad theme={"system"} public class HiddenCatchBlock { public static class CustomException extends Exception { } public static class CustomDerivedException extends CustomException { } public static void main(String[] args) { try { throwCustomDerivedException(); } catch(CustomDerivedException e) { // ... } catch(CustomException e) { // Noncompliant; this code is unreachable // ... } } private static void throwCustomDerivedException() throws CustomDerivedException { throw new CustomDerivedException(); } } ``` ```java Fix theme={"system"} public class HiddenCatchBlock { public static class CustomException extends Exception { } public static class CustomDerivedException extends CustomException { } public static void main(String[] args) { try { throwCustomDerivedException(); } catch(CustomDerivedException e) { // Compliant; try-catch block is "catching" only the Exception that can be thrown in the "try" //... } } } ```

Possessive quantifiers in Regex patterns like below improve performance by eliminating needless backtracking:

?+ , \*+ , ++ , \{n}+ , \{n,}+ , \{n,m}+

But because possessive quantifiers do not keep backtracking positions and never give back, the following sub-patterns should not match only similar characters. Otherwise, possessive quantifiers consume all characters that could have matched the following sub-patterns and nothing remains for the following sub-patterns.

```java Bad theme={"system"} Pattern pattern1 = Pattern.compile("a++abc"); // Noncompliant, the second 'a' never matches Pattern pattern2 = Pattern.compile("\\d*+[02468]"); // Noncompliant, the sub-pattern "[02468]" never matches ``` ```java Fix theme={"system"} Pattern pattern1 = Pattern.compile("aa++bc"); // Compliant, for example it can match "aaaabc" Pattern pattern2 = Pattern.compile("\\d*+(?<=[02468])"); // Compliant, for example it can match an even number like "1234" ```

Libraries used to unarchive a file (zip, bzip2, tar, …​) do what they were made for: they extract the content of the archive blindly, creating on the filesystem directories and files corresponding exactly to the content of the archive. Using a specially crafted archive containing some path traversal filenames, it is possible to create directories/files outside of the dir where the archive is extracted. This can lead to overwriting an executable or a configuration file with a file containing malicious code and transform a simple archive into a way to execute arbitrary code.

```java Bad theme={"system"} Enumeration entries = zipFile.entries(); while (entries.hasMoreElements()) { ZipEntry entry = entries.nextElement(); File extractedFile = new File(toDir, entry.getName()); FileOutputStream fos = new FileOutputStream(extractedFile); // Noncompliant; entry.getName() that was used to created "extractedFile" may be tainted with "../../../../../../../../tmp/evil.sh" InputStream input = zipFile.getInputStream(entry); IOUtils.copy(input, fos); } ``` ```java Fix theme={"system"} Enumeration entries = zipFile.entries(); while (entries.hasMoreElements()) { ZipEntry zipEntry = entries.nextElement(); String fileName = zipEntry.getName(); File extractedFile = new File(toDir, fileName); String canonicalDirPath = toDir.getCanonicalPath(); String canonicalDestPath = extractedFile.getCanonicalPath(); sanitizeAgainstZipFlipVulnerability(fileName, canonicalDestPath, canonicalDirPath); // Compliant FileOutputStream fos = new FileOutputStream(extractedFile); InputStream input = zipFile.getInputStream(entry); IOUtils.copy(input, fos); } public static void sanitizeAgainstZipFlipVulnerability(String fileName, String canonicalDestPath, String canonicalDirPath) throws ArchiverException { if (fileName.indexOf("..") != -1 && !canonicalDestPath.startsWith(canonicalDirPath + File.separator)) { // Sanitizer throw new ArchiverException("The file " + fileName + " is trying to leave the target output directory."); } } ```

There are several reasons to use a group in a regular expression:

  • to change the precedence (e.g. do(g|or) will match 'dog' and 'door')

  • to remember parenthesised part of the match in the case of capturing group

  • to improve readability

In any case, having an empty group is most probably a mistake. Either it is a leftover after refactoring and should be removed, or the actual parentheses were intended and were not escaped.

```java Bad theme={"system"} "foo()" // Noncompliant, will match only 'foo' ``` ```java Fix theme={"system"} "foo\\(\\)" // Matches 'foo()' ```

The use of a non-standard algorithm is dangerous because a determined attacker may be able to break the algorithm and compromise whatever data has been protected. Standard algorithms like \`SHA-256, SHA-384, SHA-512, …​ should be used instead.

This rule tracks creation of java.security.MessageDigest\` subclasses.

```java Bad theme={"system"} MessageDigest digest = MessageDigest.getInstance("SHA-256"); ``` ```java Fix theme={"system"} ```

The requirement for a final default clause is defensive programming. The clause should either take appropriate action, or contain a suitable comment as to why no action is taken.

```java Bad theme={"system"} switch (param) { //missing default clause case 0: doSomething(); break; case 1: doSomethingElse(); break; } switch (param) { default: // default clause should be the last one error(); break; case 0: doSomething(); break; case 1: doSomethingElse(); break; } ``` ```java Fix theme={"system"} switch (param) { case 0: doSomething(); break; case 1: doSomethingElse(); break; default: error(); break; } ```

There are valid cases for passing a variable multiple times into the same method call, but usually doing so is a mistake, and something else was intended for one of the arguments.

```java Bad theme={"system"} if (compare(myPoint.x, myPoint.x) != 0) { // Noncompliant   //... } if (compare(getNextValue(), getNextValue()) != 0) { // Noncompliant   // ... } ``` ```java Fix theme={"system"} if (compare(myPoint.x, myPoint.y) != 0) {   //... } Object v1 = getNextValue(); Object v2 = getNextValue(); if (compare(v1, v2) != 0) {   // ... } ```

In Android applications, broadcasting intents is security-sensitive. For example, it has led in the past to the following vulnerability:

By default, broadcasted intents are visible to every application, exposing all sensitive information they contain.

This rule raises an issue when an intent is broadcasted without specifying any "receiver permission".

```java Bad theme={"system"} import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.UserHandle; import android.support.annotation.RequiresApi; public class MyIntentBroadcast { @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1) public void broadcast(Intent intent, Context context, UserHandle user, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras, String broadcastPermission) { context.sendBroadcast(intent, broadcastPermission); context.sendBroadcastAsUser(intent, user, broadcastPermission); context.sendOrderedBroadcast(intent, broadcastPermission); context.sendOrderedBroadcastAsUser(intent, user,broadcastPermission, resultReceiver, scheduler, initialCode, initialData, initialExtras); } } ``` ```java Fix theme={"system"} ```

Android KeyStore is a secure container for storing key materials, in particular it prevents key materials extraction, i.e. when the application process is compromised, the attacker cannot extract keys but may still be able to use them. It’s possible to enable an Android security feature, user authentication, to restrict usage of keys to only authenticated users. The lock screen has to be unlocked with defined credentials (pattern/PIN/password, biometric).

```java Bad theme={"system"} KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore"); KeyGenParameterSpec builder = new KeyGenParameterSpec.Builder("test_secret_key_noncompliant", KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT) // Noncompliant .setBlockModes(KeyProperties.BLOCK_MODE_GCM) .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE) .build(); keyGenerator.init(builder); ``` ```java Fix theme={"system"} KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore"); KeyGenParameterSpec builder = new KeyGenParameterSpec.Builder("test_secret_key", KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT) .setBlockModes(KeyProperties.BLOCK_MODE_GCM) .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE) .setUserAuthenticationRequired(true) .setUserAuthenticationParameters (60, KeyProperties.AUTH_DEVICE_CREDENTIAL) .build(); keyGenerator.init(builder) ```

By default XML processors attempt to load all XML schemas and DTD (their locations are defined with xsi:schemaLocation attributes and DOCTYPE declarations), potentially from an external storage such as file system or network, which may lead, if no restrictions are put in place, to server-side request forgery (SSRF) vulnerabilities.

```java Bad theme={"system"} DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setValidating(true); // Noncompliant factory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", true); // Noncompliant SAXParserFactory factory = SAXParserFactory.newInstance(); factory.setValidating(true); // Noncompliant factory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", true); // Noncompliant SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); schemaFactory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", true); // Noncompliant ``` ```java Fix theme={"system"} SAXReader xmlReader = new SAXReader(); // Noncompliant xmlReader.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", true); // Noncompliant ```

Content security policy (CSP) (fetch directives) is a W3C standard which is used by a server to specify, via a http header, the origins from where the browser is allowed to load resources. It can help to mitigate the risk of cross site scripting (XSS) attacks and reduce privileges used by an application. If the website doesn’t define CSP header the browser will apply same-origin policy by default.

Content-Security-Policy: default-src 'self'; script-src ‘self ‘ [http://www.example.com](http://www.example.com)

In the above example, all resources are allowed from the website where this header is set and script resources fetched from example.com are also authorized:

\  \
        \ \
        \