Java 为什么tomcat返回错误HTTP500?
我创建了自己的会话,子类为Java 为什么tomcat返回错误HTTP500?,java,tomcat,wicket,Java,Tomcat,Wicket,我创建了自己的会话,子类为WebSession。在Tomcat控制台中,我可以看到正在抛出异常: pqlrd.is.seguridad.SesionPQLRD cannot be cast to org.apache.wicket.Session 我的扩展网络会话: package pqlrd.is.seguridad; import org.apache.wicket.Session; import org.apache.wicket.protocol.http.WebSession; i
WebSession
。在Tomcat控制台中,我可以看到正在抛出异常:
pqlrd.is.seguridad.SesionPQLRD cannot be cast to org.apache.wicket.Session
我的扩展网络会话:
package pqlrd.is.seguridad;
import org.apache.wicket.Session;
import org.apache.wicket.protocol.http.WebSession;
import org.apache.wicket.request.Request;
import pqlrd.domain.AccesoWeb;
import pqlrd.domain.Usuario;
public final class SesionPQLRD extends WebSession {
public SesionPQLRD(Request request) {
super(request);
// TODO Auto-generated constructor stub
}
private AccesoWeb acceso;
public AccesoWeb getUsuario() {
return acceso;
}
public void setUsuario(AccesoWeb usuario) {
this.acceso = usuario;
}
public static SesionPQLRD getSesionPQLRD(){
return (SesionPQLRD) Session.get();
}
public boolean estaLogeado(){
return (acceso!=null);
}
}
仅仅因为
SessionPQLRD
is-aWebSession
(因此Session
)并不意味着WebSession
is-aSessionPQLRD
。您试图将WebSession
强制为SesionPQLRD
,但除非Wicket知道使用自定义会话而不是自己的会话,否则它将返回框架默认值
简而言之,你不能强迫一个超类像一个子类一样工作,除非它能真正履行子类的契约。考虑<代码>动物< /代码>接口,<代码>动物> <代码>实现,以及<代码>斑马> /代码>子类。动物可能不是斑马,而是长颈鹿
pqlrd.is.segurida.SesionPQLRD不能强制转换为org.apache.wicket.Session
这表示有东西试图将您的SesionPQLRD
对象之一强制转换为org.apache.wicket.Session
,而您的类不会继承或扩展该类。表面上看,这是胡说八道。根据源代码,您的类显然是WebSession
的子类,WebSession
是Session
的子类。那么是什么原因呢
我认为最可能的解释是,您的Tomcat正在使用不同的类加载器加载两个会话
/WebSession
类的副本。最可能的原因是,在同一个容器中有两个Web应用程序共享对象。如果每个webapps都有自己的wicket JAR副本,其中包含会话
和WebSession
类,那么每个webapps都有自己版本的这些类。当您的一个Web应用程序尝试使用另一个Web应用程序创建的实例时,类型将不兼容,类型转换将失败
有两种简单的方法可以避免这种情况:
- 停止在两个Web应用程序之间共享对象,或
- 从webapps的lib目录中删除JAR文件,并将它们放在共享库目录中
public class WicketApplication extends WebApplication {
//...
@Override
public Session newSession(final Request request, final Response response) {
return new SessionPQLRD(request);
}
}
我原以为这会有帮助,但事实并非如此@重写公共会话newSession(请求-请求,响应-响应){//TODO自动生成的方法存根//返回super.newSession(请求,响应);返回新的SesionPQLRD(请求);}因此,此方法返回SesionPQLRD而不是会话的代码是错误的。我已经换了,试试这个。但在我研究的示例中,由于java协方差,这是允许的。这令人困惑。公共静态会话getSesionPQLRD(){return(SesionPQLRD)Session.get();}类加载问题确实是最可能的原因。但是不要从应用程序的WEB-INF/lib中删除wicket的jar,而是将它们保留在那里(每个应用程序都有自己的wicket jar集),并从tomcat的lib(shared/lib,common/lib,取决于其版本)文件夹中删除任何wicket jar。Tomcat将保持类的版本分离(尽管JBoss在某些情况下不会)。或者只保留服务器版本(如Stephen C所述),但在这种情况下,请确保任何其他文件夹或应用程序中都没有其他版本。@tetsuo-“Tomcat将保持类的版本分离”。如果是这样,那么这个问题就不会发生了。我怀疑他在幕后实现了某种允许webapps共享实例的渠道。我的建议是1)不要共享实例,或者2)将所有相关的JAR放入共享库目录。当您将冲突的JAR放入common/lib和WEB-INF/lib时,就会出现此问题。Tomcat将其类加载器构造为一棵树,其中应用程序的jar是叶子,相互保护。但是common/lib是webapp类加载器的父类,因此在它们之间是共享的@铁锁-我知道所有这些,这并不直接重要。事实上,不同的Web应用程序中可能存在冲突的JAR。。。只要每个webapp加载的类的不同版本不在一起。只有当他们聚在一起时才有问题;e、 在webapp上时,可以获取其他版本的类的实例。事实上,当这种情况发生时,JAR可以具有相同的内容,而您仍然会遇到这个问题。是的,我所说的“冲突JAR”是指包含具有相同包/名称的类的JAR,不一定具有不同的内容。无论如何,由不同类加载器加载的类都是不同的类,不管它们是否相同。