JavaMail: Access to default session denied

openfire 插件中使用javamail 發送郵件時有如下問題發生:

Access to default session denied

對這個問題的詳細解釋如下:

http://stackoverflow.com/questions/4184204/what-is-the-difference-between-getdefaultinstance-and-getinstance-in-session

What is the difference between Session.getDefaultInstance(props, authenticator) and getInstance(props, authenticator)? In general, when will you choose one over the other?

I also read Java doc on getDefaultInstance(props, authenticator), but still couldn't able to make out the difference distinctly/clearly.

Hope experts can help me in understanding this better.

UPDATE: Actual reason that triggered to ask this question is: We've used Session.getDefaultInstance() method in some places within our web-based application. Sometimes, it throws java.lang.SecurityException: Access to default session denied, on quick googling, it suggested to use Session.getInstance() method instead. Hence, when one would choose one over the other?

If you read the documentation, you will see that

getDefaultInstance Get the default Session object. If a default has not yet been setup, a new Session object is created and installed as the default.

Therefore, if one does not already exist, it call getInstance()

getInstance Get a new Session object.

So, a new session object is created, regardless of whether one already exists.

Actual reason for asking this question is explained here: We've used Session.getDefaultInstance()method in some places within our web-based application. Sometimes, it throws java.lang.SecurityException: Access to default session denied, on quick googling, it suggested to use Session.getInstance() method instead. And that's the reason I've asked here when one would choose one over the other?

The only I reason I can see to use defaultinstance, is that it prevents the need to create multiple instances needlessly of the session, but other than that there is no difference. If you are having trouble with permissions, then just use getInstance(), it shouldn't cause you a problem. Your application however, should store this at a global level however, rather than create a new instance each time you need it. 

Per doc, getDefaultInstance(): Get the default Session object. If a default has not yet been setup, a new Session object is created and installed as the default., will subsequent calls to getDefaultInstance() just not make use of the session that was created before? 

@Gnanam, yes, but it uses a shared instance across JVM's (reading between the lines in the documentation that says a session can be shared across the desktop). So, that is possibly why he is getting his error, that it is using a shared instance and accessing it with the wrong credentials. So, to prevent the error, it is safer not to use getDefaultInstance(). 

A very important side affect of using getDefaultInstance is that if the session is already created your properties you passed in will be ignored. The existing sessions properties will not be updated in any way, so if you're changing any properties you want to be using getInstance.


Cause This error is raised in the getDefaultInstance method in javax.mail.Session.java. According to this source code, this error occures when the default session object is already initialized, but authenticator instance is renewed or changed, or the class loader of the default session object is different from the argument authentificator's. Maybe the java source code using the default session instance of the java mail is recompiled and reloaded, or duplicate javamail class libraries are included into the Classpath of the environment. it gives proper solution

javax.mail.Session.java file
   public static synchronized Session getDefaultInstance(Properties props,
                                       Authenticator authenticator) {
       if (defaultSession == null)
           defaultSession = new Session(props, authenticator);
       else {
           // have to check whether caller is allowed to see default session
           if (defaultSession.authenticator == authenticator)
               ;       // either same object or both null, either way OK
           else if (defaultSession.authenticator != null &&
                   authenticator != null &&
                   defaultSession.authenticator.getClass().getClassLoader() ==
                       authenticator.getClass().getClassLoader())
               ;       // both objects came from the same class loader, OK
           else
               // anything else is not allowed
               throw new SecurityException("Access to default session denied");
       }

       return defaultSession;
   }


與jvm、classloader有關,學藝不精,暫時不能解釋
結論:
使用getInstance()替換getDefaultInstance()即可,不會有問題。
openfire插件在使用一些類似功能時都會有這種問題發生。
使用morphia也有,解決方案暫時定爲:(1)自己實現一套mongo(2)不使用morphia。。待測試


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章