<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;DEIHSHk6cSp7ImA9WhRVGUU.&quot;"><id>tag:blogger.com,1999:blog-754001278635115086</id><updated>2012-01-19T07:22:19.719-08:00</updated><category term="jboss" /><category term="maven" /><category term="tomcat" /><category term="ejb 3" /><category term="hudson" /><category term="java" /><category term="erlang" /><category term="struts 2" /><category term="ide" /><category term="session manager" /><category term="filtering" /><title>IT in the FOG</title><subtitle type="html">Programming techniques,software methodologies, application frameworks and more.</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://fogit.blogspot.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://fogit.blogspot.com/" /><author><name>Pavel Rodionov</name><uri>http://www.blogger.com/profile/12191929867434155859</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>3</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/fogit" /><feedburner:info uri="fogit" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry gd:etag="W/&quot;CkIHQXk6eCp7ImA9WxJUFkU.&quot;"><id>tag:blogger.com,1999:blog-754001278635115086.post-711276541798968523</id><published>2009-07-15T10:25:00.000-07:00</published><updated>2009-07-15T10:55:30.710-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-07-15T10:55:30.710-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="java" /><category scheme="http://www.blogger.com/atom/ns#" term="filtering" /><category scheme="http://www.blogger.com/atom/ns#" term="hudson" /><category scheme="http://www.blogger.com/atom/ns#" term="maven" /><title>Web resources filtering with Maven 2</title><content type="html">&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_CTGlw5KhVhk/Sl4SCf7mcjI/AAAAAAAAACU/jDoIzxbqSEE/s1600-h/filter.jpg"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer; width: 200px; height: 150px;" src="http://4.bp.blogspot.com/_CTGlw5KhVhk/Sl4SCf7mcjI/AAAAAAAAACU/jDoIzxbqSEE/s200/filter.jpg" alt="" id="BLOGGER_PHOTO_ID_5358740440757989938" border="0" /&gt;&lt;/a&gt;Here is a simple solution for filtering web resources in your maven-based web application. Assume, that you have some jsp files and you want to add some maven or user-defined property. For example I want to include current build number as a root virtual directory for some javascript included (it's one of the strategies for versioning web resources and useful as a caching strategy).&lt;br /&gt;&lt;br /&gt;Here is excerpt from jsp file (src/main/webapp/pages/index.jsp):&lt;br /&gt;&lt;br /&gt;&lt;script src="%3Cs:url%20value=" yui="" event="" js=""&gt;" type="text/javascript"&gt;&lt;/script&gt;&lt;span style="font-style: italic;"&gt;&lt;script src="%3Cs:url%20value=" yui="" event="" js=""&gt;" type="text/javascript"&gt;&lt;/script&gt;&lt;/span&gt;&lt;span style="font-style: italic;"&gt;&amp;lt;script src="&lt;/span&gt;&lt;span style="font-style: italic;"&gt;&lt;script src="%3Cs:url%20value=" yui="" event="" js=""&gt;" type="text/javascript"&gt;&lt;/script&gt;&lt;/span&gt;&lt;span style="font-style: italic;"&gt;&amp;lt;s:url value="/build-${BUILD_NUMBER}/js/yui/yahoo-dom-event/yahoo-dom-event.js"/&amp;gt;" type="text/javascript"&gt;&lt;/span&gt;&lt;span style="font-style: italic;"&gt;&lt;script src="%3Cs:url%20value=" yui="" event="" js=""&gt;" type="text/javascript"&gt;&lt;/script&gt;&lt;/span&gt;&lt;span style="font-style: italic;"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;${BUILD_NUMBER}&lt;/span&gt; - is just simple placeholder, you can have any property here. (&lt;span style="font-weight: bold;"&gt;BUILD_NUMBER&lt;/span&gt; - it's a &lt;a href="https://hudson.dev.java.net/"&gt;Hudson &lt;/a&gt;variable, which is very useful as unique identifier, and QA members could always say to you what was wrong and which version of some script wasn't working)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Assume you have standard maven layout for your web project:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_CTGlw5KhVhk/Sl4TGxVmkRI/AAAAAAAAACk/33oG_72qgCc/s1600-h/directory_layout.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 304px; height: 400px;" src="http://2.bp.blogspot.com/_CTGlw5KhVhk/Sl4TGxVmkRI/AAAAAAAAACk/33oG_72qgCc/s400/directory_layout.png" alt="" id="BLOGGER_PHOTO_ID_5358741613661557010" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;So, I need placeholder &lt;span style="font-weight: bold;"&gt;${BUILD_NUMBER}&lt;/span&gt; replaced by actual value. This is just simple filtering for web application.  I want to see something like:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;&amp;lt;script src="&amp;lt;s:url value="/build-1231312/js/yui/yahoo-dom-event/yahoo-dom-event.js"/&amp;gt;" type="text/javascript"&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;But as you know standard filtering, require us to copy some resource from one directory to another. So standard maven filtering is no longer works here, because I don't want to move my jsp files anywhere just for filtering. I found solution in maven war plugin, but &lt;a href="http://maven.apache.org/plugins/maven-war-plugin/examples/adding-filtering-webresources.html"&gt;solution was only applied&lt;/a&gt; to external web resources. I was thinking, can we apply same technique for local resources as for external resources . And the answer is - yes!&lt;br /&gt;Here is example of maven plugin configuration:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;&amp;lt;build&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;...&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;               &amp;lt;plugin&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;                        &amp;lt;groupId&amp;gt;org.apache.maven.plugins&amp;lt;/groupId&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;                        &amp;lt;artifactId&amp;gt;maven-war-plugin&amp;lt;/artifactId&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;                        &amp;lt;version&amp;gt;2.0.2&amp;lt;/version&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;                        &amp;lt;configuration&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;                           &amp;lt;webResources&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;                                &amp;lt;resource&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;                                    &amp;lt;directory&amp;gt;src/main/webapp/pages&amp;lt;/directory&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;                                    &amp;lt;includes&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;                                        &amp;lt;include&amp;gt;**/*.jsp&amp;lt;/include&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;                                    &amp;lt;/includes&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;                                    &amp;lt;filtering&amp;gt;true&amp;lt;/filtering&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;                                    &amp;lt;targetPath&amp;gt;pages&amp;lt;/targetPath&amp;gt;  &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;                                &amp;lt;/resource&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;                            &amp;lt;/webResources&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;                        &amp;lt;/configuration&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;                    &amp;lt;/plugin&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;...&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;&amp;lt;/build&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;So, there is nothing tricky with this configuration: &lt;span style="font-style: italic;"&gt;directory &lt;/span&gt;is what we want to filter and &lt;span style="font-style: italic;"&gt;targetPath &lt;/span&gt;just dir, related to build directory. Source and destination directories should have the same structure. If you'll mistype directory name, you would see duplicates of your filtered files, which is not what we wanted.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Conclusion&lt;/span&gt;: you could use any file types - css, js, jsp or something else, not binaries of course :) . Web resources  filtering helps you when you need some externally configured strings at build time, not at runtime. Such filtering decouples your application from particular environment.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/754001278635115086-711276541798968523?l=fogit.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://fogit.blogspot.com/feeds/711276541798968523/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=754001278635115086&amp;postID=711276541798968523" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/754001278635115086/posts/default/711276541798968523?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/754001278635115086/posts/default/711276541798968523?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/fogit/~3/7S6xVjXJ1LY/web-resources-filtering-with-maven-2.html" title="Web resources filtering with Maven 2" /><author><name>Pavel Rodionov</name><uri>http://www.blogger.com/profile/12191929867434155859</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_CTGlw5KhVhk/Sl4SCf7mcjI/AAAAAAAAACU/jDoIzxbqSEE/s72-c/filter.jpg" height="72" width="72" /><thr:total>3</thr:total><feedburner:origLink>http://fogit.blogspot.com/2009/07/web-resources-filtering-with-maven-2.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CE8NQXs6eip7ImA9WxVUF0k.&quot;"><id>tag:blogger.com,1999:blog-754001278635115086.post-4178973356768107026</id><published>2008-05-19T06:03:00.001-07:00</published><updated>2009-03-22T10:28:10.512-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-03-22T10:28:10.512-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="ide" /><category scheme="http://www.blogger.com/atom/ns#" term="erlang" /><title>Choosing Erlang IDE</title><content type="html">&lt;div style="text-align: left;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_CTGlw5KhVhk/SDF6qWPgO-I/AAAAAAAAABA/XqDnktW273o/s1600-h/erlang_ide_selection.jpg"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer;" src="http://1.bp.blogspot.com/_CTGlw5KhVhk/SDF6qWPgO-I/AAAAAAAAABA/XqDnktW273o/s200/erlang_ide_selection.jpg" alt="" id="BLOGGER_PHOTO_ID_5202073912533335010" border="0" /&gt;&lt;/a&gt;    After having some object-oriented language experience, I decided to move forward in learing programming languages. There are many languages today and each of them correspond to some category. Ubiquity of multicore processors dictate us today new rules for scalable programming systems. And one of the interesting trend in programming - functional programming languages. Maybe I was affected by Steve Vinoski &lt;a href="http://steve.vinoski.net/blog/"&gt;blog &lt;/a&gt; or some InfoQ &lt;a href="http://www.infoq.com/erlang"&gt;articles&lt;/a&gt; , but &lt;a href="http://www.erlang.org/"&gt;Erlang &lt;/a&gt;language was chosen.&lt;br /&gt;&lt;br /&gt;After writing on java for two  consecutive years I formed the habit of using my lovely IDE (not a secret it's  &lt;a href="http://www.jetbrains.com/idea/"&gt;Intellij IDEA&lt;/a&gt;). And I started to dig for something similar in Erlang space.&lt;br /&gt; Though i had 4 candidates :&lt;br /&gt;&lt;ul&gt;&lt;li&gt; &lt;a href="http://erlide.sourceforge.net/"&gt;Erlide&lt;/a&gt; - plugin for eclipse (ver. &lt;strong style="font-weight: normal;"&gt;0.3.45&lt;/strong&gt;)&lt;/li&gt;&lt;li&gt;&lt;a href="http://sourceforge.net/projects/erlybird"&gt;Erlybird &lt;/a&gt;- plugin for netbeans (ver. 0.16.0)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.ultraedit.com/"&gt;Ultraedit &lt;/a&gt;- win32 text editor + with syntax &lt;a href="http://www.erlang.org/download/contrib/ultraedit_erlang.zip"&gt;highlighting&lt;br /&gt;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Emacs - with erlang  mode (according to documentation this is a best way of developing erlang apps)&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-style: italic;"&gt;Last variant with emacs occured suddenly during playing with first three candidates. Reason is subconscious resistance to *NIX utils cause win32 legacy.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;Main criteria in choosing IDE were : syntax highlighting, smart identation,  quick  compilation of  *. erl  files, code templates and integrated console.&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Maybe because 0 is major release number or some other reasons but the first two IDE Erlide and Erlybird are very raw.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;    Erlide - is interesting IDE, but many  unpredictable errors occured during usage. But in future, i think this IDE has high chances to become ubiquitous. WRT my criterias of choosing IDE it has syntax highlighting, smart identation(very simple) , compilation is made faster after some project configuration(it's not clear).  Mark: &lt;span style="font-weight: bold;"&gt;3/5&lt;/span&gt;.&lt;br /&gt;&lt;span style="font-style: italic;"&gt;This IDE has features which I don't evaluate, because the researh was to find most comfortable IDE for code editing,but not most functional.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;    Erlybird - visually it's fantastic, it has beautiful syntax highlights and identation ,  autocompletion is good, but some bugs during exploitation is upset me. Mark: &lt;span style="font-weight: bold;"&gt;3,5/5&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Ultraedit -well, it's not IDE actually,it's text editor with many features and languages supported, but sadly Erlang natively isn't supported and only using aforementioned wordfile (plugin for ultraedit) we can add support for some pleasant features. Actually it's only syntax highlighting, not great. But this editor has some templates support. Another disadvantage - shareware.  Mark: &lt;span style="font-weight: bold;"&gt;1,5/5&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;  Emacs (erlang mode) - well, when I set a goal  to research some  IDE for  Erlang I  couldn't predict that emacs will be one of candidates. It was added for comparison because first 3 IDE was not production-ready. Emacs has all you needed in Erlang development. But it has some learning curve in learning emacs finger-crossing:) but you won't be sorry. Mark: &lt;span style="font-weight: bold;"&gt;4/5&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;  So if you want production-ready Erlang use Emacs with Erlang mode. If you developed earlier for Netbeans or Eclipse platform you can choose   Erlybird  or Erlide but don't forget this IDE are currently in the beginning phase. If you bought Ultraedit and you like them much use Ultraedit with wordfile.&lt;br /&gt;&lt;span style="text-decoration: underline;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/754001278635115086-4178973356768107026?l=fogit.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://fogit.blogspot.com/feeds/4178973356768107026/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=754001278635115086&amp;postID=4178973356768107026" title="9 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/754001278635115086/posts/default/4178973356768107026?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/754001278635115086/posts/default/4178973356768107026?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/fogit/~3/fHD9yYrx8Ik/choosing-erlang-ide_19.html" title="Choosing Erlang IDE" /><author><name>Pavel Rodionov</name><uri>http://www.blogger.com/profile/12191929867434155859</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/_CTGlw5KhVhk/SDF6qWPgO-I/AAAAAAAAABA/XqDnktW273o/s72-c/erlang_ide_selection.jpg" height="72" width="72" /><thr:total>9</thr:total><feedburner:origLink>http://fogit.blogspot.com/2008/05/choosing-erlang-ide_19.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0MBRX8yfSp7ImA9WxVRE00.&quot;"><id>tag:blogger.com,1999:blog-754001278635115086.post-3682483929535886441</id><published>2008-04-05T11:57:00.001-07:00</published><updated>2009-01-18T11:04:14.195-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-01-18T11:04:14.195-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="session manager" /><category scheme="http://www.blogger.com/atom/ns#" term="struts 2" /><category scheme="http://www.blogger.com/atom/ns#" term="ejb 3" /><category scheme="http://www.blogger.com/atom/ns#" term="tomcat" /><category scheme="http://www.blogger.com/atom/ns#" term="jboss" /><title>Struts 2 session replication</title><content type="html">&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_CTGlw5KhVhk/R_z0T4LyMsI/AAAAAAAAAA4/pG0E2Q7jEUg/s1600-h/1767677232_c0788ab76b_m.jpg"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer;" src="http://4.bp.blogspot.com/_CTGlw5KhVhk/R_z0T4LyMsI/AAAAAAAAAA4/pG0E2Q7jEUg/s200/1767677232_c0788ab76b_m.jpg" alt="" id="BLOGGER_PHOTO_ID_5187289493160473282" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;p&gt;&lt;em&gt;Very often the following task occuring: saving  and distributing session between web applications. In this post, implemented  one of the strategies of saving and distributing session for web framework  Struts 2.&lt;/em&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;em&gt;Used technologies : &lt;a href="http://trailblazer.demo.jboss.com/EJB3Trail/"&gt;EJB3&lt;/a&gt;, &lt;a href="http://struts.apache.org/2.x/"&gt;Struts-2&lt;/a&gt;, &lt;a href="http://tomcat.apache.org/"&gt;Tomcat&lt;/a&gt;, &lt;a href="http://www.jboss.org/"&gt;Jboss&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;So we have  task for linking several web applications with Session Manager. One of the  restrictions in this implementation is usage of subdomains of domain e.g.  *.domain.com. So we can use domain cookies (this restriction can be taken off  with URL rewriting, but in this implementation we use cookies ). Because existed system was build on  Struts 2 web framework, we decided to  use internal capabilities of this framework.  As we will see further, Struts 2 has very exciting futures called &lt;a href="http://struts.apache.org/2.x/docs/writing-interceptors.html"&gt;Interceptors&lt;/a&gt;,  and they help us to get rid of crosscutting concernes.&lt;br /&gt;Session Manager  is a EJB3 component with simple interface,  for simplicity only subset of methods will be shown with descriptive methods  signature :&lt;/p&gt;&lt;br /&gt;&lt;pre style="border-left: 5px solid rgb(221, 221, 221); background-color: rgb(239, 239, 239); color: rgb(0, 0, 0);" andale="" mono="" courier="" new="" 0px="" 15px="" 5px=""&gt;&lt;br /&gt;@Remote&lt;br /&gt;public interface SessionManagerRemote {&lt;br /&gt;  void extendActivity(String sessionId) throws SessionExpiredException;&lt;br /&gt;  String registerActivity();&lt;br /&gt;  void unregister(String sessionId);&lt;br /&gt;  Long getSessionDuration(String sessionId);&lt;br /&gt;  Map getSession (String sessionId) throws SessionExpiredException;&lt;br /&gt;  void putSession (String sessionId,Map&lt;string,object&gt; sessionObjects)throws SessionExpiredException;&lt;br /&gt;}&lt;br /&gt;&lt;/string,object&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;This  component will be deployed on J2EE Application Server, e.g. JBOSS. Jboss  implementation following:&lt;/p&gt;&lt;br /&gt;&lt;pre style="border-left: 5px solid rgb(221, 221, 221); background-color: rgb(239, 239, 239); color: rgb(0, 0, 0);" andale="" mono="" courier="" new="" 0px="" 15px="" 5px=""&gt;&lt;br /&gt;@org.jboss.annotation.ejb.Service(objectName = "jboss:managementService=SessionManager")&lt;br /&gt;@Remote(SessionManagerRemote.class)&lt;br /&gt;@org.jboss.annotation.ejb.RemoteBinding(jndiBinding = "com/project/management/session/remote")&lt;br /&gt;public class SessionManager implements SessionManagerRemote {&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;&lt;a href="http://docs.jboss.com/ejb3/app-server/tutorial/service/service.html"&gt;Service&lt;/a&gt; annotation is used for Singleton implementation in Jboss runtime.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;So, back to  main task. We need to replace Struts 2 session implementation with our  distributed session, controlled by session manager. But for make such serious  session replacement we must understand architecture of Struts 2 framework.  First we must detect how we use session in Struts 2 application :&lt;/p&gt;&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt; OGNL expressions with #session identifier e.g. &amp;lt;s:property:value="#session.PARAMETER_IN_SESSION"/&amp;gt; &lt;/li&gt;&lt;br /&gt;&lt;li&gt;Actions that implement &lt;a href="http://struts.apache.org/2.0.11/struts2-core/apidocs/org/apache/struts2/interceptor/SessionAware.html"&gt;SessionAware&lt;/a&gt; interface :&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;pre style="border-left: 5px solid rgb(221, 221, 221); background-color: rgb(239, 239, 239); color: rgb(0, 0, 0);" andale="" mono="" courier="" new="" 0px="" 15px="" 5px=""&gt;&lt;br /&gt;public class TempAction implements SessionAware {&lt;br /&gt;  private Map session;&lt;br /&gt;  public void setSession(Map map) {&lt;br /&gt;      this.session = map;&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;So we must create our interceptor  that &lt;/p&gt;&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;initialize OGNL value stack with our  distributed session &lt;/li&gt;&lt;br /&gt;&lt;li&gt;inject our distributed session in  Actions that implements SessionAware interface&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;p&gt;According  to Struts 2 source code, &lt;a href="http://svn.apache.org/repos/asf/struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/Dispatcher.java"&gt;Dispatcher&lt;/a&gt; initialize OGNL value stack, and session in particular:&lt;/p&gt;&lt;br /&gt;&lt;pre style="border-left: 5px solid rgb(221, 221, 221); background-color: rgb(239, 239, 239); color: rgb(0, 0, 0);" andale="" mono="" courier="" new="" 0px="" 15px="" 5px=""&gt;&lt;br /&gt;extraContext.put("session", sessionMap);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;and &lt;a href="http://svn.apache.org/repos/asf/struts/struts2/trunk/core/src/main/java/org/apache/struts2/interceptor/ServletConfigInterceptor.java"&gt;ServletConfigInterceptor&lt;/a&gt; injects session in Action classes.So we  override such behaviour as following :&lt;/p&gt;&lt;br /&gt;&lt;pre style="border-left: 5px solid rgb(221, 221, 221); background-color: rgb(239, 239, 239); color: rgb(0, 0, 0);" andale="" mono="" courier="" new="" 0px="" 15px="" 5px=""&gt;&lt;br /&gt;//initializing session in OGNL value stack&lt;br /&gt;actionInvocation.getInvocationContext().getContextMap().put("session",distributedSession); &lt;br /&gt;//injecting our session&lt;br /&gt;if (action instanceof SessionAware) {&lt;br /&gt; ((SessionAware) action).setSession(distributedSession);&lt;br /&gt;}&lt;br /&gt;  &lt;/pre&gt;&lt;br /&gt;&lt;p&gt;So final  configuration is following. struts.xml  :&lt;/p&gt;&lt;br /&gt;&lt;pre style="border-left: 5px solid rgb(221, 221, 221); background-color: rgb(239, 239, 239); color: rgb(0, 0, 0);" andale="" mono="" courier="" new="" 0px="" 15px="" 5px=""&gt;&lt;p&gt;&amp;lt;struts&amp;gt;&lt;br /&gt;           &amp;lt;package  name="default" extends="struts-default"&amp;gt;&lt;br /&gt;                       &amp;lt;interceptors&amp;gt;&lt;br /&gt;                                  &amp;lt;interceptor name="distributedSession" class="com.interceptors.SessionCheckerInterceptor"/&amp;gt;&lt;br /&gt;                                  &amp;lt;interceptor-stack name="distributedSessionStack"&amp;gt;&lt;br /&gt;                                              &amp;lt;interceptor-ref name="basicStack"/&amp;gt;&lt;br /&gt;                                              &amp;lt;interceptor-ref name="distributedSession"/&amp;gt;&lt;br /&gt;                                  &amp;lt;/interceptor-stack&amp;gt;&lt;br /&gt;                       &amp;lt;/interceptors&amp;gt;&lt;br /&gt;                       &amp;lt;default-interceptor-ref name="distributedSessionStack"/&amp;gt;&lt;br /&gt;           &amp;lt;/package&amp;gt;&lt;br /&gt;           &amp;lt;package  name="test" extends="default"  namespace="/actions"&amp;gt;&lt;br /&gt;                       &amp;lt;action  name="logon" class="com.actions.SomeTemporaryAction" method="login"&amp;gt;&lt;br /&gt;                                  &amp;lt;result  name="success" type="redirectAction"&amp;gt;myaccount&amp;lt;/result&amp;gt;&lt;br /&gt;                                  &amp;lt;result  name="input" type="redirect"&amp;gt;/&amp;lt;/result&amp;gt;&lt;br /&gt;                       &amp;lt;/action&amp;gt;&lt;br /&gt;           &amp;lt;/package&amp;gt;&lt;br /&gt;&amp;lt;/struts&amp;gt; &lt;/p&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;We call  interceptor distributedSession, and it must be in list after basicStack in order to work  consistently.&lt;br /&gt;Final  version of our Interceptor :&lt;/p&gt;&lt;br /&gt;&lt;pre style="border-left: 5px solid rgb(221, 221, 221); background-color: rgb(239, 239, 239); color: rgb(0, 0, 0);" andale="" mono="" courier="" new="" 0px="" 15px="" 5px=""&gt;&lt;br /&gt;public class SessionCheckerInterceptor extends AbstractInterceptor {&lt;br /&gt;  public String intercept(ActionInvocation actionInvocation) throws Exception {&lt;br /&gt;      HttpServletRequest request = ServletActionContext.getRequest();&lt;br /&gt;      String distributedSession = processCookie(request);&lt;br /&gt;      String result = null;&lt;br /&gt;      Map sessionBeforeInvokation = JNDICacheableFactory.getSessionManager().getSession(distributedSession);&lt;br /&gt;      Object action = actionInvocation.getAction();&lt;br /&gt;      if (action instanceof SessionAware) {&lt;br /&gt;          ((SessionAware) action).setSession(sessionBeforeInvokation);&lt;br /&gt;      }&lt;br /&gt;      actionInvocation.getInvocationContext().setSession(sessionBeforeInvokation);&lt;br /&gt;      actionInvocation.getInvocationContext().getContextMap().put("session", sessionBeforeInvokation); &lt;br /&gt;      int beforeInvHash = sessionBeforeInvokation.hashCode();&lt;br /&gt;&lt;br /&gt;      result = actionInvocation.invoke();&lt;br /&gt;&lt;br /&gt;      Map sessionAfterInvocation = actionInvocation.getInvocationContext().getSession();&lt;br /&gt;&lt;br /&gt;      int afterInvHash = sessionAfterInvocation.hashCode();&lt;br /&gt;&lt;br /&gt;      if (afterInvHash != beforeInvHash) {&lt;br /&gt;          JNDICacheableFactory.getSessionManager().putSession(distributedSession, sessionAfterInvocation);&lt;br /&gt;      }&lt;br /&gt;      return result;&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;:  method processCookie omited, in this method cookie processing logic  implemented, but if we’d want to realize cross-domain logic we might use URL  rewriting for example (in our case we use cookies because we use subdomains of  similar domain).&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: for  checking updates in session we compare their hashes, but other implementations  are possible. If session changed it is updated.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/754001278635115086-3682483929535886441?l=fogit.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://fogit.blogspot.com/feeds/3682483929535886441/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=754001278635115086&amp;postID=3682483929535886441" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/754001278635115086/posts/default/3682483929535886441?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/754001278635115086/posts/default/3682483929535886441?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/fogit/~3/kgTOwaKuAAw/choosing-appropriate-methodology.html" title="Struts 2 session replication" /><author><name>Pavel Rodionov</name><uri>http://www.blogger.com/profile/12191929867434155859</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_CTGlw5KhVhk/R_z0T4LyMsI/AAAAAAAAAA4/pG0E2Q7jEUg/s72-c/1767677232_c0788ab76b_m.jpg" height="72" width="72" /><thr:total>2</thr:total><feedburner:origLink>http://fogit.blogspot.com/2008/04/choosing-appropriate-methodology.html</feedburner:origLink></entry></feed>

