Site Network: Personal | Professional | Photography

Technical Blog

This blog will contain content related to Java, Seam, Security, my sites and projects, as well as other technical subjects I am interested in.

Comments and questions are welcome!

Archive for the ‘Java’ Category

Updates to the ATG RSS Feed Module

Sunday, May 4th, 2008

Thanks to Doug Henderson sending me some code updates I have released a new version of the RSS Feed Droplet (first mentioned in this post) which supports configurable character encodings. This can be very useful if you have "interesting" characters in the content you are publishing.

I have also rolled the code into my ATG Open Source Module Pack, so that I can maintain everything in one location.

Also: please note that you cannot reformat the JSP code, or introduce any spaces as it will break the feed. I've made note of that in the module's Readme as well.

Enjoy!

Adding the “Upload Image” Button in the ACC

Monday, April 14th, 2008

If you have your own content repository items defined, and you'd like the ACC to provide the Upload Image functionality for your internal binary properties, Russell Moore has figured it out:

In /atg/devtools/ create a local version of admins.xml:

 
<repository-admins>
  <default-admin id="YourRepository">
    <display-name>Your Content</display-name>
    <repository-name>YourRepository</repository-name>
    <create-bean-displays>
      <bean-display type="media" class="atg.ui.repository.MediaInternalBinaryEditor">
<property name="internalBinaryExcludedTableProperties" value="path, version, mimeType,data, length,url"/>
      </bean-display>
    </create-bean-displays>
    <standard-bean-displays>
      <bean-display type="media" class="atg.ui.repository.MediaInternalBinaryEditor">
<property name="internalBinaryExcludedTableProperties" value="version, mimeType, data, length, url"/>
<property name="internalBinaryTableReadOnlyProperties" value="path"/>
      </bean-display>
    </standard-bean-displays>
  </default-admin>
</repository-admins>
 

Thanks Russell!

RichFaces Modal Panels, s:graphicImage, and IE6

Sunday, April 13th, 2008

If, like me, you are using the Seam s:graphicImage tag to serve an image from within a RichFaces modal panel, you may have run into an issue where in IE6 the image does not get displayed, and you get the dreaded red X of failure. It works fine in all other browsers, including IE7, and works outside of the modal panel, but not from within the modal panel.

It's not a problem with the image data (saving the image from another browser and serving it up directly works fine. I suspect it's a delay issue with the rendering of the modal panel. For me, it was serving up the red X about 90% of the time under IE6.

The "fix" is to stop using the s:graphicImage tag within the modal, and use a Servlet to stream out the image data instead. It's pretty easy.

One gotcha I had was that I already had a Servlet handling video output, and I couldn't find an example of how to configure two separate paths into the seam web:context-filter Servlet Filter (which allows access to Seam components, like the entity manager to load up the video/image items). A helpful response on the forums gave me this solution:

 
<web:context-filter regex-url-pattern="/image/*|/video/*" />
 

Also, if you're struggling to figure out what a library's new feature isn't working for you, no matter how many permutations of the documented usage you try, check the versions in the manifest files in the library's jars. Maybe, like me, you upgraded the jars in one project, but forgot to upgrade them in this one....

Seam EntityHome Design Pattern

Friday, April 11th, 2008

I've been using Seam for over a year. At some point the "Home" object was introduced to the documentation (Chapter 11). Reading the documentation didn't convince me of the point. Being an ATG guy at heart, I still prefer using "form handlers" for managing my important entities. So I haven't bothered.

However, just recently I ran into a little problem with LazyInitializationExceptions. I'm sure you've run into them yourself. Basically, when Hibernate loads an entity for you, it's loaded by an entity manager which is available to manage that object within a specific scope. This effects persisting changes. Also, if you have properties on that entity that have a fetchType.LAZY, those properties can only be lazily loaded while the same entity manager is available. If it's not, you get LazyInitializationExceptions. No fun.

So in Seam, what I usually do to avoid this, is to create a long running conversation, and load the entity within the context of that conversation. Then, as long as you're still in that long running conversation, you can lazily load all the properties you want.

Normally this is fine. However, in my latest project the application will send e-mails to users when they get a new inter-user message. If they click on the link in the e-mail, they come to the site, but without the existing long running conversation query parameter. Their user component is session scoped, so they're still logged in, but the user object is now outside of it's conversation, and if you attempt to access lazily loaded properties, for instance the user's messages they are trying to see based on the e-mail, blammo: exception central. Unhappy users.

I was pointed to this page: Using EntityHome for entities in long-running contexts

Which showed me how to use the EntityHome to avoid the whole problem. Basically it works like this:

When the user logs in, set the user entity's id into a session scoped component. Don't bother with long running conversations (at least not for the user). The User Home component's Factory method creates a user component using the session scoped user id, anytime the user component is referenced. This component entity is loaded within the context of the current conversation (if it hasn't already been loaded). So, presto-magic, no lazy loading issues.

It let me fix the issue with about 20 lines of code, and little trouble. It's working perfectly so far.

Getting the Real IP Address from a Proxied Request in ATG

Tuesday, April 8th, 2008

Many things can obscure the real IP address of the end user when they visit your site: a load balancer in front of your ATG cluster, Akamai, the user's ISP or office network, and more. This makes correlating logging events, or using the ATG session IP validation security option, and more, very difficult. In light of that challange I've added a new mini-module to my Open Source ATG Modules called the ProxyIPFixer. It uses a simple ATG pipeline Servlet to examine the X-FORWARDED-FOR request header, and if it finds one, parse through the IP addresses to find the originating IP address of the user, and puts that value into the ATG Request object's remoteAddr property.

This allows downstream pipeline servlets, code, and pages to see the real user's IP address.

The caveat is that the header can be faked, and that some ISPs/companies, such as AOL, do not set the true end point of the user, and you can only see back to their outgoing proxy server. In AOL's case in particular, they can also route subsequent requests by the same AOL user through different AOL proxy points, which will make it appear that someone is hijacking a session (if you're using the ATG session security mechanism). So be aware of the limitations. However it can be very useful.

For those who don't want to download the whole module package, I have attached the Java source and the ATG properties file to this post.

Enjoy! (and as always feel free to contact me with questions, issues, improvements, etc...)

ProxyIPFixerServlet Java Source

ProxyIPFixer ATG Properties File