标签:
case1)用户输入了正确的username 和 pwd:验证器阀会调用后续的阀;case2)用户输入错误:验证器阀会返回,不会调用后续的阀;
private void createUserDatabase() {// SimpleRealm.createUserDatabase() 创建了users 列表;
User user1 = new User("ken", "blackcomb");
user1.addRole("manager");
user1.addRole("programmer");
User user2 = new User("cindy", "bamboo");
user2.addRole("programmer");
users.add(user1);
users.add(user2);
}public Principal authenticate (String username, String credentials); // generally used public Principal authenticate (String username, byte[] credentials); public Principal authenticate (String username, String digest, String nonce, String nc, String cnonce, String qop, String realm, String md5a2); public Principal authenticate (X509Certificate cents[]);;3)在catalina中, Realm接口的基本实现形式是org.apache.catalina.realm.RealmBase类;其UML类图如下:

public class GenericPrincipal implements Principal { //org.apache.catalina.realm.GenericPrincipal,代表一个用户(封装了username,password,role,realm)
public GenericPrincipal(Realm realm, String name, String password) {
this(realm, name, password, null);
}
public GenericPrincipal(Realm realm, String name, String password,
List roles) {
super();
this.realm = realm;
this.name = name;
this.password = password;
if (roles != null) {
this.roles = new String[roles.size()];
this.roles = (String[]) roles.toArray(this.roles);
if (this.roles.length > 0)
Arrays.sort(this.roles);
}
}
protected String name = null;
public String getName() {
return (this.name);
}
protected String password = null;
public String getPassword() {
return (this.password);
}
protected Realm realm = null;
public Realm getRealm() {
return (this.realm);
}
protected String roles[] = new String[0];
public String[] getRoles() {
return (this.roles);
}
public boolean hasRole(String role) { // highlight line.
if (role == null)
return (false);
return (Arrays.binarySearch(roles, role) >= 0);
}
public String toString() {
StringBuffer sb = new StringBuffer("GenericPrincipal[");
sb.append(this.name);
sb.append("]");
return (sb.toString());
}
}step1)如果web.xml 文件包含 login-config 元素的配置,则tomcat会创建一个 LoginConfig对象,并设置其相应属性;(干货——tomcat创建一个 LoginConfig对象的条件)step2)验证器阀会调用 LoginConfig.getRealmName() 获取领域对象名,并将领域对象名发送到 browser,显示在登录对话框中;case2.1)如果getReamlName()方法的返回值是null,则会将服务器名和相应端口发送给 browser;
public final class LoginConfig { //org.apache.catalina.deploy.LoginConfig
public LoginConfig() {
super();
}
public LoginConfig(String authMethod, String realmName,
String loginPage, String errorPage) {
super();
setAuthMethod(authMethod);
setRealmName(realmName);
setLoginPage(loginPage);
setErrorPage(errorPage);
}
// ------------------------------------------------------------- Properties
private String authMethod = null;
public String getAuthMethod() {
return (this.authMethod);
}
public void setAuthMethod(String authMethod) {
this.authMethod = authMethod;
}
private String errorPage = null;
public String getErrorPage() {
return (this.errorPage);
}
public void setErrorPage(String errorPage) {
this.errorPage = RequestUtil.URLDecode(errorPage);
}
private String loginPage = null;
public String getLoginPage() {
return (this.loginPage);
}
public void setLoginPage(String loginPage) {
this.loginPage = RequestUtil.URLDecode(loginPage);
}
private String realmName = null;
public String getRealmName() {
return (this.realmName);
}
public void setRealmName(String realmName) {
this.realmName = realmName;
}
public String toString() {
StringBuffer sb = new StringBuffer("LoginConfig[");
sb.append("authMethod=");
sb.append(authMethod);
if (realmName != null) {
sb.append(", realmName=");
sb.append(realmName);
}
if (loginPage != null) {
sb.append(", loginPage=");
sb.append(loginPage);
}
if (errorPage != null) {
sb.append(", errorPage=");
sb.append(errorPage);
}
sb.append("]");
return (sb.toString());
}
}
A1)BasicAuthenticator:用来支持基本的身份验证;A2)FormAuthenticator:提供了基于表单的身份验证;A3)DigestAuthenticator:提供了基于信息摘要的身份验证;A4)SSLAuthenticator:用于对SSL 进行身份验证;A5)当tomcat 用户没有指定验证方法名时,NonLoginAuthenticator类用于对来访者的身份进行验证。NonLoginAuthenticator类实现的验证器只会检查安全限制,而不会涉及用户身份的验证;
A1)验证器的重要工作:是对用户进行身份验证;(干货——验证器的重要工作是对用户进行身份验证)A2)当看到 AuthenticatorBase.invoke() 方法调用 authenticate() 抽象方法时:后者的实现依赖于子类;(而authenticate()方法会使用基本身份验证来验证用户的身份信息);
public class BasicAuthenticator
extends AuthenticatorBase { <span style="font-family: SimSun;">//org.apache.catalina.authenticator.BasicAuthenticator,这里仅以BasicAuthenticator 为例po出 source code.</span>
// ----------------------------------------------------- Instance Variables
protected static final Base64 base64Helper = new Base64();
protected static final String info =
"org.apache.catalina.authenticator.BasicAuthenticator/1.0";
public String getInfo() {
return (this.info);
}
public boolean authenticate(HttpRequest request,
HttpResponse response,
LoginConfig config)
throws IOException {
// Have we already authenticated someone?
Principal principal =
((HttpServletRequest) request.getRequest()).getUserPrincipal();
String ssoId = (String) request.getNote(Constants.REQ_SSOID_NOTE);
if (principal != null) {
if (debug >= 1)
log("Already authenticated '" + principal.getName() + "'");
// Associate the session with any existing SSO session
if (ssoId != null)
associate(ssoId, getSession(request, true));
return (true);
}
// Is there an SSO session against which we can try to reauthenticate?
if (ssoId != null) {
if (debug >= 1)
log("SSO Id " + ssoId + " set; attempting reauthentication");
if (reauthenticateFromSSO(ssoId, request))
return true;
}
// Validate any credentials already included with this request
HttpServletRequest hreq =
(HttpServletRequest) request.getRequest();
HttpServletResponse hres =
(HttpServletResponse) response.getResponse();
String authorization = request.getAuthorization();
String username = parseUsername(authorization);
String password = parsePassword(authorization);
principal = context.getRealm().authenticate(username, password);
if (principal != null) {
register(request, response, principal, Constants.BASIC_METHOD,
username, password);
return (true);
}
// Send an "unauthorized" response and an appropriate challenge
String realmName = config.getRealmName();
if (realmName == null)
realmName = hreq.getServerName() + ":" + hreq.getServerPort();
hres.setHeader("WWW-Authenticate",
"Basic realm=\"" + realmName + "\"");
hres.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
// hres.flushBuffer();
return (false);
}
// ------------------------------------------------------ Protected Methods
protected String parseUsername(String authorization) {
if (authorization == null)
return (null);
if (!authorization.toLowerCase().startsWith("basic "))
return (null);
authorization = authorization.substring(6).trim();
// Decode and parse the authorization credentials
String unencoded =
new String(base64Helper.decode(authorization.getBytes()));
int colon = unencoded.indexOf(':');
if (colon < 0)
return (null);
String username = unencoded.substring(0, colon);
// String password = unencoded.substring(colon + 1).trim();
return (username);
}
protected String parsePassword(String authorization) {
if (authorization == null)
return (null);
if (!authorization.startsWith("Basic "))
return (null);
authorization = authorization.substring(6).trim();
// Decode and parse the authorization credentials
String unencoded =
new String(base64Helper.decode(authorization.getBytes()));
int colon = unencoded.indexOf(':');
if (colon < 0)
return (null);
// String username = unencoded.substring(0, colon).trim();
String password = unencoded.substring(colon + 1);
return (password);
}
}
A1)若没有设置 auth-method元素:则 LoginConfig 对象 的 atuh-method属性的值默认为 NONE,使用 NonLoginAuthenticator 进行安全验证;A2)由于使用的验证器类是在运行时才确定的,故该类是动态载入的;A3)StandardContext容器使用 org.apahce.catalina.startup.ContextConfig类来对 StandardContext 实例的属性进行设置:这些设置包括 实例化一个验证器类,并将该实例与Context实例相关联;
// Identify the class name of the Valve we should configure
String authenticatorName = "org.apache.catalina.authenticator.BasicAuthenticator";
// Instantiate and install an Authenticator of the requested class
Valve authenticator = null;
try {
Class authenticatorClass = Class.forName(authenticatorName);
authenticator = (Valve) authenticatorClass.newInstance();
((StandardContext) context).addValve(authenticator);
System.out.println("Added authenticator valve to Context");
}
catch (Throwable t) {
}step1)先检查在相关联的Context容器是否有安全限制,若没有直接返回,而不会安装验证器;// Does this Context require an Authenticator? SecurityConstraint constraints[] = context.findConstraints(); if ((constraints == null) || (constraints.length == 0)) return;
step2)若当前Context容器有一个或多个安全限制,authenticatorConfig() 方法会检查该Context实例是否有 LoginConfig对象。若没有,则它会创建一个新的 LoginConfig实例:LoginConfig loginConfig = context.getLoginConfig(); if (loginConfig == null) { loginConfig = new LoginConfig("NONE", null, null, null); context.setLoginConfig(loginConfig); }
step3)检查管道中的基础阀或附加阀是否是验证器。因为一个Context实例只能有一个验证器,所以当发现某个阀是验证器后,直接返回:// Has an authenticator been configured already? Pipeline pipeline = ((StandardContext) context).getPipeline(); if (pipeline != null) { Valve basic = pipeline.getBasic(); if ((basic != null) && (basic instanceof Authenticator)) return; Valve valves[] = pipeline.getValves(); for (int i = 0; i < valves.length; i++) { if (valves[i] instanceof Authenticator) return; } } else { // no Pipeline, cannot install authenticator valve return; }
step4)查找当前Context实例是否有与之关联的领域对象(Realm)。如果没有领域对象,就不需要安装验证器了,因为用户是无法通过身份验证的;// Has a Realm been configured for us to authenticate against? if (context.getRealm() == null) { return; }
step5)若找到了领域对象,则会动态载入 BasicAuthenticator类,创建该类的一个实例,并将其作为阀添加到 StandardContext实例中;// Identify the class name of the Valve we should configure String authenticatorName = "org.apache.catalina.authenticator.BasicAuthenticator"; // Instantiate and install an Authenticator of the requested class Valve authenticator = null; try { Class authenticatorClass = Class.forName(authenticatorName); authenticator = (Valve) authenticatorClass.newInstance(); ((StandardContext) context).addValve(authenticator); System.out.println("Added authenticator valve to Context"); } catch (Throwable t) { } }
public class SimpleRealm implements Realm {
public SimpleRealm() {
createUserDatabase(); //highlight line.
}
private void createUserDatabase() { // there are 2 roles.
User user1 = new User("ken", "blackcomb");
user1.addRole("manager"); // manager role.
user1.addRole("programmer"); // programmer role.
User user2 = new User("cindy", "bamboo");
user2.addRole("programmer");
users.add(user1);
users.add(user2);
// private ArrayList users = new ArrayList();
}
}public Principal authenticate(String username, String credentials) {
System.out.println("SimpleRealm.authenticate()");
if (username==null || credentials==null)
return null;
User user = getUser(username, credentials);
if (user==null)
return null;
return new GenericPrincipal(this, user.username, user.password, user.getRoles()); // highlight line.
}public class GenericPrincipal implements Principal { // 该类封装了用户的一些信息,如username,pass,role,realm等info;
public GenericPrincipal(Realm realm, String name, String password) {
this(realm, name, password, null);
}
public GenericPrincipal(Realm realm, String name, String password,
List roles) {
super();
this.realm = realm;
this.name = name;
this.password = password;
if (roles != null) {
this.roles = new String[roles.size()];
this.roles = (String[]) roles.toArray(this.roles);
if (this.roles.length > 0)
Arrays.sort(this.roles);
}
}
protected String name = null;
public String getName() {
return (this.name);
}
protected String password = null;
public String getPassword() {
return (this.password);
}
protected Realm realm = null;
public Realm getRealm() {
return (this.realm);
}
protected String roles[] = new String[0];
public String[] getRoles() {
return (this.roles);
}
public boolean hasRole(String role) {
if (role == null)
return (false);
return (Arrays.binarySearch(roles, role) >= 0);
}
public String toString() {
StringBuffer sb = new StringBuffer("GenericPrincipal[");
sb.append(this.name);
sb.append("]");
return (sb.toString());
}
}// tomcat-users.xml 的源码如下: <?xml version='1.0' encoding='utf-8'?> <tomcat-users> <role rolename="tomcat"/> <role rolename="role1"/> <role rolename="manager"/> <role rolename="admin"/> <user username="tomcat" password="tomcat" roles="tomcat"/> <user username="role1" password="tomcat" roles="role1"/> <user username="both" password="tomcat" roles="tomcat,role1"/> <user username="admin" password="admin" roles="admin,manager"/> </tomcat-users>
// 以下代码是 Bootstrap2.java 中的源码
Realm realm = new SimpleUserDatabaseRealm();
String filedir = new File(System.getProperty("user.dir")).getParent() + File.separator +
"conf" + File.separator + "tomcat-users.xml";
((SimpleUserDatabaseRealm) realm).createDatabase(filedir); // highlight line.public void createDatabase(String path) { // SimpleUserDatabaseRealm.createDatabase().
database = new MemoryUserDatabase(name);
((MemoryUserDatabase) database).setPathname(path);
try {
database.open(); // highlight line.
}
catch (Exception e) {
}
}public void open() throws Exception { // org.apache.catalina.users.MemoryUserDatabase.open().
synchronized (groups) {
synchronized (users) {
// Erase any previous groups and users
users.clear();
groups.clear();
roles.clear();
// Construct a reader for the XML input file (if it exists)
File file = new File(pathname);
if (!file.isAbsolute()) {
file = new File(System.getProperty("catalina.base"),
pathname);
}
if (!file.exists()) {
return;
}
FileInputStream fis = new FileInputStream(file);
// Construct a digester to read the XML input file
Digester digester = new Digester();
digester.addFactoryCreate
("tomcat-users/group",
new MemoryGroupCreationFactory(this));
digester.addFactoryCreate
("tomcat-users/role",
new MemoryRoleCreationFactory(this));
digester.addFactoryCreate
("tomcat-users/user",
new MemoryUserCreationFactory(this));
// Parse the XML input file to load this database
try {
digester.parse(fis);
fis.close();
} catch (Exception e) {
try {
fis.close();
} catch (Throwable t) {
;
}
throw e;
} } } }public final class Bootstrap1 {
public static void main(String[] args) {
//invoke: http://localhost:8080/Modern or http://localhost:8080/Primitive
System.setProperty("catalina.base", System.getProperty("user.dir"));
System.out.println("user.dir = " + System.getProperty("user.dir"));
Connector connector = new HttpConnector();
Wrapper wrapper1 = new SimpleWrapper();
wrapper1.setName("Primitive");
wrapper1.setServletClass("servlet.PrimitiveServlet");
Wrapper wrapper2 = new SimpleWrapper();
wrapper2.setName("Modern");
wrapper2.setServletClass("servlet.ModernServlet");
Context context = new StandardContext(); // highlight line.
// StandardContext's start method adds a default mapper
context.setPath("/myApp");
context.setDocBase("myApp");
LifecycleListener listener = new SimpleContextConfig();// highlight line.
((Lifecycle) context).addLifecycleListener(listener);
context.addChild(wrapper1);
context.addChild(wrapper2);
// for simplicity, we don't add a valve, but you can add
// valves to context or wrapper just as you did in Chapter 6
Loader loader = new WebappLoader();
context.setLoader(loader);
// context.addServletMapping(pattern, name);
context.addServletMapping("/Primitive", "Primitive");
context.addServletMapping("/Modern", "Modern");
// add ContextConfig. This listener is important because it configures
// StandardContext (sets configured to true), otherwise StandardContext
// won't start
// add constraint
SecurityCollection securityCollection = new SecurityCollection();// highlight line.
securityCollection.addPattern("/");// highlight line.
securityCollection.addMethod("GET");// highlight line.
SecurityConstraint constraint = new SecurityConstraint();// highlight line.
constraint.addCollection(securityCollection);// highlight line.
constraint.addAuthRole("manager");// highlight line.
LoginConfig loginConfig = new LoginConfig();// highlight line.
loginConfig.setRealmName("Simple Realm");
// add realm
Realm realm = new SimpleRealm();// highlight line.
context.setRealm(realm);// highlight line.
context.addConstraint(constraint);// highlight line.
context.setLoginConfig(loginConfig);// highlight line.
connector.setContainer(context);
// add a Manager
Manager manager = new StandardManager();
context.setManager(manager);
try {
connector.initialize();
((Lifecycle) connector).start();
((Lifecycle) context).start();
// make the application wait until we press a key.
System.in.read();
((Lifecycle) context).stop();
}
catch (Exception e) {
e.printStackTrace();
}
}
}A1)创建StandardContext对象:设置其path属性和 documentBase属性,并添加一个 SimpleContextConfig 类的监听器。该监听器会把一个 BasicAuthenticator 对象安装到 StandardContext 对象中;A2)创建SecurityColleciton对象:并调用其addPattern和 addMethod方法,addPattern方法指定某个url 要遵循哪个安全限制, 而addMethod方法会指定该安全限制要使用哪种验证方法;在addMethod()方法中设置为GET, 则使用GET 方法提交的http 请求会遵循安全限制;A3)创建 SecurityManager对象:并将其添加到 安全限制集合中,且还设置了哪种角色可以访问这些受限资源。A4)创建LoginConfig对象 和 SimpleRealm对象;A5)将领域对象,安全限制对象,登录配置对象 与 StandardContext实例相关联;A6)接着,启动Context实例。。。。。。。

<pre name="code" class="java">E:\bench-cluster\cloud-data-preprocess\HowTomcatWorks\src>java -cp .;lib/servlet.jar;lib/catalina_4_1_24.jar;lib/catalina-5.5.4.jar;lib/naming-common
jar;lib/commons-collections.jar;lib/naming-resources.jar;lib/;lib/catalina.jar;E:\bench-cluster\cloud-data-preprocess\HowTomcatWorks\webroot com.tomc
t.chapter10.startup.Bootstrap1
HttpConnector Opening server socket on all host IP addresses
HttpConnector[8080] Starting background thread
WebappLoader[/myApp]: Deploying class repositories to work directory E:\bench-cluster\cloud-data-preprocess\HowTomcatWorks\src\work\_\_\myApp
Starting Wrapper Primitive
Starting Wrapper Modern
Added authenticator valve to Context
StandardManager[/myApp]: Seeding random number generator class java.security.SecureRandom
StandardManager[/myApp]: Seeding of random number generator has been completed
StandardManager[/myApp]: IOException while loading persisted sessions: java.io.EOFException
// 这是从文件中加载 session对象到内存,由于没有相关文件,所以加载失败,抛出异常,但这不会影响我们访问servlet,大家不要惊慌;
java.io.EOFException
at java.io.ObjectInputStream$PeekInputStream.readFully(Unknown Source)
at java.io.ObjectInputStream$BlockDataInputStream.readShort(Unknown Source)
at java.io.ObjectInputStream.readStreamHeader(Unknown Source)
at java.io.ObjectInputStream.<init>(Unknown Source)
at org.apache.catalina.util.CustomObjectInputStream.<init>(CustomObjectInputStream.java:103)
at org.apache.catalina.session.StandardManager.load(StandardManager.java:408)
at org.apache.catalina.session.StandardManager.start(StandardManager.java:655)
at org.apache.catalina.core.StandardContext.start(StandardContext.java:3570)
at com.tomcat.chapter10.startup.Bootstrap1.main(Bootstrap1.java:84)
StandardManager[/myApp]: Exception loading sessions from persistent storage
java.io.EOFException
at java.io.ObjectInputStream$PeekInputStream.readFully(Unknown Source)
at java.io.ObjectInputStream$BlockDataInputStream.readShort(Unknown Source)
at java.io.ObjectInputStream.readStreamHeader(Unknown Source)
at java.io.ObjectInputStream.<init>(Unknown Source)
at org.apache.catalina.util.CustomObjectInputStream.<init>(CustomObjectInputStream.java:103)
at org.apache.catalina.session.StandardManager.load(StandardManager.java:408)
at org.apache.catalina.session.StandardManager.start(StandardManager.java:655)
at org.apache.catalina.core.StandardContext.start(StandardContext.java:3570)
at com.tomcat.chapter10.startup.Bootstrap1.main(Bootstrap1.java:84)
SimpleRealm.authenticate()
SimpleRealm.authenticate()
ModernServlet -- init
SimpleRealm.authenticate()
SimpleRealm.authenticate()
SimpleRealm.authenticate()
SimpleRealm.authenticate()
SimpleRealm.authenticate()
SimpleRealm.authenticate()
init
SimpleRealm.authenticate()
from service
from servicepublic final class Bootstrap2 {
public static void main(String[] args) {
//invoke: http://localhost:8080/Modern or http://localhost:8080/Primitive
System.setProperty("catalina.base", System.getProperty("user.dir"));
Connector connector = new HttpConnector();
Wrapper wrapper1 = new SimpleWrapper();
wrapper1.setName("Primitive");
wrapper1.setServletClass("servlet.PrimitiveServlet");
Wrapper wrapper2 = new SimpleWrapper();
wrapper2.setName("Modern");
wrapper2.setServletClass("servlet.ModernServlet");
Context context = new StandardContext(); // highlight line.
// StandardContext's start method adds a default mapper
context.setPath("/myApp");
context.setDocBase("myApp");
LifecycleListener listener = new SimpleContextConfig();// highlight line.
((Lifecycle) context).addLifecycleListener(listener);
context.addChild(wrapper1);
context.addChild(wrapper2);
// for simplicity, we don't add a valve, but you can add
// valves to context or wrapper just as you did in Chapter 6
Loader loader = new WebappLoader();
context.setLoader(loader);
// context.addServletMapping(pattern, name);
context.addServletMapping("/Primitive", "Primitive");
context.addServletMapping("/Modern", "Modern");
// add ContextConfig. This listener is important because it configures
// StandardContext (sets configured to true), otherwise StandardContext
// won't start
// add constraint
SecurityCollection securityCollection = new SecurityCollection();// highlight line.
securityCollection.addPattern("/");// highlight line.
securityCollection.addMethod("GET");// highlight line.
SecurityConstraint constraint = new SecurityConstraint();// highlight line.
constraint.addCollection(securityCollection);// highlight line.
constraint.addAuthRole("manager");// highlight line.
constraint.addAuthRole("tomcat");// highlight line.注意这里的角色,必要要和tomcat-users.xml 中的users 列表相对应,如果要设置某个用户有权限访问servlet资源,则需要添加其所属的角色;
LoginConfig loginConfig = new LoginConfig();// highlight line.
loginConfig.setRealmName("Simple User Database Realm");
// add realm
Realm realm = new SimpleUserDatabaseRealm();// highlight line.
String filedir = new File(System.getProperty("user.dir")).getParent() + File.separator +
"conf" + File.separator + "tomcat-users.xml";
((SimpleUserDatabaseRealm) realm).createDatabase(filedir); // highlight line.设置tomcat-users.xml 的文件路径 以载入其内容到内存进行身份验证工作;
context.setRealm(realm);// highlight line.
context.addConstraint(constraint);// highlight line.
context.setLoginConfig(loginConfig);// highlight line.
connector.setContainer(context);
try {
connector.initialize();
((Lifecycle) connector).start();
((Lifecycle) context).start();
// make the application wait until we press a key.
System.in.read();
((Lifecycle) context).stop();
}
catch (Exception e) {
e.printStackTrace();
}
}}// tomcat-users.xml 的源码如下: <?xml version='1.0' encoding='utf-8'?> <tomcat-users> <role rolename="tomcat"/> <role rolename="role1"/> <role rolename="manager"/> <role rolename="admin"/> <user username="tomcat" password="tomcat" roles="tomcat"/> <user username="role1" password="tomcat" roles="role1"/> <user username="both" password="tomcat" roles="tomcat,role1"/> <user username="admin" password="admin" roles="admin,manager"/> </tomcat-users>
E:\bench-cluster\cloud-data-preprocess\HowTomcatWorks\src>java -cp .;lib/servlet.jar;lib/catalina_4_1_24.jar;lib/catalina-5.5.4.jar;lib/naming-common.
jar;lib/commons-collections.jar;lib/naming-resources.jar;lib/;lib/catalina.jar;lib\commons-digester.jar;lib\commons-logging.jar;E:\bench-cluster\cloud
-data-preprocess\HowTomcatWorks\webroot com/tomcat/chapter10/startup/Bootstrap2
HttpConnector Opening server socket on all host IP addresses
HttpConnector[8080] Starting background thread
WebappLoader[/myApp]: Deploying class repositories to work directory E:\bench-cluster\cloud-data-preprocess\HowTomcatWorks\src\work\_\_\myApp
Starting Wrapper Primitive
Starting Wrapper Modern
Added authenticator valve to Context
StandardManager[/myApp]: Seeding random number generator class java.security.SecureRandom
StandardManager[/myApp]: Seeding of random number generator has been completed
StandardManager[/myApp]: IOException while loading persisted sessions: java.io.EOFException // 这是从文件中加载 session对象到内存,由于没有相关文件,所以加载失败,抛出异常,但这不会影响我们访问servlet,大家不要惊慌;
java.io.EOFException
at java.io.ObjectInputStream$PeekInputStream.readFully(Unknown Source)
at java.io.ObjectInputStream$BlockDataInputStream.readShort(Unknown Source)
at java.io.ObjectInputStream.readStreamHeader(Unknown Source)
at java.io.ObjectInputStream.<init>(Unknown Source)
at org.apache.catalina.util.CustomObjectInputStream.<init>(CustomObjectInputStream.java:103)
at org.apache.catalina.session.StandardManager.load(StandardManager.java:408)
at org.apache.catalina.session.StandardManager.start(StandardManager.java:655)
at org.apache.catalina.core.StandardContext.start(StandardContext.java:3570)
at com.tomcat.chapter10.startup.Bootstrap2.main(Bootstrap2.java:84)
StandardManager[/myApp]: Exception loading sessions from persistent storage
java.io.EOFException
at java.io.ObjectInputStream$PeekInputStream.readFully(Unknown Source)
at java.io.ObjectInputStream$BlockDataInputStream.readShort(Unknown Source)
at java.io.ObjectInputStream.readStreamHeader(Unknown Source)
at java.io.ObjectInputStream.<init>(Unknown Source)
at org.apache.catalina.util.CustomObjectInputStream.<init>(CustomObjectInputStream.java:103)
at org.apache.catalina.session.StandardManager.load(StandardManager.java:408)
at org.apache.catalina.session.StandardManager.start(StandardManager.java:655)
at org.apache.catalina.core.StandardContext.start(StandardContext.java:3570)
at com.tomcat.chapter10.startup.Bootstrap2.main(Bootstrap2.java:84)
ModernServlet -- init
标签:
原文地址:http://blog.csdn.net/pacosonswjtu/article/details/51253679