At line 1 added 232 lines. |
!Steps for running Appfuse 1.8.2 under Oracle Application Server Enterprise Edition 10g Release 2 (10.1.2.0.2) |
|
''Contributed by Stefano Bertini (stefano.bertini at plangroup.it) '' |
|
To successfully deploy an application developed with Appfuse 1.8.2 under the Oracle AS 10g Rel.2 there are quite a number of steps to follow as Oracle AS has a lot of different (and odd) behaviours from Tomcat. |
|
We need to modify the build.xml and some classes... \\And we need to write some new ones... |
|
Here we go ! |
---- |
|
!Oracle doesn't like <dispatcher> tags in web.xml |
|
We need to edit the __properties.xml__ file to add a property:\\ |
{{{<property name="DeployOnOrion" value="true"/>}}} |
|
Then, we modify the __build.xml__, in the __package-web__ target so that it doesn't remove the comments from the <dispatcher> tags: |
{{{ |
<if> |
<and> <!-- Modified Part start --> |
<not> |
<isset property="DeployOnOrion"/> |
</not> |
<or> |
<isset property="tomcat5"/> |
<isset property="tomcat5.5"/> |
</or> |
</and> <!-- Modified Part end--> |
<then> |
<replaceregexp flags="g" |
file="${webapp.target}/WEB-INF/web.xml" |
match='<!--dispatcher>' |
replace='<dispatcher>'/> |
<replaceregexp flags="g" |
file="${webapp.target}/WEB-INF/web.xml" |
match='</dispatcher-->' |
replace='</dispatcher>'/> |
</then> |
</if> |
}}} |
---- |
|
!The contextConfigLocation parameter |
|
In the __/metadata/web/web-settings.xml__ file there is the __contextConfigLocation__ parameter that looks like this: |
|
{{{ |
<context-param> |
<param-name>contextConfigLocation</param-name> |
<param-value> |
classpath*:META-INF/applicationContext-*.xml |
/WEB-INF/applicationContext-*.xml |
</param-value> |
</context-param> |
}}} |
|
The problem with Oracle AS is that the wildcards syntax won't work. \\ |
And, moreover, the __classpath*:META-INF/__ search doesn't work because Oracle returns a bad URL format while browsing inside jar files. |
|
So we have to do two different things: the first step is to modify the __build.xml__ file so that it copies the __applicationContext-hibernate.xml__ and __applicationContext-service.xml__ files in the WEB-INF directory.\\ |
We do this by adding the following statements at the __end__ of the __copy-resources__ target: |
|
{{{ |
<copy overwrite="true" tofile="${build.dir}/${webapp.name}/WEB-INF/applicationContext-${dao.type}.xml"> |
<fileset dir="src/dao" includes="**/*-${dao.type}.xml"/> |
<filterset refid="variables.to.replace"/> |
</copy> |
<copy tofile="${build.dir}/${webapp.name}/WEB-INF/applicationContext-service.xml"> |
<fileset dir="src/service" includes="**/*-service.xml"/> |
</copy> |
|
}}} |
Then, we modify the __contextConfigLocation__ parameter in this way: |
|
{{{ |
<context-param> |
<param-name>contextConfigLocation</param-name> |
<param-value> |
/WEB-INF/applicationContext-hibernate.xml |
/WEB-INF/applicationContext-service.xml |
/WEB-INF/applicationContext-resources.xml |
/WEB-INF/applicationContext-security.xml |
</param-value> |
</context-param> |
}}} |
---- |
|
!Oracle calls the UserCounterListener twice |
|
The UserCounterListener is added twice when the application is deployed because it is defined both in the __web.xml__ file and in the __/WEB-INF/<appname>.tld__ file. |
|
This causes the application to add every user twice in the user list. |
|
Infact, the __webdoclet__ target, in the __jsptaglip__ subtask, re-adds every listener in the taglibrary definition. |
|
You need to modify the __webdoclet__ target in this way: |
|
{{{ |
<target name="webdoclet" depends="compile-web" unless="webdoclet.unnecessary" |
description="Generate web and Struts descriptors"> |
<taskdef name="webdoclet" classname="xdoclet.modules.web.WebDocletTask"> |
<classpath> |
<path refid="xdoclet.classpath"/> |
<path refid="web.compile.classpath"/> |
</classpath> |
</taskdef> |
<webdoclet destdir="${webapp.target}/WEB-INF" |
force="${xdoclet.force}" |
mergedir="metadata/web" |
excludedtags="@version,@author" |
verbose="true"> |
<fileset dir="src/web"/> |
<fileset dir="${build.dir}/web/gen"/> |
<deploymentdescriptor validateXML="true" |
servletspec="2.3" sessiontimeout="10" |
destdir="${webapp.target}/WEB-INF" distributable="false" |
displayname="${ant.project.name}"> |
<configParam name="httpPort" value="${http.port}"/> |
<configParam name="httpsPort" value="${https.port}"/> |
<configParam name="daoType" value="${dao.type}"/> |
</deploymentdescriptor> |
<strutsconfigxml validateXML="true" version="1.2"/> |
<strutsvalidationxml/> |
</webdoclet> |
<webdoclet destdir="${webapp.target}/WEB-INF" |
force="${xdoclet.force}" |
mergedir="metadata/web" |
excludedtags="@version,@author" |
verbose="true"> |
<fileset dir="src/web" excludes="**/listener/**"/> |
<fileset dir="${build.dir}/web/gen"/> |
<jsptaglib validateXML="true" |
description="Custom tag library for this application" |
shortName="${webapp.name}" filename="${webapp.name}.tld"/> |
</webdoclet> |
</target> |
}}} |
---- |
|
!When invalidating a session, Oracle doesn't call any HttpSessionAttributeListener |
|
So the UserCounterListener is never called to remove unlogged users from the User List. |
|
To fix this behaviour I created an OrionSessionListener class that gets called when a session is invalidated and that removes every variable in the session itself, forcing every HttpSessionAttributeListener to be called from the server. |
|
Here is the class (create it in your /src/.../webapp/listener directory): |
|
[{Java2HtmlPlugin |
|
package <your_package_path>.webapp.listener; |
|
import java.util.Enumeration; |
|
import javax.servlet.http.HttpSession; |
import javax.servlet.http.HttpSessionEvent; |
import javax.servlet.http.HttpSessionListener; |
|
/** |
* This listener is invoked by Orion when a session is invalidated. |
* It removes every variable bound to that session forcing Orion |
* to call every HttpSessionAttributeListener. |
* |
* @author <a href="mailto:stefano.bertini at plangroup.it">Stefano Bertini</a> |
* |
* @web.listener |
*/ |
|
public class OrionSessionListener implements HttpSessionListener { |
|
public void sessionCreated(HttpSessionEvent event) { |
} |
|
public void sessionDestroyed(HttpSessionEvent event) { |
HttpSession session = event.getSession(); |
Enumeration names = session.getAttributeNames() ; |
while (names.hasMoreElements()) { |
session.removeAttribute(names.nextElement().toString()); |
} |
} |
} |
|
}] |
|
---- |
|
!Null Object reference in class ConstantsTag |
|
In the __header.jsp__ page, you get a NullPointerException when executing the line |
{{{ |
<appfuse:constants scope="request"/> |
}}} |
|
This is caused by the __release()__ method of the __ConstantsTag__ |
{{{ public void release() { |
super.release(); |
clazz = null; |
scope = Constants.class.getName(); |
} |
}}} |
in the line |
{{{ |
clazz = null; |
}}} |
|
Just comment it out and everything works again. |
|
I tried to use the __class__ parameter of the __constants__ tag, but i got another error and i had no more time to investigate further. :-) |
---- |
|
!Oracle doesn't execute filters if the url doesn't contain an extension |
|
The problem happens with the __j_security_check__ filter. |
|
If you deploy the application, you will find out that it is impossible to login. This happens because the filter that should be triggered by the __j_security_check__ url never gets called. |
|
I found out that the problem is because the url doesn't have an extension, so I changed the __j_security_check__ into __j_security_check.login__ and everything works again. |
|
You have to change this in the following files:\\ |
{{ |
/properties.xml \\ |
/metadata/web/filter-mappings.xml \\ |
/src/web/your_app_path/webapp/action/LoginServlet.java \\ |
/web/WEB-INF/applicationContext-security.xml \\ |
}} |
---- |
|
!Strange behaviours with Orache Web Cache |
|
Using Oracle Web Cache i noticed some strange behaviours. |
OWC keeps caching pages even if the header's meta tags say not to cache anything. |
|
I had to disable the OWC to have the application work correctly. |