org.hibernate.QueryException: ClassNotFoundException: org.hibernate.hql.ast.HqlToken異常
這是使用Hibernate 3.0以後版本均會出現的異常;
exception is java.lang.NoSuchMethodError: javax.persistence.UniqueConstraint.name()Ljava/lang/String,如果使用Hibernate 3.5,在實體中使用了唯一約束會出現這個異常,因爲在Hibernate 3.5使用了最新的Jpa 2.0,WebLogic中還是Jpa 1.0, UniqueConstraint.name在Jpa 2.0纔有。
exception is java.lang.NoSuchMethodError: org.apache.commons.lang.ArrayUtils.isNotEmpty,我在項目使用了比較新版本的commons-lang-2.5.jar在webLogic 10.3會報這個異常;
在網search一下,解決ClassNotFoundException異常最常用的辦法就是將出現異常類所在的jar包入到weblogic環境中的classpath最前面加載,將相應的antlr-2.7.6.jar、hibernate-jpa-2.0-api-1.0.0.Final.jar、commons-lang-2.5.jar copy到${WL_HOME/}server/lib/或其他目錄,可以修改${DOMAIN_HOME}/bin/startWebLogic.sh,在CLASSPATH之前加上下面一句:
- PRE_CLASSPATH=”${WL_HOME/}server/lib/antlr-2.7.6.jar:${WL_HOME/}server/lib/hibernate-jpa-2.0-api-1.0.0.Final.jar:${WL_HOME/}server/lib/commons-lang-2.5.jar”
並將修改爲CLASSPATH="${SAVE_CLASSPATH}"
- CLASSPATH="${PRE_CLASSPATH}:${SAVE_CLASSPATH}"
或者修改${DOMAIN_HOME}/bin/setDomainEnv.sh,在setDomainEnv.sh前面加入一句:
- EXT_PRE_CLASSPATH=”${WL_HOME/}server/lib/antlr-2.7.6.jar:${WL_HOME/}server/lib/hibernate-jpa-2.0-api-1.0.0.Final.jar:${WL_HOME/}server/lib/commons-lang-2.5.jar”
- export EXT_PRE_CLASSPATH
在我項目實踐中發現加入antlr-2.7.6.jar、hibernate-jpa-2.0-api-1.0.0.Final.jar、commons-lang-2.5.jar後,前兩個起作用,異常消除,commons-lang-2.5.jar沒有作用,exception is java.lang.NoSuchMethodError: org.apache.commons.lang.ArrayUtils.isNotEmpty異常依舊,當時沒有解決方法,只好在項目中去掉ArrayUtils.isNotEmpty,杯具!!!
後來在網上找到一種更有效解決ClassNotFoundException的,可以解決所有WebLogic中的ClassNotFoundException。改解決辦法是將web項目包含進ear包中。將web項目打包成war文件,在war文件相同目錄下建立META-INF目錄,目錄建立application.xml、weblogic-application.xml兩個文件,文件內容很簡單,開發過weblogic EJB應用的應該很清楚。
application.xml
- <?xml version="1.0" encoding="UTF-8"?>
- <!DOCTYPE application PUBLIC '-//Sun Microsystems, Inc.//DTD J2EE Application 1.3//EN' 'http://java.sun.com/dtd/application_1_3.dtd'>
- <application>
- <display-name>cckzzx</display-name>
- <description>cckzzx</description>
- <module>
- <web>
- <web-uri>cckzzx.war</web-uri>
- <context-root>cckzzx</context-root>
- </web>
- </module>
- </application>
weblogic-application.xml
- <?xml version="1.0"?>
- <weblogic-application xmlns="http://www.bea.com/ns/weblogic/90"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
- <application-param>
- <param-name>webapp.encoding.default</param-name>
- <param-value>UTF-8</param-value>
- </application-param>
- <prefer-application-packages>
- <package-name>org.apache.commons.*</package-name>
- <package-name>antlr.*</package-name>
- <package-name>javax.persistence.*</package-name>
- </prefer-application-packages>
- </weblogic-application>
<prefer-application-packages>
表示在weblogic中優先使用當前應用中的jar包
最後將war文件和META-INF目錄打包成ear包、部署。在這裏我參考網上資料寫了一個ant腳本build.xml對項目進行ear打包
build.xml
- <?xml version="1.0"?>
- <project name="cckzzx" default="ear" basedir=".">
- <property name="project.name" value="cckzzx" />
- <property name="app.dir" value="${basedir}" />
- <property name="src.java.dir" value="${app.dir}/src/main/java" />
- <property name="src.resources.dir" value="${app.dir}/src/main/resources" />
- <property name="weblogic.home" value="/opt/Oracle/Middleware/wlserver_10.3" />
- <property name="wls.username" value="weblogic" />
- <property name="wls.password" value="weblogic123" />
- <property name="wls.hostname" value="localhost" />
- <property name="wls.port" value="7001" />
- <property name="wls.server.name" value="AdminServer" />
- <property name="build.dir" value="${app.dir}/build" />
- <property name="build.classes.dir" value="${build.dir}/classes" />
- <property name="build.tmp.dir" value="${build.dir}/tmp" />
- <path id="build.classpath" description="編譯時的classpath路徑">
- <fileset dir="${basedir}/WebRoot/WEB-INF/lib">
- <include name="*.jar" />
- </fileset>
- <fileset dir="${weblogic.home}/server/lib">
- <include name="weblogic.jar" />
- </fileset>
- <pathelement location="${build.classes.dir}" />
- </path>
- <taskdef name="wldeploy" classname="weblogic.ant.taskdefs.management.WLDeploy" classpathref="build.classpath" />
- <target name="clean" description="刪除編譯目錄">
- <delete dir="${build.dir}" />
- </target>
- <target name="prepare" depends="clean" description="創建編譯目錄">
- <mkdir dir="${build.dir}" />
- <mkdir dir="${build.classes.dir}" />
- <mkdir dir="${build.tmp.dir}" />
- </target>
- <target name="compile" depends="prepare" description="編譯">
- <javac srcdir="${src.java.dir}" destdir="${build.classes.dir}" compiler="org.eclipse.jdt.core.JDTCompilerAdapter" encoding="UTF-8" source="1.6" target="1.6" debug="on" deprecation="on" optimize="off" includes="**">
- <classpath refid="build.classpath" />
- </javac>
- </target>
- <target name="ear" depends="compile" description="打包EAR包">
- <jar jarfile="${build.dir}/${project.name}.jar">
- <fileset dir="${build.classes.dir}">
- <include name="com/**/*.class" />
- <include name="**/*.xml" />
- </fileset>
- </jar>
- <mkdir dir="${build.tmp.dir}/WebRoot" />
- <copy todir="${build.tmp.dir}/WebRoot">
- <fileset dir="${app.dir}/WebRoot">
- <exclude name="WEB-INF/classes/**" />
- </fileset>
- </copy>
- <copy todir="${build.tmp.dir}/WebRoot/WEB-INF/lib">
- <fileset file="${build.dir}/${project.name}.jar" />
- </copy>
- <mkdir dir="${build.tmp.dir}/WebRoot/WEB-INF/classes" />
- <copy todir="${build.tmp.dir}/WebRoot/WEB-INF/classes">
- <fileset dir="${src.resources.dir}" />
- </copy>
- <war warfile="${build.dir}/${project.name}.war" webxml="${build.tmp.dir}/WebRoot/WEB-INF/web.xml">
- <fileset dir="${build.tmp.dir}/WebRoot">
- <exclude name="WEB-INF/web.xml" />
- </fileset>
- </war>
- <ear earfile="${build.dir}/${project.name}.ear" appxml="${app.dir}/src/weblogic/META-INF/application.xml">
- <fileset dir="${app.dir}/src/weblogic">
- <include name="META-INF/weblogic-application.xml" />
- </fileset>
- <fileset dir="${build.dir}">
- <include name="${project.name}.war" />
- </fileset>
- </ear>
- <delete file="${build.dir}/${project.name}.jar" />
- <delete file="${build.dir}/${project.name}.war" />
- <delete dir="${build.classes.dir}" />
- <delete dir="${build.tmp.dir}" />
- </target>
- <target name="deploy" depends="ear,undeploy" description="佈署EAR服務">
- <wldeploy action="deploy" name="${project.name}" source="${build.dir}/${project.name}.ear" targets="${wls.server.name}" user="${wls.username}" password="${wls.password}" adminurl="t3://${wls.hostname}:${wls.port}" debug="true" verbose="true" failοnerrοr="true" />
- <echo message="come here......" /> <echo message="deploy success......." />
- </target>
- <target name="undeploy" description="刪除EAR服務">
- <wldeploy action="undeploy" name="${project.name}" targets="${wls.server.name}" user="${wls.username}" password="${wls.password}" adminurl="t3://${wls.hostname}:${wls.port}" debug="false" verbose="false" failοnerrοr="false" />
- </target>
- </project>
如果項目中使用了泛型,使用該腳本如果拋出無法確定 T 的類型參數;對於上限爲 T ,java.lang.Object 的類型變量 T,不存在唯一最大實例異常,在eclipse中可以編譯運行,爲什麼用ant就不行了呢?
解決方法是在classpath加入${eclipse_home}/plugins/org.eclipse.jdt.core_3.6.1.v_A68_R36x.jar和從org.eclipse.jdt.core_3.6.1.v_A68_R36x.jar解決出來的jdtCompilerAdapter.jar兩個包。