2 Replies Latest reply: Oct 8, 2013 7:36 AM by ea76cb98-67b1-40e4-a15d-8fe1b8a2d70d RSS

    getContextClassLoader() in javax.mail.Session.getService(Provider provider, URLName url)

    ea76cb98-67b1-40e4-a15d-8fe1b8a2d70d

      I am setting up Logback with SMTPAppender for glassfish 4 and having issues with javax.mail.Session's getService(Provider provider, URLName url) method. I have put all the logback jars and javax.mail (javax.mail.jar; jcl-over-slf4j-1.7.5.jar; jul-to-slf4j-1.7.5.jar; logback-classic-1.0.13.jar; logback-core-1.0.13.jar; slf4j-api-1.7.5.jar) in glassfish4\glassfish\lib\endorsed. The getService method, instead of loading the service class by utilizing this.getClass().getClassLoader(), relies on getContextClassLoader(). The service class in my setup is com.sun.mail.smtp.SMTPTransport. Since the javax.mail.Session.class, javax.mail.URLName.class are loaded directly, they resolve to the classes in the endorsed directory. However, the service class is loaded through getContextClassLoader() and it resolves to the class of the jar in glassfish4\glassfish\modules. As a result, the code can't find the constructor:

       

       

      Class[] c = {javax.mail.Session.class, javax.mail.URLName.class};

      Constructor cons = serviceClass.getConstructor(c);

       

       

      I started to wonder, why the code section below exists in Session.getService(...).

       

       

      // First try the "application's" class loader.

           ClassLoader ccl = getContextClassLoader();

           if (ccl != null)

        try {

           serviceClass =

        Class.forName(provider.getClassName(), false, ccl);

        } catch (ClassNotFoundException ex) {

           // ignore it

        }

       

       

      Thanks,

      Janos

        • 1. Re: getContextClassLoader() in javax.mail.Session.getService(Provider provider, URLName url)
          Bshannon-Oracle

          I'm not sure I fully understand what you're trying to do...

           

          First, JavaMail is already included with GlassFish, so you shouldn't need to install the JavaMail jar files anywhere.

           

          It's not clear whether you're trying to make JavaMail work with your provider, or whether you're having trouble because JavaMail can't find it's own providers.  If the latter, start by removing the JavaMail jar file that you put in the endorsed directory.  If that doesn't help, please provide more details about what exactly is failing.  If you're calling JavaMail from a context in which the thread's context class loader has been set up, it should still fall back to finding the class relative to JavaMail's class loader.  Possibly you're running into an OSGi class loading issue.

           

          The JavaMail code you're looking at is intended to be able to load providers from within the application (located using the thread's context class loader), or from any parent class loader using the normal class loader delegation model.

          • 2. Re: getContextClassLoader() in javax.mail.Session.getService(Provider provider, URLName url)
            ea76cb98-67b1-40e4-a15d-8fe1b8a2d70d

            I am trying to redirect all the logs to logback from glassfish. I set it up according to this tutorial: Glassfish 3.1.2 logging with slf4j and logback | jitter-free.org Also, I would like to send an email if an error appears in the logs. In order to do so, I utilize SMTPAppender. That is, I copied the logback and slf4j jars listed above into $GF_INSTALL/glassfish/lib/endorsed. However, when I start the server I see the exception below and do not receive any e-mails:

             

            -ERROR in ch.qos.logback.core.joran.action.AppenderAction - Could not create an Appender of type [ch.qos.logback.classic.net.SMTPAppender]. ch.qos.logback.core.util.DynamicClassLoadingException: Failed to instantiate type ch.qos.logback.classic.net.SMTPAppender

              at ch.qos.logback.core.util.DynamicClassLoadingException: Failed to instantiate type ch.qos.logback.classic.net.SMTPAppender

              at at ch.qos.logback.core.util.OptionHelper.instantiateByClassNameAndParameter(OptionHelper.java:73)

              at at ch.qos.logback.core.util.OptionHelper.instantiateByClassName(OptionHelper.java:48)

              at at ch.qos.logback.core.util.OptionHelper.instantiateByClassName(OptionHelper.java:35)

              at at ch.qos.logback.core.joran.action.AppenderAction.begin(AppenderAction.java:54)

              at at ch.qos.logback.core.joran.spi.Interpreter.callBeginAction(Interpreter.java:275)

              at at ch.qos.logback.core.joran.spi.Interpreter.startElement(Interpreter.java:147)

              at at ch.qos.logback.core.joran.spi.Interpreter.startElement(Interpreter.java:129)

              at at ch.qos.logback.core.joran.spi.EventPlayer.play(EventPlayer.java:50)

              at at ch.qos.logback.core.joran.GenericConfigurator.doConfigure(GenericConfigurator.java:149)

              at at ch.qos.logback.core.joran.GenericConfigurator.doConfigure(GenericConfigurator.java:135)

              at at ch.qos.logback.core.joran.GenericConfigurator.doConfigure(GenericConfigurator.java:99)

              at at ch.qos.logback.core.joran.GenericConfigurator.doConfigure(GenericConfigurator.java:49)

              at at ch.qos.logback.classic.util.ContextInitializer.configureByResource(ContextInitializer.java:75)

              at at ch.qos.logback.classic.util.ContextInitializer.autoConfig(ContextInitializer.java:148)

              at at org.slf4j.impl.StaticLoggerBinder.init(StaticLoggerBinder.java:85)

              at at org.slf4j.impl.StaticLoggerBinder.<clinit>(StaticLoggerBinder.java:55)

              at at org.slf4j.LoggerFactory.bind(LoggerFactory.java:128)

              at at org.slf4j.LoggerFactory.performInitialization(LoggerFactory.java:107)

              at at org.slf4j.LoggerFactory.getILoggerFactory(LoggerFactory.java:295)

              at at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:269)

              at at org.slf4j.bridge.SLF4JBridgeHandler.getSLF4JLogger(SLF4JBridgeHandler.java:204)

              at at org.slf4j.bridge.SLF4JBridgeHandler.publish(SLF4JBridgeHandler.java:291)

              at at java.util.logging.Logger.log(Logger.java:610)

              at at com.sun.enterprise.server.logging.LogManagerService.postConstruct(LogManagerService.java:621)

              at at org.jvnet.hk2.internal.ClazzCreator.postConstructMe(ClazzCreator.java:281)

              at at org.jvnet.hk2.internal.ClazzCreator.create(ClazzCreator.java:328)

              at at org.jvnet.hk2.internal.SystemDescriptor.create(SystemDescriptor.java:448)

              at at org.glassfish.hk2.runlevel.internal.AsyncRunLevelContext.findOrCreate(AsyncRunLevelContext.java:163)

              at at org.jvnet.hk2.internal.Utilities.createService(Utilities.java:2204)

              at at org.jvnet.hk2.internal.ServiceHandleImpl.getService(ServiceHandleImpl.java:93)

              at at org.glassfish.hk2.runlevel.internal.CurrentTaskFuture$QueueRunner.oneJob(CurrentTaskFuture.java:673)

              at at org.glassfish.hk2.runlevel.internal.CurrentTaskFuture$QueueRunner.run(CurrentTaskFuture.java:660)

              at at org.glassfish.hk2.runlevel.internal.CurrentTaskFuture$UpOneJob.run(CurrentTaskFuture.java:490)

              at at org.glassfish.hk2.runlevel.internal.CurrentTaskFuture$UpAllTheWay.go(CurrentTaskFuture.java:362)

              at at org.glassfish.hk2.runlevel.internal.CurrentTaskFuture$UpAllTheWay.access$100(CurrentTaskFuture.java:279)

              at at org.glassfish.hk2.runlevel.internal.CurrentTaskFuture.go(CurrentTaskFuture.java:113)

              at at org.glassfish.hk2.runlevel.internal.AsyncRunLevelContext.proceedTo(AsyncRunLevelContext.java:296)

              at at org.glassfish.hk2.runlevel.internal.RunLevelControllerImpl.proceedTo(RunLevelControllerImpl.java:66)

              at at com.sun.enterprise.v3.server.AppServerStartup.proceedTo(AppServerStartup.java:532)

              at at com.sun.enterprise.v3.server.AppServerStartup.run(AppServerStartup.java:313)

              at at com.sun.enterprise.v3.server.AppServerStartup.doStart(AppServerStartup.java:226)

              at at com.sun.enterprise.v3.server.AppServerStartup.start(AppServerStartup.java:217)

              at at com.sun.enterprise.glassfish.bootstrap.GlassFishImpl.start(GlassFishImpl.java:79)

              at at com.sun.enterprise.glassfish.bootstrap.GlassFishDecorator.start(GlassFishDecorator.java:63)

              at at com.sun.enterprise.glassfish.bootstrap.osgi.EmbeddedOSGiGlassFishImpl.start(EmbeddedOSGiGlassFishImpl.java:75)

              at at com.sun.enterprise.glassfish.bootstrap.GlassFishDecorator.start(GlassFishDecorator.java:63)

              at at com.sun.enterprise.glassfish.bootstrap.osgi.OSGiGlassFishImpl.start(OSGiGlassFishImpl.java:71)

              at at com.sun.enterprise.glassfish.bootstrap.GlassFishMain$Launcher.launch(GlassFishMain.java:117)

              at at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

              at at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)

              at at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

              at at java.lang.reflect.Method.invoke(Method.java:606)

              at at com.sun.enterprise.glassfish.bootstrap.GlassFishMain.main(GlassFishMain.java:97)

              at at com.sun.enterprise.glassfish.bootstrap.ASMain.main(ASMain.java:54)

            Caused by: java.lang.NoClassDefFoundError: javax/mail/internet/InternetAddress

              at at ch.qos.logback.core.net.SMTPAppenderBase.<clinit>(SMTPAppenderBase.java:64)

              at at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)

              at at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)

              at at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)

              at at java.lang.reflect.Constructor.newInstance(Constructor.java:526)

              at at java.lang.Class.newInstance(Class.java:374)

              at at ch.qos.logback.core.util.OptionHelper.instantiateByClassNameAndParameter(OptionHelper.java:65)

              at ... 53 common frames omitted]]

             

             

            [2013-10-08T14:18:32.787+0200] [glassfish 4.0] [INFO] [] [] [tid: _ThreadID=1 _ThreadName=Thread-3] [timeMillis: 1381234712787] [levelValue: 800] [[

              14:18:32,786 |-ERROR in ch.qos.logback.core.joran.spi.Interpreter@35:76 - ActionException in Action for tag [appender] ch.qos.logback.core.joran.spi.ActionException: ch.qos.logback.core.util.DynamicClassLoadingException: Failed to instantiate type ch.qos.logback.classic.net.SMTPAppender

              at ch.qos.logback.core.joran.spi.ActionException: ch.qos.logback.core.util.DynamicClassLoadingException: Failed to instantiate type ch.qos.logback.classic.net.SMTPAppender

              at at ch.qos.logback.core.joran.action.AppenderAction.begin(AppenderAction.java:82)

              at at ch.qos.logback.core.joran.spi.Interpreter.callBeginAction(Interpreter.java:275)

              at at ch.qos.logback.core.joran.spi.Interpreter.startElement(Interpreter.java:147)

              at at ch.qos.logback.core.joran.spi.Interpreter.startElement(Interpreter.java:129)

              at at ch.qos.logback.core.joran.spi.EventPlayer.play(EventPlayer.java:50)

              at at ch.qos.logback.core.joran.GenericConfigurator.doConfigure(GenericConfigurator.java:149)

              at at ch.qos.logback.core.joran.GenericConfigurator.doConfigure(GenericConfigurator.java:135)

              at at ch.qos.logback.core.joran.GenericConfigurator.doConfigure(GenericConfigurator.java:99)

              at at ch.qos.logback.core.joran.GenericConfigurator.doConfigure(GenericConfigurator.java:49)

              at at ch.qos.logback.classic.util.ContextInitializer.configureByResource(ContextInitializer.java:75)

              at at ch.qos.logback.classic.util.ContextInitializer.autoConfig(ContextInitializer.java:148)

              at at org.slf4j.impl.StaticLoggerBinder.init(StaticLoggerBinder.java:85)

              at at org.slf4j.impl.StaticLoggerBinder.<clinit>(StaticLoggerBinder.java:55)

              at at org.slf4j.LoggerFactory.bind(LoggerFactory.java:128)

              at at org.slf4j.LoggerFactory.performInitialization(LoggerFactory.java:107)

              at at org.slf4j.LoggerFactory.getILoggerFactory(LoggerFactory.java:295)

              at at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:269)

              at at org.slf4j.bridge.SLF4JBridgeHandler.getSLF4JLogger(SLF4JBridgeHandler.java:204)

              at at org.slf4j.bridge.SLF4JBridgeHandler.publish(SLF4JBridgeHandler.java:291)

              at at java.util.logging.Logger.log(Logger.java:610)

              at at com.sun.enterprise.server.logging.LogManagerService.postConstruct(LogManagerService.java:621)

              at at org.jvnet.hk2.internal.ClazzCreator.postConstructMe(ClazzCreator.java:281)

              at at org.jvnet.hk2.internal.ClazzCreator.create(ClazzCreator.java:328)

              at at org.jvnet.hk2.internal.SystemDescriptor.create(SystemDescriptor.java:448)

              at at org.glassfish.hk2.runlevel.internal.AsyncRunLevelContext.findOrCreate(AsyncRunLevelContext.java:163)

              at at org.jvnet.hk2.internal.Utilities.createService(Utilities.java:2204)

              at at org.jvnet.hk2.internal.ServiceHandleImpl.getService(ServiceHandleImpl.java:93)

              at at org.glassfish.hk2.runlevel.internal.CurrentTaskFuture$QueueRunner.oneJob(CurrentTaskFuture.java:673)

              at at org.glassfish.hk2.runlevel.internal.CurrentTaskFuture$QueueRunner.run(CurrentTaskFuture.java:660)

              at at org.glassfish.hk2.runlevel.internal.CurrentTaskFuture$UpOneJob.run(CurrentTaskFuture.java:490)

              at at org.glassfish.hk2.runlevel.internal.CurrentTaskFuture$UpAllTheWay.go(CurrentTaskFuture.java:362)

              at at org.glassfish.hk2.runlevel.internal.CurrentTaskFuture$UpAllTheWay.access$100(CurrentTaskFuture.java:279)

              at at org.glassfish.hk2.runlevel.internal.CurrentTaskFuture.go(CurrentTaskFuture.java:113)

              at at org.glassfish.hk2.runlevel.internal.AsyncRunLevelContext.proceedTo(AsyncRunLevelContext.java:296)

              at at org.glassfish.hk2.runlevel.internal.RunLevelControllerImpl.proceedTo(RunLevelControllerImpl.java:66)

              at at com.sun.enterprise.v3.server.AppServerStartup.proceedTo(AppServerStartup.java:532)

              at at com.sun.enterprise.v3.server.AppServerStartup.run(AppServerStartup.java:313)

              at at com.sun.enterprise.v3.server.AppServerStartup.doStart(AppServerStartup.java:226)

              at at com.sun.enterprise.v3.server.AppServerStartup.start(AppServerStartup.java:217)

              at at com.sun.enterprise.glassfish.bootstrap.GlassFishImpl.start(GlassFishImpl.java:79)

              at at com.sun.enterprise.glassfish.bootstrap.GlassFishDecorator.start(GlassFishDecorator.java:63)

              at at com.sun.enterprise.glassfish.bootstrap.osgi.EmbeddedOSGiGlassFishImpl.start(EmbeddedOSGiGlassFishImpl.java:75)

              at at com.sun.enterprise.glassfish.bootstrap.GlassFishDecorator.start(GlassFishDecorator.java:63)

              at at com.sun.enterprise.glassfish.bootstrap.osgi.OSGiGlassFishImpl.start(OSGiGlassFishImpl.java:71)

              at at com.sun.enterprise.glassfish.bootstrap.GlassFishMain$Launcher.launch(GlassFishMain.java:117)

              at at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

              at at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)

              at at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

              at at java.lang.reflect.Method.invoke(Method.java:606)

              at at com.sun.enterprise.glassfish.bootstrap.GlassFishMain.main(GlassFishMain.java:97)

              at at com.sun.enterprise.glassfish.bootstrap.ASMain.main(ASMain.java:54)

            Caused by: ch.qos.logback.core.util.DynamicClassLoadingException: Failed to instantiate type ch.qos.logback.classic.net.SMTPAppender

              at at ch.qos.logback.core.util.OptionHelper.instantiateByClassNameAndParameter(OptionHelper.java:73)

              at at ch.qos.logback.core.util.OptionHelper.instantiateByClassName(OptionHelper.java:48)

              at at ch.qos.logback.core.util.OptionHelper.instantiateByClassName(OptionHelper.java:35)

              at at ch.qos.logback.core.joran.action.AppenderAction.begin(AppenderAction.java:54)

              at ... 50 common frames omitted

            Caused by: java.lang.NoClassDefFoundError: javax/mail/internet/InternetAddress

              at at ch.qos.logback.core.net.SMTPAppenderBase.<clinit>(SMTPAppenderBase.java:64)

              at at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)

              at at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)

              at at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)

              at at java.lang.reflect.Constructor.newInstance(Constructor.java:526)

              at at java.lang.Class.newInstance(Class.java:374)

              at at ch.qos.logback.core.util.OptionHelper.instantiateByClassNameAndParameter(OptionHelper.java:65)

              at ... 53 common frames omitted]]

             

            I tried to fix it by putting javax.mail jar with the missing classes into $GF_INSTALL/glassfish/lib/endorsed, next to the logback jars. The result is another exception:


            -ERROR in ch.qos.logback.classic.net.SMTPAppender[EMAIL] - Error occurred while sending e-mail notification. javax.mail.NoSuchProviderException: smtp

              at javax.mail.NoSuchProviderException: smtp

              at at javax.mail.Session.getService(Session.java:806)

              at at javax.mail.Session.getTransport(Session.java:728)

              at at javax.mail.Session.getTransport(Session.java:668)

              at at javax.mail.Session.getTransport(Session.java:648)

              at at javax.mail.Session.getTransport(Session.java:705)

              at at javax.mail.Transport.send0(Transport.java:248)

              at at javax.mail.Transport.send(Transport.java:124)

              at at ch.qos.logback.core.net.SMTPAppenderBase.sendBuffer(SMTPAppenderBase.java:395)

              at at ch.qos.logback.core.net.SMTPAppenderBase$SenderRunnable.run(SMTPAppenderBase.java:689)

              at at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)

              at at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)

              at at java.lang.Thread.run(Thread.java:724)]]

             

            I debugged the javax.mail.Session class and know exactly, that com.sun.mail.smtp.SMTPTransport, javax.mail.Session and javax.mail.URLName classes loaded at least twice (same class name with different id-s). I also realized, that the logging would work if javax.mail.Session and javax.mail.URLName haven't referenced directly, but through getContextClassLoader(). That is why I asked my original question.

             

            Thanks, for the OSGi class loading hint. I will investigate that too.