I'm getting this warning on Sonar:

Hide Utility Class Constructor:

Utility classes should not have a public or default constructor

My class:

👉 For more insights, check out this resource.

public class FilePathHelper { private static String resourcesPath; public static String getFilePath(HttpServletRequest request) { if(resourcesPath == null) { String serverpath = request.getSession() .getServletContext() .getRealPath(""); resourcesPath = serverpath + "/WEB-INF/classes/"; } return resourcesPath; } } 

I want solution to remove this warning on Sonar Qube.

1
Table of Contents

12 Answers

If this class is only a utility class, you should make the class final and define a private constructor:

👉 Discover more in this in-depth guide.

public final class FilePathHelper { private FilePathHelper() { //not called } } 

This prevents the default parameter-less constructor from being used elsewhere in your code.

Additionally, you can make the class final, so that it can't be extended in subclasses, which is a best practice for utility classes. Since you declared only a private constructor, other classes wouldn't be able to extend it anyway, but it is still a best practice to mark the class as final.

12

I don't know Sonar, but I suspect it's looking for a private constructor:

private FilePathHelper() { // No-op; won't be called } 

Otherwise the Java compiler will provide a public parameterless constructor, which you really don't want.

(You should also make the class final, although other classes wouldn't be able to extend it anyway due to it only having a private constructor.)

I use an enum with no instances

public enum MyUtils { ; // no instances // class is final and the constructor is private public static int myUtilityMethod(int x) { return x * x; } } 

you can call this using

int y = MyUtils.myUtilityMethod(5); // returns 25. 
5

Best practice is to throw an error if the class is constructed.

Example:

/** * The Class FooUtilityService. */ final class FooUtilityService{ /** * Instantiates a new FooUtilityService. Private to prevent instantiation */ private FooUtilityService() { // Throw an exception if this ever *is* called throw new AssertionError("Instantiating utility class."); } 
3

You can just use Lombok annotation to avoid unnecessary initialization.

Using @NoArgsConstructor with AccessLevel.PRIVATE as bellow:

@NoArgsConstructor(access = AccessLevel.PRIVATE) public class FilePathHelper { // your code } 

I recommend just disabling this rule in Sonar, there is no real benefit of introducing a private constructor, just redundant characters in your codebase other people need to read and computer needs to store and process.

5

Alternative using Lombok is use @UtilityClass annotation.

@UtilityClass was introduced as an experimental feature in Lombok v1.16.2:

If a class is annotated with @UtilityClass, the following things happen to it:

  • It is marked final.
  • If any constructors are declared in it, an error is generated.
    • Otherwise, a private no-args constructor is generated; it throws a UnsupportedOperationException.
  • All methods, inner classes, and fields in the class are marked static.

Overview:

A utility class is a class that is just a namespace for functions. No instances of it can exist, and all its members are static. For example, java.lang.Math and java.util.Collections are well known utility classes.

This annotation automatically turns the annotated class into one.

A utility class cannot be instantiated.

By marking your class with @UtilityClass, lombok will automatically generate a private constructor that throws an exception, flags as error any explicit constructors you add, and marks the class final.

If the class is an inner class, the class is also marked static.

All members of a utility class are automatically marked as static. Even fields and inner classes.

Example:

import lombok.experimental.UtilityClass; @UtilityClass public class FilePathHelper { private static String resourcesPath; public static String getFilePath(HttpServletRequest request) { if(resourcesPath == null) { ServletContext context = request.getSession().getServletContext(); String serverpath = context.getRealPath(""); resourcesPath = serverpath + "/WEB-INF/classes/"; } return resourcesPath; } } 

Reference from official documentation:

Although using @UtilityClass annotation will show issue on sonarCube. So basic problem is "Java provide a default no-argument public constructor" for a class. now we have two solutions -

  1. Remove @UtilityClass and make it static final class with private constructor.
  2. Instead of using it as class, Use it as Enum . but -

When the problem in sonarQube then use - @SuppressWarnings("java:###") "###" rule number.

1

Add private constructor:

private FilePathHelper(){ super(); } 
1
public class LmsEmpWfhUtils { private LmsEmpWfhUtils() { // prevents access default paramater-less constructor } } 

This prevents the default parameter-less constructor from being used elsewhere in your code.

SonarQube documentation recommends adding static keyword to the class declaration.

That is, change public class FilePathHelper to public static class FilePathHelper.

Alternatively you can add a private or protected constructor.

public class FilePathHelper { // private or protected constructor // because all public fields and methods are static private FilePathHelper() { } } 
1

make the utility class final and add a private constructor

1