天空是蓝色的

做好软件为中国 #gcc -c helloworld.c -o helloworld.o //编译目标文件 #gcc helloworld.o -o helloworld //编译成可执行exe #helloworld //运行exe
数据加载中……
[转贴]详解 Tomcat: The value for the useBean class attribute is invalid 问题

详解 Tomcat: The value for the useBean class attribute is invalid 问题

使用Tomcat 常见 "The value for the useBean class attribute is invalid" 错误。该错误是指 JSP 中给定的 useBean 标签的 class 属性的值无效(不是 Bean 的属性值)。

在说明这个问题前,先看看有关的 Tomcat 源代码(org.apache.jasper.compiler.Generator):

  if (beanName == null{
      
try {
          Class bean 
= ctxt.getClassLoader().loadClass(klass);
          
int modifiers = bean.getModifiers();
          
if (!Modifier.isPublic(modifiers) ||
               Modifier.isInterface(modifiers) 
||
              Modifier.isAbstract (modifiers)) 
{
              
throw new Exception("Invalid bean class modifier");
          }

          
// Check that there is a 0 arg constructor 
          bean.getConstructor(new Class[] {});
          generateNew 
= true
      }
 catch (Exception e) {
          
// Cannot instantiate the specified class
          if (ctxt.getOptions().getErrorOnUseBeanInvalidClassAttribute()) 
              err.jspError(n, 
"jsp.error.invalid.bean ", klass);
          }

      }

  }


可见错误可能的原因包括:

1. 在编译 JSP 时(不是运行时),指定的 Bean 类没找到
2. Bean 虽然找到了,但是它不是 public 的,或者找到的 class 文件是 interface 或抽象类
3. Bean 类中没有 public 的默认构建函数

第二点很明显,不用多解释,最经常发生的情况是 Bean 类忘了声明为 public 。

第三点中需要注意的是,如果你的 Bean 类没有提供任何构造函数,将自动生成一个默认构建函数,这没有问题。但是,如果你有构造函数,则不会自动生成该默认构造函数。经常被忽略的问题是写了默认构造函数却不是 public 的。

第一点看起来简单,不过却最令人头痛,尤其是在开发环境里。这里需要注意的是,"在编译 JSP 时",意味着引用 Bean 的 JSP 是新的,或者刚刚更新过,或者 TOMCAT_HOME/work 中的编译结果被清除了。此时,Tomcat 将自动(重新)编译该 JSP,此时如果发现 Bean 没找到,就会报这个错。情况因为 JSP 或者 Bean 类正在开发而变得复杂,一一列举所有情况没有意义,这里我举一些典型例子,借此应该可以举一反三:
 
如果 JSP 编译结果存在,且 JSP 没有更新,Tomcat 不会重新编译 JSP,同时默认情况也不会自动重新加载更新过的 Bean 类(参考 http://jakarta.apache.org/tomcat/tomcat-5.5-doc/config/context.html 中的 reloadable)。所以,你会发现此时即使删除了 Bean 类都没有问题,当然,更新 Bean 类也不会有什么用。如果在 JSP 编译产生之后,我们重起了服务器,由于 JSP 文件编译的结果存在,所以,可以仍然访问 JSP 页面,而不必重新编译。可是如果访问前,删掉了 Bean 类,就会报过 ClassNotFoundException 而不是上述错误。关键在于 JSP 是否经过编译,没有编译则没有找到类报告题目中的编译错误 ,编译过则是 ClassNotFoundException 运行时实例化错误。

 
还有一个更为特殊的例子。如果 Web 应用在启动时, WEB-INF/classes 目录不存在,则在启动应用后,新建 classes 目录,动态添加新的类进去是没有用的,会报告同样的错误。原因是此时的 Tomcat 不会去检查该目录,也就不会找到你需要的类。对 WEB-INF/lib 目录也是同样。这一点可以参考下面的源代码(org.apache.catalina.loader.WebappLoader):

  // Setting up the class repository (/WEB-INF/classes), if it exists

  String classesPath 
= "/WEB-INF/classes";
  DirContext classes 
= null;

  
try {
      Object object 
= resources.lookup(classesPath);
      
if (object instanceof DirContext) {
          classes 
= (DirContext) object;
      }

  }
 catch(NamingException e) 
      
// Silent catch: it's valid that no /WEB-INF/classes collection
      
// exists
  }


  
if (classes != null{

      File classRepository 
= null;

      String absoluteClassesPath 
=
          servletContext.getRealPath(classesPath);

      
if (absoluteClassesPath != null{

          classRepository 
= new File(absoluteClassesPath);

      }
 else {

          classRepository 
= new File(workDir, classesPath);
          classRepository.mkdirs();
          copyDir(classes, classRepository);

      }


      
if(log.isDebugEnabled())
          log.debug(sm.getString(
"webappLoader.classDeploy", classesPath,
                       classRepository.getAbsolutePath())); 


      
// Adding the repository to the class loader
      classLoader.addRepository(classesPath + "/", classRepository);
      loaderRepositories.add(classesPath 
+ "/" ); 

  }


尽管这个问题的复杂场景可能不一而足,不过解决它的办法却很简单:停止服务器,确认你的 JSP 和 Bean 正确部署,清理掉 TOMCAT_HOME/work 中的内容,重起服务器。 此外,配置动态类加载对开发而言是个不错的选择。
 
本文基于 Tomcat 5.5.9 版本。

作者blog:http://spaces.msn.com/members/thomaszhou/

posted on 2005-12-05 16:01 bluesky 阅读(21475) 评论(10)  编辑  收藏 所属分类: 工作总结

评论

# re: [转贴]详解 Tomcat: The value for the useBean class attribute is invalid 问题  2006-12-01 11:21 利剑

呵呵 不错
  回复  更多评论    

# re: [转贴]详解 Tomcat: The value for the useBean class attribute is invalid 问题  2007-11-17 16:48 Mr Ma

我遇到一个情况就是,在我的虚拟目录中(相对于虚拟根目录),也就是说:如果我的Host为:
<Host name="128.128.19.49" appBase="D:/StoreWeb"
unpackWARs="true" autoDeploy="true"
xmlValidation="false" xmlNamespaceAware="false">

<Context path="" docBase="D:/StoreWeb" debug="0" reloadable="true"/>
<Context path="/score/" docBase="D:/StoreWeb" debug="0" reloadable="true"/>

</Host>但是在score中的jsp页面无法访问在StoreWeb中的类文件。我把jSP页面放在StoreWeb中一切正常。请问这是什么原因?
谢谢
  回复  更多评论    

# re: [转贴]详解 Tomcat: The value for the useBean class attribute is invalid 问题  2007-11-17 16:49 Mr Ma

Tomcat的版本为:6.0
谢谢!!!
^_^
  回复  更多评论    

# re: [转贴]详解 Tomcat: The value for the useBean class attribute is invalid 问题  2007-11-18 19:57 bluesky

肯定的啊,score只是web应用的 context 真实目录还是StoreWeb啊
  回复  更多评论    

# re: [转贴]详解 Tomcat: The value for the useBean class attribute is invalid 问题  2007-11-23 20:35 Mr Ma

谢谢!
^_^
  回复  更多评论    

# re: [转贴]详解 Tomcat: The value for the useBean class attribute is invalid 问题  2007-12-26 17:23 桌面

我现在上传自己的网站就出现了这样的问题。也不知道怎么才好。在我本机上是可以进行的,可是传上远程服务器后,就出现了以上的问题。说JavaBean值无效。
  回复  更多评论    

# re: [转贴]详解 Tomcat: The value for the useBean class attribute is invalid 问题 [未登录] 2009-12-15 13:24 小吴

  回复  更多评论    

# re: [转贴]详解 Tomcat: The value for the useBean class attribute is invalid 问题  2012-01-14 05:32 new car finance

我只是爱你的网站,它充满了新鲜和相关的文章,有一个非常漂亮的眼睛吸引人的设计!有些职位,真正帮助我在我的工作,所以表示感谢!
  回复  更多评论    

# re: [转贴]详解 Tomcat: The value for the useBean class attribute is invalid 问题  2012-01-14 05:33 new ford

伟大的东西,从你的人。伊夫读你的东西,和“你太真棒。我爱什么youve来到这里,爱什么你说你说的方式。你让娱乐和你们仍设法保持它的智能。我不能等待读取。这的确是一个伟大的博客
  回复  更多评论    

# re: [转贴]详解 Tomcat: The value for the useBean class attribute is invalid 问题  2012-04-03 04:42 payday loans

我现在上传自己的网站就出现了这样的问题。也不知道怎么才好。在我本机上是可以进行的,可是传上远程服务器后,就出现了以上的问题。说JavaBean值无效。
  回复  更多评论    

只有注册用户登录后才能发表评论。


网站导航: