title: Define and throw a dedicated exception instead of using a generic one
body: <p>SonarQube is complaining about RuntimeException:
  "Define and throw a dedicated exception instead of using a generic one".</p>
  
  <p>How can I solve this in an elegant way?</p>
  
  <pre><code> public class ExceptionDefinition&lt;T extends Throwable&gt; {
  
      private final String id;
      private final MessageFormat format;
      private final Class&lt;T&gt; exceptionClass;
  
      public ExceptionDefinition( String id, Class&lt;T&gt; exceptionClass, String format ) {
          this.id = id;
          this.exceptionClass = exceptionClass;
          this.format = new MessageFormat( format );
      }
  
      public T create( Object... parameters ) throws T {
          try {
              final Constructor&lt;T&gt; constructor = exceptionClass.getConstructor( String.class );
              final T exception = constructor.newInstance( generateMessage( parameters ) );
              fillInStackDetails( exception );
              return exception;
          } catch ( InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException e ) {
              throw new RuntimeException( "An exception was thrown while creating exception", e );
          }
      }
  
      private String generateMessage( Object... parameters ) {
          return String.format( "%s - %s", id, format.format( parameters ) );
      }
  
      private void fillInStackDetails( T exception ) {
          final StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
          if ( stackTrace.length &gt; 3 ) {
              final StackTraceElement[] newTrace = Arrays.copyOfRange( stackTrace, 3, stackTrace.length );
              exception.setStackTrace( newTrace );
          }
      }
  }
  </code></pre>
  
  <p>UPDATE:</p>
  
  <pre><code>public class Exceptions {
  
      public static final ExceptionDefinition&lt;RabbitMQException&gt; UnableToCreateTargetDirectory = new ExceptionDefinition&lt;&gt;( "RBB001", RabbitMQException.class, "Unable to create target directory {0}" );
      public static final ExceptionDefinition&lt;RabbitMQException&gt; UnableToWriteOnTargetDirectory = new ExceptionDefinition&lt;&gt;( "RBB002", RabbitMQException.class, "Target directory {0} is not writeable" );
      ...
  }
  </code></pre>
  
  <p>Custom Exception:</p>
  
  <pre><code>public class RabbitMQException extends RuntimeException {
      private static final long serialVersionUID = 888888888888888286L;
  
      public RabbitMQException( String message ) {
          super( message );
      }
  
      public RabbitMQException( String message, Throwable cause ) {
          super( message, cause );
      }
  }
  </code></pre>
  
  <p>Usage of the custom exceptions:</p>
  
  <pre><code>private void startConsumer( final RabbitConsumerBuilder consumerBuilder ) {
          if ( connection == null ) {
              // log
              throw Exceptions.NoConnection.create();
          }
          ...
  }
  </code></pre>