Well, scriptlets inside a JSP page Suck. Alright, I agree!!
But sometimes it is necessary to check what are the parameters in the request or session scopes reaching your jsp page.
I found this code somewhere on the web sometime ago. One day (yeah, right) I will right a version of it using JSTL tags, but for now I allow myself to add this scriptlet in one of the pages that are included everywhere in my system. As I use Struts Tiles in my system, I do have a bottom.jsp page which is included everywhere.
So I leave the debug attribute in false state until I need to debug on page or another. At this moment, all I have to do is turn on the debug information in my page by setting the attribute to true.
Below is the scriptlet and page includes that should be added to the page where you want the debug information to be displayed.<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page import="java.util.*" %>
<%@ page import="org.apache.struts.*" %>
<%@ page import="org.apache.struts.util.*" %>
<%@ page import="org.apache.struts.action.*" %>
<%
// Print all attributes in the request object
out.println("<p><b>All Attributes in request scope:</b>");
Enumeration paramNames = request.getAttributeNames();
while (paramNames.hasMoreElements()) {
String name = (String) paramNames.nextElement();
Object values = request.getAttribute(name);
out.println("<br> " + name + ":" + values);
}
// Print all attributes in the session object
out.println("<p><b>All Attributes in session scope:</b>");
paramNames = session.getAttributeNames();
while (paramNames.hasMoreElements()) {
String name = (String) paramNames.nextElement();
Object values = session.getAttribute(name);
out.println("<br> " + name + ":" + values);
}
out.println("<p><b>Data in ActionMessages:</b>");
// Get the ActionMessages
Object o = request.getAttribute(Globals.MESSAGE_KEY);
if (o != null) {
ActionMessages ae = (ActionMessages)o;
// Get the locale and message resources bundle
Locale locale =
(Locale)session.getAttribute(Globals.LOCALE_KEY);
MessageResources messages =
(MessageResources)request.getAttribute
(Globals.MESSAGES_KEY);
// Loop thru all the labels in the ActionMessage's
for (Iterator i = ae.properties(); i.hasNext();) {
String property = (String)i.next();
out.println("<br>property " + property + ": ");
// Get all messages for this label
for (Iterator it = ae.get(property); it.hasNext();) {
ActionMessage a = (ActionMessage)it.next();
String key = a.getKey();
Object[] values = a.getValues();
out.println(" [key=" + key +
", message=" +
messages.getMessage(locale,key,values) +
"]");
}
}
}
%>
Friday, April 13, 2007
Debugging Information passed to a JSP Page
Posted by
Daniel
@
1:20 AM
0
comments
Tuesday, April 10, 2007
EJB3 QL: Using the COUNT function
If you are using EJB3 Query Language to build your application, you will probably need to use some functions other than the regular SELECT statements and logical WHERE clauses. One of the most simplest of these functions is the COUNT function.
The syntax for the COUNT function is very simple, and it receives only a parameter which is the identifier to be count, as in:
SELECT COUNT(c) FROM Customers AS c WHERE c.address.country = 'BR'This query will count all the Customers who live in Brazil.
The
COUNT function can be used with an identifier, in which case it always counts entities (as the example above demonstrates), or with path expressions but this last one can always be converted into an expression that counts entities only by managing the conditions in the WHERE clause.Below is an example on how you could write a piece of code that would count the Patients from a medical database, depending on which Clinic they are registered to:
Query query = entityManager.createQuery("SELECT COUNT (p) FROM Patients p WHERE p.clinic.idtClinic = :idtClinic");
query.setParameter("idtClinic", idtClinic);
return (Long)query.getSingleResult();
I will write about other EJB QL functions later! :)
CU!
Posted by
Daniel
@
3:32 AM
0
comments
Sunday, February 11, 2007
Find the name of your session bean in JBoss
If you are writing JEE applications, you will most likely write a Session Bean to provide your View Tier with the services it need. This Session Bean is reached by the client application through a service called JNDI.
The problem is that each Application Server uses a different JNDI provider and this makes portability very hard to achieve. I wrote the code below to allow me to access the JNDI service and find my Session Bean. Please note that this would be much better placed in the container configuration file and not in the code, as it is here.
protected static Context getInitialContext( ) throws javax.naming.NamingException {
Properties p = new Properties( );
p.put(Context.INITIAL_CONTEXT_FACTORY,"org.jnp.interfaces.NamingContextFactory");
p.put(Context.URL_PKG_PREFIXES,"org.jboss.naming:org.jnp.interfaces");
p.put(Context.PROVIDER_URL, "jnp://localhost:1099");
return new javax.naming.InitialContext(p);
}
This method will return a
java.naming.Context object which can be used for the lookup on the service, like this:
PatientServices patientServices = (PatientServices)jndiContext.lookup("PatientBean/remote");
And how can you find the name under which your bean has been published on the application server? Well, in JBoss all you need to do is access the jmx-console (default URL is http://localhost:8080/jmx-console/). On the jboss session from this page, find the JNDIView service. Click on it and a new page will display on your browser.
On this new page there will be a java.lang.String list() MBean operation, and clicking on the invoke button the names of all available JNDI names will be shown on a tree-like structure which composes the name under which your Session Bean is registered on the JNDI service.
Posted by
Daniel
@
9:22 PM
2
comments
Sunday, January 28, 2007
Using Apache as a Proxy for Tomcat Applications
I spent the day trying some configurations to make the integration between Apache HTTP Server and Tomcat.
The configuration that worked best for me basically was to setup a VirtualHost in Apache as a proxy with the same name as the application in Tomcat engine. As a resume, below tou will find some of the steps I went through and what I changed in the configuration files (I am using Apache 2.2 and Tomcat 5.5).
In Apache it is necessary to enable the mod_proxy Module and setup a NameVirtualHost. The httpd.conf (found in %APACHE_HOME%/conf) configuration file should be changed as below.
#Uncomment or add the lines below into the general session of your httpd.conf file.
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
# Add the Virtual Host for your application at the end of the file
NameVirtualHost *
<VirtualHost *>
ServerAdmin serveradmin@domain.com
DocumentRoot "C:/java/Tomcat5.5/webapps/"
ServerName myapplication.domain.com
ServerAlias *.myapplication.domain.com
ProxyPass /foo-app http://localhost:8080/foo-app
ProxyPassReverse /foo-app http://localhost:8080/foo-app
</VirtualHost>
After setting this file in your apache server, restart it and proceed to configuring the Tomcat Server, by editing the server.xml file (found in %CATALINA_HOME%/conf). Simply add the lines below at the end of the file, but inside the <server> tag.
<Service name="Tomcat-Apache">
<Engine name="Apache" defaultHost="myapplication.domain.com" debug="0">
<Host name="myapplication.domain.com" debug="0"
appBase="c:/java/Tomcat5.5/webapps/foo-app"
unpackWARs="true" autoDeploy="true">
<Context path="/foo-app" docBase="c:/java/Tomcat5.5/webapps/foo-app" debug="1" reloadable="true"/>
</Host>
</Engine>
</Service>
Now, open your browser and type the URL http://myapplication.domain.com/foo-app and you should be redirected to your application after passing by Apache and Tomcat.
Tomcat RMI Unmarshalling Exception
This is one of those posts that shows how frustrating sometimes the developer job can be! :)
I had a WAR component that was delivered successfully and worked fine in Jetty 6.0 rc2, but the same WAR file would not work under Tomcat 5.5. This application uses some session beans that are available in my JBoss Server. When I tried to execute the lookup() command in my client application running in Tomcat I had an exception thrown:
java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is: java.net.MalformedURLException: no protocol:
Then I asked: Why? Why does it work in Jetty like a charm? Reading ahead at the message of the exception I noticed the MalformedURL message included this: "5.5/temp/0-fisio-web-1.0-SNAPSHOT/WEB-INF/classes/" which made me realize that this was just part of the full URL where my Tomcat Server was running. Searching through the net I found this post, which led me to this other post (and there is also this other post on this subject).
For my surprise this is a known bug since JDK 1.2, marked as WON´T FIX by SUN! Is it unbelievable or not??
There is a workaround suggested by Sun that says that one should usefile.toURI().toURL()
instead of file.toURL()
but many times, this is not in our hands, as is my case because Tomcat is taking care of this for me, so unless me (or some other generous soul) change and test (and do a backward compatibility test which seems to be what is frightening SUN into not changing this behavior) this way of implementing the RMI communication, the best thing to avoid this problem is to install all your applications in a path that does not include white spaces or illegal characters.
Saturday, January 27, 2007
Tomcat Hot Deployment in Windows
The post about hot deploying an application to Tomcat using maven brought me a problem: the struts.jar was always left in the WEB-INF/lib of the exploded directory in the server.
This is a know issue with Tomcat working under Windows and I found an article which I quoted here below with the solution for this problem:
There were other people having this kind of problem. Please note that this has nothing to do with using Maven, but with the combination of Tomcat 5.5 + Windows and Hot Deploys! :)If you try to hot-deploy a WAR file to Tomcat on Windows, you often encounter file locking issues. Windows won’t let Tomcat undeploy the old app because files are locked by the OS. Here is a fix:
Edit
%CATALINA_HOME%\conf\context.xml. Find the root<context>and add these two attributes:
<context antijarlocking="true" antiresourcelocking="true">Now you can copy updated WAR files to your deploy directory and Tomcat will remove the old app and hot-deploy your new app. I’m using this on Tomcat 5.5.11 without any trouble.
Posted by
Daniel
@
11:58 PM
1 comments
Using Maven to deploy application to Apache Tomcat Server
For those who are not familiar with Maven, it is (as stated in the project site) a "software project management and comprehension tool. Based on the concept of a project object model (POM), Maven can manage a project's build, reporting and documentation from a central piece of information."
Based on the concept of "convention over configuration" developers may use Maven to compile, build, test, deploy, generate reports and use a whole bunch of other features to manage their software development project. In another oppportunity I will post an article about Maven, for now I will write about my most immediate need: deploy a war file to a tomcat server.As I am using maven to manage my project from test to build, all I need is to configure the Cargo plugin. Cargo is able to download, install and start Tomcat, but this is not our focus right now, so I will assume you have Tomcat installed and running with no problems.
Using Maven´s Cargo plugin it is possible to install an application into Tomcat in two ways:
- Use the Tomcat Manager application, which is deployed by default with Tomcat 5.x and is nothing more than a web interface to manage your server. It has the ability to install a WAR into the server from a remote location.
- Copy the WAR File of your application directly into the File System where Tomcat is expecting applications to be, normally %CATALINE_HOME%/webapps.
Using the Tomcat Manager
Now we will deploy an application to Tomcat while it is still running. This is called Hot Deploying.
You should add some comands to your pom file, and they should look like the excerpt of code below. Actually it should be positioned between the tags:
<build>
<plugins>
...
</plugins>
</build>
<plugin>You should need to change only the values in the
<groupid>org.codehaus.cargo</groupid>
<artifactid>cargo-maven2-plugin</artifactid>
<configuration>
<!-- Container configuration -->
<container>
<containerid>tomcat5x</containerid>
<type>remote</type>
</container>
<!-- Configuration to use with the Container -->
<configuration>
<type>runtime</type>
<properties>
<cargo.tomcat.manager.url>http://localhost:8080/manager</cargo.tomcat.manager.url>
<cargo.remote.username>admin</cargo.remote.username>
<cargo.remote.password>admin</cargo.remote.password>
</properties>
</configuration>
<!-- Deployer configuration -->
<deployer>
<type>remote</type>
<deployables>
<deployable>
<groupid>com.company</groupid>
<artifactid>web-component</artifactid>
<type>war</type>
</deployable>
</deployables>
</deployer>
</configuration>
</plugin>
Having this in your pom file, you need to issue the following command:
mvn cargo:deployIf you already have the application running in tomcat it is necessary that you undeploy it before deploying. So, issue the command below and you should be ok:
mvn cargo:undeploy
You also have the option to execute a command that will do an undeploy before attempting to deploy:
mvn cargo:deployer-redeployThat should be enough to get the application running in Tomcat, deploying from a remote server.
I would just like to add that the configuration for the tags
Thursday, December 7, 2006
JBoss World 2006 - Presentations

From November 20th to November 22nd 2006 I attended the JBoss World Conference in Berlim.
The conference was dedicated to developers, with speaks indicating the level of knowledge expected from the audience on the subject. There were also hands on sessions for testing new technologies provided by JBoss.
The presentations are now available for download from the conference web site.
Monday Speaks
Tuesday Speaks
Wednesday Speaks
Enjoy it! ;)
Posted by
Daniel
@
5:26 PM
0
comments
Labels: Conference, Java, JEE