can not be cast to javax.servlet.Filter等问题的解决方法

问题1:can not be cast to javax.servlet.Filter

  一位从测试转开发的同事首次更新代码,并编译在本地启动web项目时,报如下错误:

Exception starting filter encodingFilter
java.lang.ClassCastException:com.gaochao.platform.web.context.filter.ContextFilter2 can not be cast to javax.servlet.Filter

  根据这一错误,在网上查找资料一般认为是tomcat/lib下的jar包跟webapps目录里的应用程序中WEB-INF/lib目录下有相同的包,存在版本上的冲突,解决方案就是为依赖加上一个标签<scope>

<dependency>
				<groupId>javax.servlet</groupId>
				<artifactId>servlet-api</artifactId>
				<version>${servlet-version}</version>
				<scope>provided</scope>
			</dependency>
			<dependency>
				<groupId>javax.servlet</groupId>
				<artifactId>jsp-api</artifactId>
				<version>${jsp-version}</version>
				<scope>provided</scope>
			</dependency>

  顺着这个思路,我查找了关于<scope>标签的用法,如下:

* compile,缺省值,适用于所有阶段,会随着项目一起发布。 

* provided,类似compile,期望JDK、容器或使用者会提供这个依赖。如servlet.jar。 

* runtime,只在运行时使用,如JDBC驱动,适用运行和测试阶段。 

 * test,只在测试时使用,用于编译和运行测试代码。不会随项目发布。 

 * system,类似provided,需要显式提供包含依赖的jarMaven不会在Repository中查找它。

  但是,我们的代码里确认是有这个标签,且配置也没有错误,确实是provided。在已经打好的war包里查询,路径\oa-deploy\target\oa-deploy-0.0.1-SNAPSHOT\WEB-INF\lib中也确认没有servletjar包,也符合期望JDK、容器或使用者会提供这个依赖的解释。可见问题还不是出在这个地方,进一步搜索是不是还有其他解决思路。经过进一步查询资料,发现在http://jira.codehaus.org/有一个编号MOJO-1076的bug,其bug描述与我们的错误基本一致,另外一名用户为其提供的解决思路也是在dependency中加入<scope>属性,提报bug的用户最后加备注如下:

My issue was introduced by gwt-user.jar that contains javax.servlet package.

Setting it as provided solved the issue.


  我的问题是引入gwt-user.jar,而该包中包含servlet,将该包(也可能是该包中依赖servlet)的scope改为provided即ok了。目前我们的项目里引入百数十个包,里面是不是包含servlet查找起来将是较大的工程。另外,除了这名同事以外,其他同事的tomcat启动是不是问题的。所以以上的描述只是解决类似问题的一个思路,但并不是我们问题产生的原因。

  再进一步查找资料,还有前辈提供的一种方案,用以解决不同依赖中包含版本冲突的servlet的问题。在其描述中,类似本题目中的问题是由tomcat6-maven-plugin和paoding-rose两个工程的maven依赖引起,这两个依赖都依赖了servlet-api包,而且两个包的scope都设置成了运行时可用,其中tomcat6-maven-plugin为runtime,paoding-rose为compile该方案提供的方法是使用<exclusions>元素实现。

  如下:

<dependency>  
        <groupId>net.paoding</groupId>  
        <artifactId>paoding-rose</artifactId>  
        <version>1.0-SNAPSHOT</version>  
            <exclusions>  
            <exclusion>  
                <groupId>javax.servlet</groupId>  
                <artifactId>servlet-api</artifactId>  
            </exclusion>  
        </exclusions>  
    </dependency>      
    <dependency>  
        <groupId>javax.servlet</groupId>  
        <artifactId>servlet-api</artifactId>  
        <version>2.3</version>  
        <scope>provided</scope>  
    </dependency>  
  </dependencies>  
		</dependencies>

  以上是三种通过互联网查询的方案,未解决问题;又通过卸载jdktomcatmaven并重装等等。最终发现采用jetty可以启动项目。最后的解决方案,即为:重装机器,重新部署环境。

问题2:MYSQL里的ISNULL、IFNULL、NULLIF

  在对工作流历史任务进行查询时,历史任务的审批人存储的用户表中的用户code,需要left join 用户表将对应的用户名称。如下:

<!-- 查询集合审批历史  -->
	<select id="queryByProcessExecutionIdForPage" resultMap="TaskResultMap"  parameterType="String">
		SELECT 
			task.processExecutionId,
			process.name as processDefineName,
			task.activityName,
			user.userName as createUserCode,
			task.status,
			task.description,
			task.finishTime,
			task.createTime
		FROM T_BPM_PROCESS_TASK task
		LEFT JOIN T_BPM_PROCESS_EXECUTION execution ON task.processExecutionId = execution.id
		LEFT JOIN t_bpm_process_define process ON execution.processDefineId = process.id
		LEFT JOIN T_SYS_USER user ON task.createUserCode = user.userCode
		WHERE task.processExecutionId = #{id}
		ORDER BY task.createTime DESC, task.finishTime DESC
	</select>

  而在抢办,也就是jbpm4_taskassignee为空,而jbpm4_participation中的参与类型为Candidate时,即形成所有参与人共同参与,均为候选审批人,一人审批结束,则该任务办理通过。由于assignee为空,无法像普通任务那样直接关联查询,所以使用ISNULL函数,如下:

ISNULL(user.userName,"抢办") as createUserCode

  在执行该语句时,发现mysql并不支持ISNULL函数,sql中具有相似功能或相似写法的函数还有:IFNULL以及NULLIF。在链接所指的文章中有对以上三种函数的详细介绍,这里仅作简介。

IFNULL(expr1,expr2)

果expr1不是NULLIFNULL()返回expr1,否则它返回expr2IFNULL()返回一个数字或字符串值,取决于它被使用的上下文环境。

NULLIF(expr1,expr2)

  如果expr1= expr2  成立,那么返回值为NULL,否则返回值为 expr1。

  通过以上介绍,对于NULLIF为何如此命名感觉很奇怪,似乎与参数null与否无关。MYSQL中我们就可以使用IFNULL来代替IFNULL实现我们想要的功能,修改后如下:

ISNULL(user.userName,"抢办") as createUserCode

  修改后经测试,可以达到我们想要的结果。

问题3:MySQL关于txt格式字段的优化

  在新建工作中,会查询出所有流程定义的list,随着新的流程表单不断上线,打开所有流程列表的动作越来越耗时。在查询语句中使用的select * from字样,在流程定义所有的属性中包括了text格式的jpdlXml属性,该属性中存储了该流程的xml定义的文本。因为该查询只需列出流程的id、分类、名称,其他属性是不必须的,将jpdlXmlselect属性列表中移除,这也是sql优化的一个基础性的常识,不需要的字段就不要写进select。将jpdlXml移除后,耗时较长的问题并没有明显改善。我们继续向下阅读,发现还有另外一处,在查询出所有流程定义list后,会对该list进行筛选,之前的博文对这一处的逻辑进行过基于责任链模式的优化。其筛选逻辑中有这么一条——流程新发布或表单新保存后会更新流程/表单的某个字段,根据该字段决定新建工作中该流程是否可见。在此处代码里,会对所有流程定义list进行遍历,然后拿到流程对应的form,而查询该form时,也是使用的select *,而在form的定义表中,有两个字段是text类型的,分别为htmltemplate。我们再将这两个非必须字段移除,耗时问题明显改善,用户几无等待就可以看到所有流程的列表。

  这一问题给我们的提示就是,查询动作尽量不用*

问题4:tools.jar not found

  为解决问题2,我也尝试在我的笔记本里(已经有一个台式机和只有显示器连接云服务器的VDI盒子,因经常开会,新申请的笔记本电脑,用于远程连接台式机,一直没有安装开发环境),拉取新的代码,按照开发环境配置新的环境,包括jdk、tomcat等,在部署的时候,报出如下错误:

Fatal error compiling: tools.jar not found: C:\Program Files\Java\jre6\..\lib\tools.jar.

  网上一般对该问题的定义是eclipse中的jre配置jdk中的jre,而正确的配置应该是jdk。查找后发现并没有配置错。最后查看环境变量配置,Win+R打开cmd,输入 java -version,并没有输出版本信息,发现环境变量配置有误。

  修复完毕后,再次deploy没有再发现该问题。

本文出自 “南湖矿工技术空间” 博客,请务必保留此出处http://jncumter.blog.51cto.com/812546/1619492

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。