hstaudacher / osgi-jax-rs-connector

An OSGi - JAX-RS 2.0 Connector, software repository available on the link below
http://hstaudacher.github.io/osgi-jax-rs-connector
Other
191 stars 98 forks source link

Exceptions are muted during Jersey Context initialization. #191

Open xeagle2 opened 7 years ago

xeagle2 commented 7 years ago

In projects I have a problem when most of the exceptions are not logged anywhere and nobody knows what happens and why Jersey is not always ready.

My observations are below:

In ServletContainerBridge.run method getServletContainer().init( servletConfig ); can throw any type of unchecked exceptions which are not handled or logged anywhere.

The following block catches only ServletException.

public void run() {
    if( application.isDirty() ) {
      ClassLoader original = Thread.currentThread().getContextClassLoader();
      try {
        Thread.currentThread().setContextClassLoader( Request.class.getClassLoader() );
        synchronized( this ) {
          if( !isJerseyReady() ) {
            // if jersey has not been initialized - use the init method
            getServletContainer().init( servletConfig );
          } else {
            // otherwise reload
            isJerseyReady = false;
            getServletContainer().reload( ResourceConfig.forApplication( application ) );
          }
          isJerseyReady = true;
        }
      } catch( ServletException e ) {
        throw new RuntimeException( e );
      } finally {
        Thread.currentThread().setContextClassLoader( original );
      }
    }

If unchecked exception is thrown it goes up to parent level which is executor at ResourcePublisher

private final ScheduledExecutorService executor;

Executor is created as

Step 1: Class JerseyContext

this.resourcePublisher = new ResourcePublisher( servletContainerBridge, configuration.getPublishDelay() );

Step 2: ResourcePublisher

this( createExecutor(), servletContainerBridge, publishDelay ););

Step 3: ResourcePublisher.createExecutor

private static ScheduledExecutorService createExecutor() {
    return Executors.newSingleThreadScheduledExecutor( new ThreadFactory() {

      @Override
      public Thread newThread( Runnable runnable ) {
        Thread thread = new Thread( runnable, "ResourcePublisher" );
        thread.setUncaughtExceptionHandler( new UncaughtExceptionHandler() {

          @Override
          public void uncaughtException( Thread thread, Throwable exception ) {
            throw new IllegalStateException( exception );
          }
        } );
        return thread;
      }
    } );
  }

where uncaughtException throws IllegalStateException.

I guess this is a critical issue and it would be helpful if at least slf4j logging is introduced as soon as possible.

Thank you,