<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-2330120457456880954</id><updated>2012-01-06T14:42:52.620+11:00</updated><category term='logging'/><category term='EJB'/><category term='Tomcat'/><category term='Google Guice'/><category term='Apache Tiles'/><category term='JBoss'/><category term='Spring MVC'/><category term='SQL'/><category term='Javascript'/><category term='Eclipse'/><category term='HTML'/><category term='Hibernate'/><category term='JSF'/><category term='Spring'/><category term='Web Service'/><category term='Unit Testing'/><category term='JDBC'/><title type='text'>DevGrok</title><subtitle type='html'>A collection of my solutions to obscure or painful problems dealing with Java, SQL, Web and whatever I feel like at the time.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://devgrok.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://devgrok.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Christopher Watts</name><uri>http://www.blogger.com/profile/12923587712192007751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://3.bp.blogspot.com/_qoo3n1eKv3E/Swn9NTUeryI/AAAAAAAAC6A/qESuFc9W1CQ/S220/P9260160.JPG'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>44</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-2330120457456880954.post-2366944331513803910</id><published>2012-01-06T14:42:00.001+11:00</published><updated>2012-01-06T14:42:52.633+11:00</updated><title type='text'>Bulk upload of maven artifacts to remote repo</title><content type='html'>If you have an artifact you want to upload to a remote repository (i.e. internal company repo) then you use the command:&lt;pre&gt;mvn deploy:deploy-file -Durl=file://C:\m2-repo \&lt;br /&gt;                       -DrepositoryId=some.id \&lt;br /&gt;                       -Dfile=your-artifact-1.0.jar \&lt;br /&gt;                       [-DpomFile=your-pom.xml] \&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;However if you have more than a few files and they're in a nested directory structure (like your local repo) then this is not the way to do it. There doesn't seem to be any tool for either maven or nexus to do this, so here's a quick and dirty way I hacked together:&lt;pre class="brush:java"&gt;/**&lt;br /&gt; * run as java Importer [dirtosearch]&lt;br /&gt; **/&lt;br /&gt;public class Importer {&lt;br /&gt;   private String directory;&lt;br /&gt;   private final static String repositoryId = "repo1";&lt;br /&gt;   private final static String url = "http://remoteserver/nexus/content/repositories/repo1/";&lt;br /&gt;   private final static String mvn = "C:/java/apache-maven-3.0.3/bin/mvn.bat";&lt;br /&gt;&lt;br /&gt;   /**&lt;br /&gt;    * @param directory&lt;br /&gt;    */&lt;br /&gt;   public Importer(String directory) {&lt;br /&gt;      super();&lt;br /&gt;      this.directory = directory;&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   public static void main(String[] args) {&lt;br /&gt;      Importer importer = new Importer(args[0]);&lt;br /&gt;      importer.go();&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   private void go() {&lt;br /&gt;      try {&lt;br /&gt;         File dir = new File(directory);&lt;br /&gt;&lt;br /&gt;         doDir(dir);&lt;br /&gt;      }&lt;br /&gt;      catch (Throwable e) {&lt;br /&gt;         e.printStackTrace();&lt;br /&gt;      }&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   private void doDir(File dir) throws IOException, InterruptedException {&lt;br /&gt;      File[] listFiles = dir.listFiles(new PomFilter());&lt;br /&gt;      if (listFiles != null) {&lt;br /&gt;         for (File pom : listFiles) {&lt;br /&gt;            doPom(pom);&lt;br /&gt;         }&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;      File[] listDirs = dir.listFiles(new DirFilter());&lt;br /&gt;      if (listDirs != null) {&lt;br /&gt;         for (File subdir : listDirs) {&lt;br /&gt;            doDir(subdir);&lt;br /&gt;         }&lt;br /&gt;      }&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   private void doPom(File pom) throws IOException, InterruptedException {&lt;br /&gt;      File base = pom.getParentFile();&lt;br /&gt;      String fileName = pom.getName();&lt;br /&gt;      String jarName = fileName.substring(0, fileName.length() - 3) + "jar";&lt;br /&gt;      File jar = new File(base.getAbsolutePath() + "/" + jarName);&lt;br /&gt;&lt;br /&gt;      String exec = mvn + " deploy:deploy-file -DrepositoryId=" + repositoryId + " -Durl=" + url;&lt;br /&gt;      if (jar.exists()) {&lt;br /&gt;         exec += " -Dfile=\"" + jar.getAbsolutePath() + "\"";&lt;br /&gt;      }&lt;br /&gt;      else {&lt;br /&gt;         exec += " -Dfile=\"" + pom.getAbsolutePath() + "\"";&lt;br /&gt;      }&lt;br /&gt;      exec += " -DpomFile=\"" + pom.getAbsolutePath() + "\"";&lt;br /&gt;      exec(exec);&lt;br /&gt;&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   private void exec(String exec) throws InterruptedException, IOException {&lt;br /&gt;      System.out.println(exec);&lt;br /&gt;      Process p = Runtime.getRuntime().exec(exec);&lt;br /&gt;      String line;&lt;br /&gt;      BufferedReader bri = new BufferedReader(new InputStreamReader(p.getInputStream()));&lt;br /&gt;      BufferedReader bre = new BufferedReader(new InputStreamReader(p.getErrorStream()));&lt;br /&gt;      while ((line = bri.readLine()) != null) {&lt;br /&gt;         System.out.println(line);&lt;br /&gt;      }&lt;br /&gt;      bri.close();&lt;br /&gt;      while ((line = bre.readLine()) != null) {&lt;br /&gt;         System.out.println(line);&lt;br /&gt;      }&lt;br /&gt;      bre.close();&lt;br /&gt;      p.waitFor();&lt;br /&gt;      System.out.println("Done.");&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   private class PomFilter implements java.io.FileFilter {&lt;br /&gt;&lt;br /&gt;      @Override&lt;br /&gt;      public boolean accept(File pathname) {&lt;br /&gt;         return pathname.getName().endsWith(".pom");&lt;br /&gt;      }&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   private class DirFilter implements java.io.FileFilter {&lt;br /&gt;&lt;br /&gt;      @Override&lt;br /&gt;      public boolean accept(File pathname) {&lt;br /&gt;         return pathname.isDirectory();&lt;br /&gt;      }&lt;br /&gt;   }&lt;br /&gt;}&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2330120457456880954-2366944331513803910?l=devgrok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devgrok.blogspot.com/feeds/2366944331513803910/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://devgrok.blogspot.com/2012/01/bulk-upload-of-maven-artifacts-to.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/2366944331513803910'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/2366944331513803910'/><link rel='alternate' type='text/html' href='http://devgrok.blogspot.com/2012/01/bulk-upload-of-maven-artifacts-to.html' title='Bulk upload of maven artifacts to remote repo'/><author><name>Christopher Watts</name><uri>http://www.blogger.com/profile/12923587712192007751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://3.bp.blogspot.com/_qoo3n1eKv3E/Swn9NTUeryI/AAAAAAAAC6A/qESuFc9W1CQ/S220/P9260160.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2330120457456880954.post-3640566764449240371</id><published>2011-05-11T17:52:00.002+10:00</published><updated>2011-10-05T11:15:57.715+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Web Service'/><title type='text'>WAS SOAPFault causing throws a WebServicesFault</title><content type='html'>When returning a SOAPFault  from a SOAP handler I saw this in Websphere Application Server's (6.1.0) console:&lt;br /&gt;&lt;pre&gt;[11/05/11 18:20:51:654 EST] 00000047 WebServicesSe E com.ibm.ws.webservices.engine.transport.http.WebServicesServlet doPost WSWS3227E:  Error: Exception:&lt;br /&gt;                                 WebServicesFault&lt;br /&gt; faultCode: 666&lt;br /&gt; faultString: myfaultstring&lt;br /&gt; faultActor: myhandler&lt;br /&gt; faultDetail: &lt;br /&gt;&lt;br /&gt;myfaultstring&lt;br /&gt; at com.ibm.ws.webservices.engine.xmlsoap.builders.WebServicesFaultProcessor.createFault(WebServicesFaultProcessor.java:420)&lt;br /&gt; at com.ibm.ws.webservices.engine.xmlsoap.SOAPFault.getFault(SOAPFault.java:615)&lt;br /&gt; at com.ibm.ws.webservices.engine.SOAPPart.getFault(SOAPPart.java:1097)&lt;br /&gt; at com.ibm.ws.webservices.engine.SOAPPart.getFault(SOAPPart.java:754)&lt;br /&gt; at com.ibm.ws.webservices.engine.Message.getFault(Message.java:935)&lt;br /&gt; ....&lt;br /&gt;&lt;/pre&gt;Or when throwing a custom SOAPFaultException:&lt;br /&gt;&lt;pre&gt;[11/05/11 18:32:05:678 EST] 00000065 WebServicesSe E com.ibm.ws.webservices.engine.transport.http.WebServicesServlet doPost WSWS3227E:  Error: Exception:&lt;br /&gt;                                 WebServicesFault&lt;br /&gt; faultCode: myWebServiceFunction&lt;br /&gt; faultString: my test&lt;br /&gt; faultActor: testActor&lt;br /&gt; faultDetail: &lt;br /&gt;&lt;br /&gt;my test&lt;br /&gt; at com.ibm.ws.webservices.engine.WebServicesFault.makeFault(WebServicesFault.java:189)&lt;br /&gt; at com.ibm.ws.webservices.engine.dispatchers.java.SessionDispatcher.invoke(SessionDispatcher.java:213)&lt;br /&gt; at com.ibm.ws.webservices.engine.PivotHandlerWrapper.invoke(PivotHandlerWrapper.java:248)&lt;br /&gt; ...&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;A SOAP fault is still returned to the client but you get a WebServicesFault exception on both ends. Digging into Websphere's with the help of a decompiler shows that this is caused simply by no fault detail being passed. Simply adding a fault detail with a text of "error" gets rid of this error.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2330120457456880954-3640566764449240371?l=devgrok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devgrok.blogspot.com/feeds/3640566764449240371/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://devgrok.blogspot.com/2011/05/was-soapfault-causing-throws.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/3640566764449240371'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/3640566764449240371'/><link rel='alternate' type='text/html' href='http://devgrok.blogspot.com/2011/05/was-soapfault-causing-throws.html' title='WAS SOAPFault causing throws a WebServicesFault'/><author><name>Christopher Watts</name><uri>http://www.blogger.com/profile/12923587712192007751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://3.bp.blogspot.com/_qoo3n1eKv3E/Swn9NTUeryI/AAAAAAAAC6A/qESuFc9W1CQ/S220/P9260160.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2330120457456880954.post-609468676445883042</id><published>2010-11-01T14:40:00.002+11:00</published><updated>2011-10-04T22:51:45.702+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JSF'/><title type='text'>Persisting ViewScoped beans across views in request</title><content type='html'>I came across this problem when trying to deal with view scoped beans that you want to reuse in a different view, i.e. after clicking next in a wizard like page.&lt;br /&gt;&lt;br /&gt;This was originally&amp;nbsp;&lt;a href="http://forums.sun.com/thread.jspa?threadID=5436699"&gt;Discussed Here&lt;/a&gt;&amp;nbsp;(now removed since Oracle merged Sun's forums).&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;The View Scope&lt;/span&gt;&lt;br /&gt;There is a a brief summary of it here: &lt;a href="http://137.254.16.27/rlubke/entry/jsf_2_0_new_feature6"&gt;JSF 2.0 New Feature Preview Series (Part 5) EDR1 Potpourri&lt;/a&gt;.&lt;br /&gt;Basically view scoped values are attached to the current viewId.&amp;nbsp;Values for the view scoped variables are stored in the map returned by&amp;nbsp;&lt;a href="http://java.sun.com/javaee/javaserverfaces/2.0/docs/api/javax/faces/component/UIViewRoot.html#getViewMap%28boolean%29"&gt;UIViewRoot.getViewMap(boolean)&lt;/a&gt;. Which is great for when your accessing the same view. However, it is cleared when the view is changed (e.g. from a navigation result) &lt;a href="http://java.sun.com/javaee/javaserverfaces/2.0/docs/api/javax/faces/context/FacesContext.html#setViewRoot%28javax.faces.component.UIViewRoot%29"&gt;FacesContext.setViewRoot(javax.faces.component.UIViewRoot)&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;However, the flash scope was designed seemingly to solve this very problem.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;Using the Flash Scope&lt;/span&gt;&lt;br /&gt;Here's a write up of the &lt;a href="http://www.jroller.com/HazemBlog/entry/understanding_the_jsf_2_0"&gt;Understanding the JSF 2.0 Flash scope&lt;/a&gt;. There's also some&amp;nbsp;caveats&amp;nbsp;shown here:&amp;nbsp;&lt;a href="http://balusc.blogspot.com/2010/06/benefits-and-pitfalls-of-viewscoped.html"&gt;The benefits and pitfalls of @ViewScoped&lt;/a&gt;.&lt;br /&gt;So the logical step is to try it, :&lt;br /&gt;&lt;pre class="brush:java"&gt;public String doIt() {&lt;br /&gt;   FacesContext.getCurrentInstance().getExternalContext().getFlash().put("thisBean", this);   return "next";&lt;br /&gt;}&lt;/pre&gt;However, after some poking around, I discovered you can't re-store in FlashScope as &lt;code&gt;ManagedBeanELResolver&lt;/code&gt; is before &lt;code&gt;ScopedAttributeELResolver&lt;/code&gt; in the expression language resolver chain. Meaning that if you have a view &lt;code&gt;"view1"&lt;/code&gt; with bean name &lt;code&gt;"viewScopeBean1"&lt;/code&gt; and want to use the exact same bean in &lt;code&gt;"view2"&lt;/code&gt; with bean name &lt;code&gt;"viewScopeBean2"&lt;/code&gt;, you can't.&lt;br /&gt;The most you can do is store whatever data you need in the flash scope, then in the @PostConstruct of the new bean, pull in the values you need. Not an elegant solution but I'm sure messing around with the ELResolver chain could also do it but then you run the risk of it breaking else where.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2330120457456880954-609468676445883042?l=devgrok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devgrok.blogspot.com/feeds/609468676445883042/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://devgrok.blogspot.com/2010/11/persisting-viewscoped-beans-across.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/609468676445883042'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/609468676445883042'/><link rel='alternate' type='text/html' href='http://devgrok.blogspot.com/2010/11/persisting-viewscoped-beans-across.html' title='Persisting ViewScoped beans across views in request'/><author><name>Christopher Watts</name><uri>http://www.blogger.com/profile/12923587712192007751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://3.bp.blogspot.com/_qoo3n1eKv3E/Swn9NTUeryI/AAAAAAAAC6A/qESuFc9W1CQ/S220/P9260160.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2330120457456880954.post-2524880777493517891</id><published>2010-10-12T18:19:00.001+11:00</published><updated>2010-10-12T18:36:31.033+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JSF'/><title type='text'>f:convertNumber parses to double not BigDecimal</title><content type='html'>The default behaviour of the &lt;a href="https://javaserverfaces.dev.java.net/nonav/docs/2.0/pdldocs/facelets/f/convertNumber.html"&gt;f:convertNumber&lt;/a&gt;, implemented with &lt;a href="https://javaserverfaces.dev.java.net/nonav/docs/2.0/javadocs/javax/faces/convert/NumberConverter.html"&gt;NumberConverter&lt;/a&gt;, in converting a decimal String of "1.11", is to convert it to a double and then JSF converts that to a &lt;code&gt;BigDecimal&lt;/code&gt;. Most of the time you won't notice this happening until you use CallableStatement.setBigDecimal to invoke a stored procedure. In MS SQL Server, you get the following error:&lt;br /&gt;&lt;pre&gt;com.microsoft.sqlserver.jdbc.SQLServerException: Error converting data type nvarchar to decimal.&lt;/pre&gt;The cause of this is because inside the BigDecimal it stored "1100000000000000976996261670137755572795867919921875" as a result of converting the &lt;code&gt;String&lt;/code&gt; to a &lt;code&gt;double&lt;/code&gt;. This floating point error is the motivation for using &lt;code&gt;BigDecimal&lt;/code&gt; in the first place. And of course because the SQL Server JDBC driver didn't know how to handle the BigDecimal properly.&lt;br /&gt;&lt;br /&gt;Looking into &lt;code&gt;ConvertNumber&lt;/code&gt;, it uses one of two converters (&lt;code&gt;DecimalFormat&lt;/code&gt; or &lt;code&gt;NumberFormat&lt;/code&gt;) depending on whether 'pattern' is used. In Java 5, they added &lt;a href="http://download-llnw.oracle.com/javase/1.5.0/docs/api/java/text/DecimalFormat.html#setParseBigDecimal%28boolean%29"&gt;setParseBigDecimal(boolean newValue)&lt;/a&gt; in order to yield the desired output. &lt;br /&gt;&lt;br /&gt;You can't easily change the NumberConverter but you can very simply add your own. To do so, I grabbed the source of NumberConverter from Mojarra 2.0.2 and copied all of it into my own class: &lt;code&gt;net.devgrok.BigDecimalConverter&lt;/code&gt;.&lt;br /&gt;&lt;pre class="brush:java"&gt;@FacesConverter(forClass = BigDecimal.class, value="bigdecimal")&lt;br /&gt;public class BigDecimalConverter implements Converter, PartialStateHolder {&lt;br /&gt;&lt;br /&gt;// ... existing code&lt;br /&gt;&lt;br /&gt;  public Object getAsObject(FacesContext context, UIComponent component, String value) {&lt;br /&gt;&lt;br /&gt;// ... existing code&lt;br /&gt;&lt;br /&gt;      // Create and configure the parser to be used&lt;br /&gt;      parser = getNumberFormat(locale);&lt;br /&gt;      if (((pattern != null) &amp;amp;&amp;amp; pattern.length() != 0) || "currency".equals(type))&lt;br /&gt;      {&lt;br /&gt;        configureCurrency(parser);&lt;br /&gt;      }&lt;br /&gt;      parser.setParseIntegerOnly(isIntegerOnly());&lt;br /&gt;      boolean groupSepChanged = false;&lt;br /&gt;&lt;br /&gt;      // BEGIN BigDecimal HACK&lt;br /&gt;      if (parser instanceof DecimalFormat)&lt;br /&gt;      {&lt;br /&gt;        ((DecimalFormat) parser).setParseBigDecimal(true);&lt;br /&gt;      }&lt;br /&gt;      // END BigDecimal HACK&lt;br /&gt;      &lt;br /&gt;// ... existing code&lt;br /&gt;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;// ... existing code&lt;br /&gt;&lt;br /&gt;}&lt;/pre&gt;Then just create a file META-INF/custom.taglib.xml:&lt;br /&gt;&lt;pre class="brush:xml"&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;facelet-taglib xmlns="http://java.sun.com/xml/ns/javaee"&lt;br /&gt;    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&lt;br /&gt;    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facelettaglibrary_2_0.xsd"&lt;br /&gt;    version="2.0"&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;namespace&amp;gt;http://devgrok.net/facestags&amp;lt;/namespace&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;tag&amp;gt;&lt;br /&gt;        &amp;lt;tag-name&amp;gt;convertBigDecimal&amp;lt;/tag-name&amp;gt;&lt;br /&gt;        &amp;lt;converter&amp;gt;&lt;br /&gt;            &amp;lt;converter-id&amp;gt;bigdecimal&amp;lt;/converter-id&amp;gt;&lt;br /&gt;        &amp;lt;/converter&amp;gt;&lt;br /&gt;    &amp;lt;/tag&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/facelet-taglib&amp;gt;&lt;/pre&gt;&lt;br /&gt;And to use: &lt;br /&gt;&lt;pre class="brush: xml"&gt;&amp;lt;?xml version="1.0" ?&amp;gt;&lt;br /&gt;&amp;lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&amp;gt;&lt;br /&gt;&amp;lt;ui:composition xmlns="http://www.w3.org/1999/xhtml"&lt;br /&gt;  xmlns:ui="http://java.sun.com/jsf/facelets"&lt;br /&gt;  xmlns:h="http://java.sun.com/jsf/html"&lt;br /&gt;  xmlns:f="http://java.sun.com/jsf/core"&lt;br /&gt;  xmlns:fn="http://java.sun.com/jsp/jstl/functions"&lt;br /&gt;  xmlns:c="http://java.sun.com/jsp/jstl/core"&lt;br /&gt;  xmlns:dg="http://devgrok.net/facestags"&lt;br /&gt;  &amp;gt;&lt;br /&gt;&lt;br /&gt;  from goes here etc&lt;br /&gt;  &lt;br /&gt;  &amp;lt;h:inputText id="txtPrice" value="#{bean.item.price}"&amp;gt;&lt;br /&gt;    &amp;lt;dg:convertBigDecimal pattern="##0.00" /&amp;gt;&lt;br /&gt;  &amp;lt;/h:inputText&amp;gt;&lt;br /&gt;  &lt;br /&gt;&amp;lt;/ui:composition&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2330120457456880954-2524880777493517891?l=devgrok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devgrok.blogspot.com/feeds/2524880777493517891/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://devgrok.blogspot.com/2010/10/fconvertnumber-creates-doubles-not.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/2524880777493517891'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/2524880777493517891'/><link rel='alternate' type='text/html' href='http://devgrok.blogspot.com/2010/10/fconvertnumber-creates-doubles-not.html' title='f:convertNumber parses to double not BigDecimal'/><author><name>Christopher Watts</name><uri>http://www.blogger.com/profile/12923587712192007751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://3.bp.blogspot.com/_qoo3n1eKv3E/Swn9NTUeryI/AAAAAAAAC6A/qESuFc9W1CQ/S220/P9260160.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2330120457456880954.post-8367820743700241109</id><published>2010-09-19T21:37:00.003+10:00</published><updated>2010-09-27T16:41:33.951+10:00</updated><title type='text'>Fixing my HTC Desire's wifi</title><content type='html'>I recently did an Over The Air (OTA) update of my new HTC Desire from 2.09 to 2.10. The update all seemed to run correctly. However I soon noticed that the wifi wasn't working. Looking in settings, it showed wifi was disabled and when you try and enable it, you just get "error". Seems like &lt;a href="http://www.htcdesireforum.com/htc-desire-troubleshooting/wifi-%27error%27-after-installing-android-2-2/"&gt;other people&lt;/a&gt; have been getting this as well. I tried following their advice, reset the factory defaults but that didn't work. I couldn't get the recovery mode to load (in order to wipe the caches) - after some brief searching it appeared that this was due to root access so I gave up on that.&lt;br /&gt;&lt;b&gt;NOTE: it turns out I was doing it wrong. After selecting the recovery option a red triangle with an exclamation point is show. At which point you need to press volume+ and power to show the next menu.&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Next I tried using latest RUU (2.10) but got &lt;i&gt;Error 170 Usb Connection Error&lt;/i&gt;. &lt;a href="http://androidforums.com/htc-desire/148932-froyo-ruu-update-available.html"&gt;One post&lt;/a&gt; mentions under 'update':&lt;br /&gt;&lt;blockquote&gt;HTC has released a new Froyo OTA update. You can install this directly  as an RUU. You may need the latest version of HTC Sync for this version. &lt;b&gt; There appear to be a lot of issues installing this RUU due to drivers&lt;/b&gt;.  I'd recommend you install the earlier version and update OTA to this  version (you can do this manually too).&lt;/blockquote&gt;&lt;br /&gt;Using 1.21.405.2 gave me &lt;i&gt;ERROR [131] customer id error&lt;/i&gt;. After some poking around, turns out that branded phones don't have a CID... That's what you get with a phone from Hong Kong I guess. However I'm not really sure if that's true...&lt;br /&gt;&lt;br /&gt;Eventually I came across this thread which mentions fixing the wifi error with this update: &lt;a href="http://androidforums.com/htc-desire/177907-froyo-2-09-405-8-update-windows-not-required.html"&gt;Froyo (2.09.405.8) update - Windows not required.&lt;/a&gt; It all installed correctly and after starting it up, it ran through the first-time setup and this time said it detected a wireless network. Success! I didn't try the windows RUU for 2.09 so I'm not sure if that will work.&lt;br /&gt;&lt;br /&gt;Next I downloaded the update manually as per the &lt;a href="http://androidforums.com/htc-desire/174365-2-10-405-2-ota-manual-update.html"&gt;instructions here&lt;/a&gt;. The phone started downloading &lt;a href="http://fotadl.htc.com/OTA_Bravo_HTC_EU_2.10.405.2-2.09.405.8_release567cypyi0feo4th5.zip"&gt;OTA_Bravo_HTC_EU_2.10.405.2-2.09.405.8_release567cypyi0feo4th5.zip&lt;/a&gt; so I'm using that instead of the one in the post.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.htcdesireforum.com/htc-desire-troubleshooting/wifi-%27error%27-after-installing-android-2-2/15/"&gt;This thread&lt;/a&gt; has a better discussion of the problem, with some simple instructions on how to revert and reload when a goldcard isn't needed.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2330120457456880954-8367820743700241109?l=devgrok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devgrok.blogspot.com/feeds/8367820743700241109/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://devgrok.blogspot.com/2010/09/fixing-my-htc-desires-wifi.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/8367820743700241109'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/8367820743700241109'/><link rel='alternate' type='text/html' href='http://devgrok.blogspot.com/2010/09/fixing-my-htc-desires-wifi.html' title='Fixing my HTC Desire&apos;s wifi'/><author><name>Christopher Watts</name><uri>http://www.blogger.com/profile/12923587712192007751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://3.bp.blogspot.com/_qoo3n1eKv3E/Swn9NTUeryI/AAAAAAAAC6A/qESuFc9W1CQ/S220/P9260160.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2330120457456880954.post-508360143400889595</id><published>2010-09-17T15:54:00.002+10:00</published><updated>2011-10-05T11:13:40.180+11:00</updated><title type='text'>Escaping a regex expression</title><content type='html'>I was working on a project where I needed to dynamically generate a regular expression based on some user input but the string to search for needed to be escaped. Below is the quick and dirty way to do it:&lt;br /&gt;&lt;pre class="brush: java"&gt;/**&lt;br /&gt; * Utility function to replace regular expressions.&lt;br /&gt; *&lt;br /&gt; * @param input&lt;br /&gt; * @return&lt;br /&gt; */&lt;br /&gt;private static String escapeRegex(String input)&lt;br /&gt;{&lt;br /&gt;    String special[] = { "\\", "[", "]", "^", "$", ".", "|", "?", "*", "+", "(", ")" };&lt;br /&gt;    String val = input;&lt;br /&gt;    for (String replace : special)&lt;br /&gt;    {&lt;br /&gt;        val = val.replace(replace, "\\" + replace);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    return val;&lt;br /&gt;}&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2330120457456880954-508360143400889595?l=devgrok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devgrok.blogspot.com/feeds/508360143400889595/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://devgrok.blogspot.com/2010/09/escaping-regex-expression.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/508360143400889595'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/508360143400889595'/><link rel='alternate' type='text/html' href='http://devgrok.blogspot.com/2010/09/escaping-regex-expression.html' title='Escaping a regex expression'/><author><name>Christopher Watts</name><uri>http://www.blogger.com/profile/12923587712192007751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://3.bp.blogspot.com/_qoo3n1eKv3E/Swn9NTUeryI/AAAAAAAAC6A/qESuFc9W1CQ/S220/P9260160.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2330120457456880954.post-5634107193881896761</id><published>2010-09-14T17:08:00.003+10:00</published><updated>2010-09-15T00:06:13.644+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JDBC'/><category scheme='http://www.blogger.com/atom/ns#' term='Tomcat'/><title type='text'>Tomcat DBCP: Data source is closed</title><content type='html'>After updating to the latest version of Tomcat I started getting the following error when redeploying a webapp from inside eclipse:&lt;br /&gt;&lt;pre&gt;java.sql.SQLException: Data source is closed&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; at org.apache.tomcat.dbcp.dbcp.BasicDataSource.createDataSource(BasicDataSource.java:1362)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; at org.apache.tomcat.dbcp.dbcp.BasicDataSource.getConnection(BasicDataSource.java:1044)&lt;/pre&gt;&lt;br /&gt;It seemed to be related to an updated version of DBCP that is used inside tomcat (I get Tomcat to manage my datasource). After tracing the code a bit I discovered it was because I called this, in my &lt;code&gt;Filter.destroy()&lt;/code&gt; to do clean up:&lt;br /&gt;&lt;pre class="brush:java"&gt;((BasicDataSource) dataSource).close();&lt;/pre&gt;&lt;br /&gt;Older versions of Tomcat (6.0.26 and below), didn't care if you called it. When the webapp was reloaded, the datasource still worked. But as of 6.0.28, the newer version of DBCP seems to cause problems.&lt;br /&gt;&lt;br /&gt;So if you want to clean up after the webapp, use the removeAbandoned attribute in the &lt;a href="http://tomcat.apache.org/tomcat-7.0-doc/jndi-datasource-examples-howto.html#Preventing_dB_connection_pool_leaks"&gt;Tomcat Configuration&lt;/a&gt; on the datasource, that way DBCP just cleans up after itself.&lt;br /&gt;&lt;br /&gt;NOTE: I'm using the tomcat-dbcp.jar from Tomcat 7 in my Tomcat 6 instance so that I'm able to use the JDBC 4 functionality. Hence the link to the new documentation, &lt;a href="http://tomcat.apache.org/tomcat-6.0-doc/jndi-datasource-examples-howto.html#Preventing_dB_connection_pool_leaks"&gt;Tomcat 6 Configuration&lt;/a&gt; also has it though.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2330120457456880954-5634107193881896761?l=devgrok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devgrok.blogspot.com/feeds/5634107193881896761/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://devgrok.blogspot.com/2010/09/tomcat-dbcp-data-source-is-closed.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/5634107193881896761'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/5634107193881896761'/><link rel='alternate' type='text/html' href='http://devgrok.blogspot.com/2010/09/tomcat-dbcp-data-source-is-closed.html' title='Tomcat DBCP: Data source is closed'/><author><name>Christopher Watts</name><uri>http://www.blogger.com/profile/12923587712192007751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://3.bp.blogspot.com/_qoo3n1eKv3E/Swn9NTUeryI/AAAAAAAAC6A/qESuFc9W1CQ/S220/P9260160.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2330120457456880954.post-7029735091053173664</id><published>2010-09-08T08:15:00.003+10:00</published><updated>2010-09-27T16:40:25.423+10:00</updated><title type='text'>Portable java environments on windows</title><content type='html'>I always seem to be copying my development environment between PCs and latops which end up being time consuming. Its not the size of the data, its the number of small files (mainly javadoc &amp;amp; java source) that slow the whole process down. I already store the source code and workspace for my clients in a &lt;a href="http://www.truecrypt.org/"&gt;TrueCrypt Volume&lt;/a&gt;, to prevent my code being stolen if someone were to get hold of my laptop.&lt;br /&gt;&lt;br /&gt;All the other necessary files I need for development; such as libraries, jdk, tomcat/jboss, elcipse etc; are stored on my hard drive. In some cases on different drive letters on different computers. So to simplify this I wanted to store them in a similar way to a TrueCrypt volume but without the overhead of encryption and the hassle of mounting it. After some poking around I remember that Windows 7 came with built-in support for creating and mounting &lt;a href="http://technet.microsoft.com/en-us/bb738373.aspx"&gt;Virtual Hard Disk (VHD)&lt;/a&gt; straight from the Storage Manager. The VHD are used by Virtual PC. For those running Vista, &lt;a href="http://www.microsoft.com/windows/virtual-pc/support/virtual-pc-2007.aspx"&gt;Virtual PC 2007&lt;/a&gt; should support this.&lt;br /&gt;&lt;br /&gt;For windows 7, you can easily mount an image using the admin interfaces or even create a shourtcut/&lt;a href="http://blogs.msdn.com/b/cschotte/archive/2009/03/09/vhd-mounting-under-windows-7.aspx"&gt;bat script&lt;/a&gt; to mount it. However I wanted the image mounted on start up so it was ready to use. I eventually came across this &lt;a href="http://www.jmedved.com/?page=vhdattach"&gt;neat utility (vhdattach)&lt;/a&gt; to add shell extension to mount an image with the option to mount at startup. Vista has &lt;a href="http://blogs.msdn.com/b/cschotte/archive/2008/03/26/how-to-mount-a-vhd-quickly-under-vista-using-your-mouse.aspx%20"&gt;this alternative&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Now all I need to do to swap PC's is to copy my TrueCrypt volume and my VHD across, mount them on the same letters and done! No need to change paths etc.&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2330120457456880954-7029735091053173664?l=devgrok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devgrok.blogspot.com/feeds/7029735091053173664/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://devgrok.blogspot.com/2010/09/portable-java-environments-on-windows.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/7029735091053173664'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/7029735091053173664'/><link rel='alternate' type='text/html' href='http://devgrok.blogspot.com/2010/09/portable-java-environments-on-windows.html' title='Portable java environments on windows'/><author><name>Christopher Watts</name><uri>http://www.blogger.com/profile/12923587712192007751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://3.bp.blogspot.com/_qoo3n1eKv3E/Swn9NTUeryI/AAAAAAAAC6A/qESuFc9W1CQ/S220/P9260160.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2330120457456880954.post-8329806667478384764</id><published>2010-06-06T11:10:00.000+10:00</published><updated>2011-10-05T11:10:23.236+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JSF'/><category scheme='http://www.blogger.com/atom/ns#' term='Tomcat'/><title type='text'>EL Coerces empty/null to ZERO</title><content type='html'>I recently came across a problem where I was expecting a null value to be populated into one of my JSF managed beans on submit. After digging through the entire stack, I found out this was deliberate.&lt;br /&gt;This bug was introduced into Tomcat 6.0.16, as a consequence of implementing the EL spec to the letter.&lt;br /&gt;The option to disable this change at command line was added in 6.0.17:&lt;br /&gt;&lt;pre&gt;-Dorg.apache.el.parser.COERCE_TO_ZERO=false&lt;/pre&gt;&lt;br /&gt;A &lt;a href="https://issues.apache.org/bugzilla/show_bug.cgi?id=48813"&gt;patch in Tomcat 6.0.24&lt;/a&gt;&amp;nbsp;was added to allow you to change it at run time:&lt;br /&gt;&lt;pre&gt;System.getProperties().put("org.apache.el.parser.COERCE_TO_ZERO", "false");&lt;/pre&gt;&lt;div&gt;&lt;br /&gt;This problem also directly occurs in JSF, as it uses an EL engine as well.&amp;nbsp;There's a&amp;nbsp;&lt;a href="https://javaserverfaces.dev.java.net/issues/show_bug.cgi?id=672"&gt;patch for 1.2_08-b01&lt;/a&gt;&amp;nbsp;but it is happening in 2.0.2. But the above fix seems to work.&lt;/div&gt;&lt;pre&gt;&lt;/pre&gt;&lt;br /&gt;&lt;a href="https://jsp-spec-public.dev.java.net/issues/show_bug.cgi?id=183"&gt;Request to change the JSP Spec&lt;/a&gt;&lt;br /&gt;&lt;blockquote&gt;As per chapter 1.18.2 and 1.18.3 of EL spec, EL coerces null values to non-null&lt;br /&gt;values such as empty String or (Long) 0 or (Boolean) false. This behaviour is in&lt;br /&gt;almost all cases unwanted when the type is not a primitive.&lt;/blockquote&gt;After some more digging also came across this &lt;a href="http://stackoverflow.com/questions/3116517/trinputtext-submitting-value-0-instead-of-null"&gt;discussion at stackoverflow&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2330120457456880954-8329806667478384764?l=devgrok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devgrok.blogspot.com/feeds/8329806667478384764/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://devgrok.blogspot.com/2011/10/el-coerces-emptynull-to-zero.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/8329806667478384764'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/8329806667478384764'/><link rel='alternate' type='text/html' href='http://devgrok.blogspot.com/2011/10/el-coerces-emptynull-to-zero.html' title='EL Coerces empty/null to ZERO'/><author><name>Christopher Watts</name><uri>http://www.blogger.com/profile/12923587712192007751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://3.bp.blogspot.com/_qoo3n1eKv3E/Swn9NTUeryI/AAAAAAAAC6A/qESuFc9W1CQ/S220/P9260160.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2330120457456880954.post-7154077172745888068</id><published>2010-06-01T14:30:00.003+10:00</published><updated>2010-06-01T14:33:20.948+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JSF'/><category scheme='http://www.blogger.com/atom/ns#' term='Tomcat'/><category scheme='http://www.blogger.com/atom/ns#' term='Google Guice'/><title type='text'>A simple way to Inject Guice into JSF (Mojarra)</title><content type='html'>Previously I have been using &lt;a href="http://code.google.com/p/guicesf/"&gt;GuiceSF&lt;/a&gt; to inject the JSF managed beans which extends the Mojarra's implementation of &lt;code&gt;ELResolver&lt;/code&gt; (&lt;code&gt;ManagedBeanELResolver&lt;/code&gt;). This was bit of a hack but it was relatively simple to implement.&lt;br /&gt;In upgrading to newer version of JSF, I had to manually tweak it to keep it in line with the new features in the spec which took a fair amount of debug stepping. So when JSF 2 came out I looked around for a way to do it which still used the implementation's bean creation and handling but also injected it with Guice.&lt;br /&gt;&lt;br /&gt;After digging around in the injection code in Mojarra, I saw how simple it would be to extend the provided Tomcat injection (which injects stuff for the @Resource and @EJB etc annotations).&lt;br /&gt;&lt;br /&gt;This solution first requires the injection provider be specified in web.xml:&lt;br /&gt;&lt;pre class="brush: xml"&gt;&amp;lt;context-param&gt;&lt;br /&gt;   &amp;lt;description&gt;JSF Injection provider&amp;lt;/description&gt;&lt;br /&gt;   &amp;lt;param-name&gt;com.sun.faces.injectionProvider&amp;lt;/param-name&gt;&lt;br /&gt;   &amp;lt;param-value&gt;net.devgrok.jsf.Tomcat6GuiceInjectionProvider&amp;lt;/param-value&gt;&lt;br /&gt;&amp;lt;/context-param&gt;&lt;/pre&gt;&lt;br /&gt;Next extend the Tomcat injector:&lt;pre class="brush: java"&gt;package net.devgrok.jsf;&lt;br /&gt;&lt;br /&gt;import javax.faces.FacesException;&lt;br /&gt;import javax.servlet.ServletContext;&lt;br /&gt;&lt;br /&gt;import org.apache.AnnotationProcessor;&lt;br /&gt;&lt;br /&gt;import com.google.inject.Injector;&lt;br /&gt;import com.sun.faces.spi.InjectionProviderException;&lt;br /&gt;import com.sun.faces.vendor.Tomcat6InjectionProvider;&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt; * Based on {@link com.sun.faces.vendor.Tomcat6InjectionProvider}. Injects using Guice for JSF.&lt;br /&gt; * &lt;br /&gt; * @author Chris Watts&lt;br /&gt; */&lt;br /&gt;public class Tomcat6GuiceInjectionProvider extends Tomcat6InjectionProvider&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt; private ServletContext servletContext;&lt;br /&gt;&lt;br /&gt; public Tomcat6GuiceInjectionProvider(ServletContext servletContext)&lt;br /&gt; {&lt;br /&gt;  super(servletContext);&lt;br /&gt;  this.servletContext = servletContext;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public void inject(Object managedBean) throws InjectionProviderException&lt;br /&gt; {&lt;br /&gt;  try&lt;br /&gt;  {&lt;br /&gt;   getProcessor().processAnnotations(managedBean);&lt;br /&gt;   getInjector().injectMembers(managedBean);&lt;br /&gt;  }&lt;br /&gt;  catch (Exception e)&lt;br /&gt;  {&lt;br /&gt;   throw new InjectionProviderException(e);&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; private AnnotationProcessor getProcessor()&lt;br /&gt; {&lt;br /&gt;  return ((AnnotationProcessor) servletContext.getAttribute(AnnotationProcessor.class.getName()));&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; protected Injector getInjector()&lt;br /&gt; {&lt;br /&gt;  Injector injector = (Injector) servletContext.getAttribute(Injector.class.getName());&lt;br /&gt;  if (injector == null)&lt;br /&gt;   throw new FacesException("Guice injector not found, verify your web.xml file for mapping GuiceContextListener");&lt;br /&gt;  return injector;&lt;br /&gt; }&lt;br /&gt;}&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2330120457456880954-7154077172745888068?l=devgrok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devgrok.blogspot.com/feeds/7154077172745888068/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://devgrok.blogspot.com/2010/06/simple-way-to-inject-guice-into-jsf.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/7154077172745888068'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/7154077172745888068'/><link rel='alternate' type='text/html' href='http://devgrok.blogspot.com/2010/06/simple-way-to-inject-guice-into-jsf.html' title='A simple way to Inject Guice into JSF (Mojarra)'/><author><name>Christopher Watts</name><uri>http://www.blogger.com/profile/12923587712192007751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://3.bp.blogspot.com/_qoo3n1eKv3E/Swn9NTUeryI/AAAAAAAAC6A/qESuFc9W1CQ/S220/P9260160.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2330120457456880954.post-8475537337702872358</id><published>2010-05-11T00:11:00.032+10:00</published><updated>2011-10-05T22:30:45.079+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JSF'/><title type='text'>Converting custom JSF 1 components to JSF 2</title><content type='html'>These are just some&amp;nbsp;observations/tips I made when converting my JSF 1 components to JSF 2.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Simpler .taglib.xml&lt;/h3&gt;The taglib definition changes from &lt;code&gt;mycomponent.tld&lt;/code&gt; to &lt;code&gt;mycomponent.taglib.xml&lt;/code&gt;. The xml inside the new file is similar but with some changes (i.e. &amp;lt;name&amp;gt; becomes &amp;lt;tag-name&amp;gt;). The major simplification is that attributes no longer need to be defined. Just the tag-name and component-type.&lt;br /&gt;&lt;pre class="brush:xml"&gt;&amp;lt;tag&amp;gt;&lt;br /&gt; &amp;lt;name&amp;gt;menuItem&amp;lt;/name&amp;gt;&lt;br /&gt; &amp;lt;tag-class&amp;gt;net.devgrok.component.MenuItemTag&amp;lt;/tag-class&amp;gt;&lt;br /&gt; &amp;lt;body-content&amp;gt;JSP&amp;lt;/body-content&amp;gt;&lt;br /&gt; &amp;lt;attribute&amp;gt;&lt;br /&gt;  &amp;lt;name&amp;gt;value&amp;lt;/name&amp;gt;&lt;br /&gt;  &amp;lt;required&amp;gt;false&amp;lt;/required&amp;gt;&lt;br /&gt;  &amp;lt;deferred-value&amp;gt;&lt;br /&gt;   &amp;lt;type&amp;gt;java.lang.String&amp;lt;/type&amp;gt;&lt;br /&gt;  &amp;lt;/deferred-value&amp;gt;&lt;br /&gt; &amp;lt;/attribute&amp;gt;&lt;br /&gt;&amp;lt;/tag&amp;gt;&lt;/pre&gt;Becomes:&lt;br /&gt;&lt;pre class="brush:xml"&gt;&amp;lt;tag&amp;gt;&lt;br /&gt; &amp;lt;tag-name&amp;gt;menuItem&amp;lt;/tag-name&amp;gt;&lt;br /&gt; &amp;lt;component&amp;gt;&lt;br /&gt;  &amp;lt;component-type&amp;gt;net.devgrok.MenuItem&amp;lt;/component-type&amp;gt;&lt;br /&gt; &amp;lt;/component&amp;gt;&lt;br /&gt;&amp;lt;/tag&amp;gt;&lt;/pre&gt;And the newly created xml file is referenced as a context-param in web.xml (it could just be located under WEB-INF): &lt;br /&gt;&lt;pre class="brush:xml"&gt;&amp;lt;context-param&amp;gt;&lt;br /&gt;   &amp;lt;description&amp;gt;list of facelet libraries&amp;lt;/description&amp;gt;&lt;br /&gt;   &amp;lt;param-name&amp;gt;javax.faces.FACELETS_LIBRARIES&amp;lt;/param-name&amp;gt;&lt;br /&gt;   &amp;lt;param-value&amp;gt;/WEB-INF/classes/META-INF/custom.taglib.xml&amp;lt;/param-value&amp;gt;&lt;br /&gt;&amp;lt;/context-param&amp;gt;&lt;/pre&gt;&lt;br /&gt;&lt;h3&gt;Component Class&lt;/h3&gt;The component class is annotated with: &lt;code&gt;@FacesComponent(value = "value from mycomponent.taglib.xml")&lt;/code&gt;. Then for each property create a setter (I also create a getter) that sets the value as evaluated at the apply request values phase. I use an enum as the key to store attributes against.&lt;pre class="brush:java"&gt;@FacesComponent(value = "net.devgrok.MenuItem")&lt;br /&gt;public class MenuItem extends UIComponentBase {&lt;br /&gt; private enum PropertyKeys {&lt;br /&gt;  value;&lt;br /&gt;  String toString;&lt;br /&gt;&lt;br /&gt;  PropertyKeys(String toString)  {&lt;br /&gt;   this.toString = toString;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  PropertyKeys()  {&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; public void setValue(Object value) {&lt;br /&gt;  getStateHelper().put(PropertyKeys.value, value);&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; public Object getValue()&lt;br /&gt; {&lt;br /&gt;  return getStateHelper().get(PropertyKeys.value);&lt;br /&gt; }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;h3&gt;No need for tag handler&lt;/h3&gt;As facelets is fully integrated into JSF 2 and it is not driven by JSPs, the need to create a class for every component that extends &lt;code&gt;com.sun.facelets.tag.TagHandler or javax.faces.webapp.UIComponentELTag&lt;/code&gt; has been removed. For cases where you need to perform special actions after the values have been populated, create a simple class extending &lt;code&gt;javax.faces.view.facelets.ComponentHandler&lt;/code&gt;. There are some instructions here: &lt;a href="http://weblogs.java.net/blog/edburns/archive/2009/10/15/jsf2-facelet-tag-handlers"&gt;JSF2 Facelet Tag Handlers&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Some problems&lt;/h3&gt;Had some trouble with tag attributes, which I worked around by using the above getter instead of using &lt;code&gt;(String) this.getAttributes().get("name");&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2330120457456880954-8475537337702872358?l=devgrok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devgrok.blogspot.com/feeds/8475537337702872358/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://devgrok.blogspot.com/2010/05/converting-custom-jsf-1-components-to.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/8475537337702872358'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/8475537337702872358'/><link rel='alternate' type='text/html' href='http://devgrok.blogspot.com/2010/05/converting-custom-jsf-1-components-to.html' title='Converting custom JSF 1 components to JSF 2'/><author><name>Christopher Watts</name><uri>http://www.blogger.com/profile/12923587712192007751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://3.bp.blogspot.com/_qoo3n1eKv3E/Swn9NTUeryI/AAAAAAAAC6A/qESuFc9W1CQ/S220/P9260160.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2330120457456880954.post-1845223501697760697</id><published>2010-02-17T15:08:00.001+11:00</published><updated>2010-02-17T15:09:47.778+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='EJB'/><category scheme='http://www.blogger.com/atom/ns#' term='Tomcat'/><title type='text'>ClassNotFoundException destroying a session in Tomcat</title><content type='html'>When a session was being expired (either through a timeout, or via using the Tomcat Manager to manually destroy them) that contained an EJB I was getting a ClassNotFoundException. The stack trace when killing from the manager was:&lt;br /&gt;&lt;pre&gt;java.lang.RuntimeException: Specified calling class, net.devgrok.MyEjbRemote could not be found for WebappClassLoader&lt;br /&gt;  delegate: false&lt;br /&gt;  repositories:&lt;br /&gt;----------&amp;gt; Parent Classloader:&lt;br /&gt;org.apache.catalina.loader.StandardClassLoader@70cb6009&lt;br /&gt;&lt;br /&gt; at org.jboss.ejb3.common.lang.SerializableMethod.getClassFromName(SerializableMethod.java:311)&lt;br /&gt; at org.jboss.ejb3.common.lang.SerializableMethod.getClassType(SerializableMethod.java:282)&lt;br /&gt; at org.jboss.ejb3.common.lang.SerializableMethod.toMethod(SerializableMethod.java:233)&lt;br /&gt; at org.jboss.ejb3.common.lang.SerializableMethod.toMethod(SerializableMethod.java:220)&lt;br /&gt; at org.jboss.ejb3.proxy.impl.handler.session.SessionProxyInvocationHandlerBase.invoke(SessionProxyInvocationHandlerBase.java:182)&lt;br /&gt; at org.jboss.ejb3.proxy.impl.handler.session.SessionProxyInvocationHandlerBase.invoke(SessionProxyInvocationHandlerBase.java:164)&lt;br /&gt; at net.devgrok.JndiRemoteProxyInvocationHandler.invoke(JndiRemoteProxyInvocationHandler.java:55)&lt;br /&gt; at $Proxy15.logout(Unknown Source)&lt;br /&gt; at org.apache.catalina.session.StandardSession.expire(StandardSession.java:702)&lt;br /&gt; at org.apache.catalina.session.StandardSession.expire(StandardSession.java:660)&lt;br /&gt; at org.apache.catalina.session.StandardSession.invalidate(StandardSession.java:1113)&lt;br /&gt; at org.apache.catalina.session.StandardSessionFacade.invalidate(StandardSessionFacade.java:150)&lt;br /&gt; at org.apache.catalina.manager.HTMLManagerServlet.invalidateSessions(HTMLManagerServlet.java:822)&lt;br /&gt; at org.apache.catalina.manager.HTMLManagerServlet.doSessions(HTMLManagerServlet.java:690)&lt;br /&gt; at org.apache.catalina.manager.HTMLManagerServlet.doGet(HTMLManagerServlet.java:128)&lt;br /&gt; at org.apache.catalina.manager.HTMLManagerServlet.doPost(HTMLManagerServlet.java:164)&lt;br /&gt; at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)&lt;br /&gt; at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)&lt;br /&gt; ...&lt;br /&gt; at java.lang.Thread.run(Thread.java:619)&lt;br /&gt;Caused by: java.lang.ClassNotFoundException: net.devgrok.MyEjbRemote&lt;br /&gt; at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1387)&lt;br /&gt; at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1233)&lt;br /&gt; at java.lang.Class.forName0(Native Method)&lt;br /&gt; at java.lang.Class.forName(Class.java:247)&lt;br /&gt; at org.jboss.ejb3.common.classloader.PrimitiveAwareClassLoader.findClass(PrimitiveAwareClassLoader.java:105)&lt;br /&gt; at java.lang.ClassLoader.loadClass(ClassLoader.java:307)&lt;br /&gt; at java.lang.ClassLoader.loadClass(ClassLoader.java:248)&lt;br /&gt; at org.jboss.ejb3.common.lang.SerializableMethod.getClassFromName(SerializableMethod.java:307)&lt;br /&gt; ... 32 more&lt;br /&gt;&lt;/pre&gt;After some investigating I discovered the current thread's ClassLoader was incorrect. So I created a HttpSessionListener to swap the ClassLoader, unload the session and put the ClassLoader back.&lt;br /&gt;&lt;pre class="brush: java"&gt;public class SessionLifecycleEventListener implements HttpSessionListener&lt;br /&gt;{&lt;br /&gt;   private static final Logger log = LoggerFactory.getLogger(SessionLifecycleEventListener.class);&lt;br /&gt;   public void sessionDestroyed(HttpSessionEvent evt)&lt;br /&gt;   {&lt;br /&gt;      HttpSession session = evt.getSession();&lt;br /&gt;      //remember class loader&lt;br /&gt;      ClassLoader currentLoad = Thread.currentThread().getContextClassLoader();&lt;br /&gt;      try&lt;br /&gt;      {&lt;br /&gt;         //set classloader to be the webapp's&lt;br /&gt;         ClassLoader webApp = this.getClass().getClassLoader();&lt;br /&gt;         Thread.currentThread().setContextClassLoader(webApp);&lt;br /&gt;         &lt;br /&gt;         //clear all the session objects now&lt;br /&gt;         Enumeration&amp;lt;String&gt; names = session.getAttributeNames();&lt;br /&gt;         while (names.hasMoreElements())&lt;br /&gt;         {&lt;br /&gt;            String name = names.nextElement();&lt;br /&gt;            session.removeAttribute(name);&lt;br /&gt;         }&lt;br /&gt;      }&lt;br /&gt;      catch (RuntimeException e)&lt;br /&gt;      {&lt;br /&gt;         log.error("closeEjbSession caught exception", e);&lt;br /&gt;      }&lt;br /&gt;      finally&lt;br /&gt;      {&lt;br /&gt;         //restore classloader&lt;br /&gt;         Thread.currentThread().setContextClassLoader(currentLoad);&lt;br /&gt;      }&lt;br /&gt;      &lt;br /&gt;   public void sessionCreated(HttpSessionEvent evt)&lt;br /&gt;   {&lt;br /&gt;   }&lt;br /&gt;}&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2330120457456880954-1845223501697760697?l=devgrok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devgrok.blogspot.com/feeds/1845223501697760697/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://devgrok.blogspot.com/2010/02/classnotfoundexception-destroying.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/1845223501697760697'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/1845223501697760697'/><link rel='alternate' type='text/html' href='http://devgrok.blogspot.com/2010/02/classnotfoundexception-destroying.html' title='ClassNotFoundException destroying a session in Tomcat'/><author><name>Christopher Watts</name><uri>http://www.blogger.com/profile/12923587712192007751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://3.bp.blogspot.com/_qoo3n1eKv3E/Swn9NTUeryI/AAAAAAAAC6A/qESuFc9W1CQ/S220/P9260160.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2330120457456880954.post-5750724933459728564</id><published>2010-02-11T19:27:00.003+11:00</published><updated>2010-02-11T19:30:37.744+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JSF'/><category scheme='http://www.blogger.com/atom/ns#' term='HTML'/><title type='text'>Using RichFaces to give versioned URL's</title><content type='html'>RichFaces has some nice components that can load scripts and styles when placed anywhere in the xhtml page and automatically inserts them into the header at render time. For example a footer could say it requires stylesheet, after you've already defined a header.&lt;br /&gt;&lt;br /&gt;The tags are pretty simple there is the style loader, &lt;a href="http://docs.jboss.org/richfaces/latest_3_3_X/en/devguide/html/a4j_loadStyle.html"&gt;loadStyle&lt;/a&gt;:&lt;br /&gt;&lt;pre class="brush: html"&gt;&amp;lt;afj:loadstyle src="/css/test.css"&amp;gt;&amp;lt;/afj:loadstyle&amp;gt;&lt;/pre&gt;And the script loader, &lt;a href="http://docs.jboss.org/richfaces/latest_3_3_X/en/devguide/html/a4j_loadScript.html"&gt;loadScript&lt;/a&gt;: &lt;br /&gt;&lt;pre class="brush: html"&gt;&amp;lt;afj:loadscript src="/javascript/test.js"&amp;gt;&lt;/pre&gt;&lt;br /&gt;The src can be a path be:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Relative to the current page.&lt;/li&gt;&lt;li&gt;Path relative to the context if starting with a slash.&lt;/li&gt;&lt;li&gt;Or loaded by RichFaces resource framework&lt;br /&gt;Using &lt;i&gt;"resource:///path/to/file"&lt;/i&gt;&lt;/li&gt;&lt;/ol&gt;Now, the problem most web developers always face is that of caching. If you disable caching then the site is slow for the user and your bandwidth is used up. If you enable caching and release a new version, how do you clear the user's and ISP's cache so they can see your changes?&lt;br /&gt;&lt;br /&gt;RichFaces already deals with this by creating virtual URL's for all their resources served (the static javascript files and the generated css files and images). It prepends "afj/g/[version]" to the url's. For example:&lt;br /&gt;&lt;pre class="brush: html"&gt;&amp;lt;script src="/myapp/jsf/a4j/g/3_3_2.SR1jquery.js" type="text/javascript"&amp;gt;&lt;/pre&gt;Where &lt;i&gt;myapp &lt;/i&gt;is the name of the context and I have a mapping to the faces servlet for &lt;i&gt;/jsf/*&lt;/i&gt;. This gets prepended to all resources served through the framework, even ones from your war.&lt;br /&gt;&lt;br /&gt;This neat little feature can be used to version your own deployments, so that after each build a new URL is generated.&lt;br /&gt;&lt;br /&gt;If your using maven its simple.&lt;br /&gt;First add this to your web.xml:&lt;br /&gt;&lt;pre class="brush: xml"&gt;&amp;lt;!-- &lt;br /&gt;  not used, but needs to be set&lt;br /&gt;--&amp;gt;&lt;br /&gt;&amp;lt;context-param&amp;gt;&lt;br /&gt;  &amp;lt;param-name&amp;gt;org.ajax4jsf.RESOURCE_URI_PREFIX&amp;lt;/param-name&amp;gt;&lt;br /&gt;  &amp;lt;param-value&amp;gt;a4j/${project.version}-r${buildNumber}&amp;lt;/param-value&amp;gt;&lt;br /&gt;&amp;lt;/context-param&amp;gt;&lt;br /&gt;&amp;lt;!-- &lt;br /&gt;  the prefix used by richfaces for global cached resources&lt;br /&gt;--&amp;gt;&lt;br /&gt;&amp;lt;context-param&amp;gt;&lt;br /&gt;  &amp;lt;param-name&amp;gt;org.ajax4jsf.GLOBAL_RESOURCE_URI_PREFIX&amp;lt;/param-name&amp;gt;&lt;br /&gt;  &amp;lt;param-value&amp;gt;a4j/g/${project.version}-r${buildNumber}&amp;lt;/param-value&amp;gt;&lt;br /&gt;&amp;lt;/context-param&amp;gt;&lt;br /&gt;&amp;lt;!-- &lt;br /&gt;  the prefix used by richfaces for session cached resources&lt;br /&gt;--&amp;gt;&lt;br /&gt;&amp;lt;context-param&amp;gt;&lt;br /&gt;  &amp;lt;param-name&amp;gt;org.ajax4jsf.SESSION_RESOURCE_URI_PREFIX&amp;lt;/param-name&amp;gt;&lt;br /&gt;  &amp;lt;param-value&amp;gt;a4j/s/${project.version}-r${buildNumber}&amp;lt;/param-value&amp;gt;&lt;br /&gt;&amp;lt;/context-param&amp;gt;&lt;/pre&gt;Next you'll need to add the buildnumber plugin:&lt;br /&gt;&lt;pre class="brush: xml"&gt;&amp;lt;build&amp;gt;&lt;br /&gt;   &amp;lt;plugins&amp;gt;&lt;br /&gt;      &amp;lt;plugin&amp;gt;&lt;br /&gt;         &amp;lt;groupId&amp;gt;org.codehaus.mojo&amp;lt;/groupId&amp;gt;&lt;br /&gt;         &amp;lt;artifactId&amp;gt;buildnumber-maven-plugin&amp;lt;/artifactId&amp;gt;&lt;br /&gt;         &amp;lt;executions&amp;gt;&lt;br /&gt;            &amp;lt;execution&amp;gt;&lt;br /&gt;               &amp;lt;phase&amp;gt;validate&amp;lt;/phase&amp;gt;&lt;br /&gt;               &amp;lt;goals&amp;gt;&lt;br /&gt;                  &amp;lt;goal&amp;gt;create&amp;lt;/goal&amp;gt;&lt;br /&gt;               &amp;lt;/goals&amp;gt;&lt;br /&gt;            &amp;lt;/execution&amp;gt;&lt;br /&gt;         &amp;lt;/executions&amp;gt;&lt;br /&gt;         &amp;lt;configuration&amp;gt;&lt;br /&gt;            &amp;lt;doCheck&amp;gt;false&amp;lt;/doCheck&amp;gt;&lt;br /&gt;            &amp;lt;doUpdate&amp;gt;false&amp;lt;/doUpdate&amp;gt;&lt;br /&gt;         &amp;lt;/configuration&amp;gt;&lt;br /&gt;      &amp;lt;/plugin&amp;gt;&lt;br /&gt;      &amp;lt;plugin&amp;gt;&lt;br /&gt;         &amp;lt;groupId&amp;gt;org.apache.maven.plugins&amp;lt;/groupId&amp;gt;&lt;br /&gt;         &amp;lt;artifactId&amp;gt;maven-war-plugin&amp;lt;/artifactId&amp;gt;&lt;br /&gt;         &amp;lt;configuration&amp;gt;&lt;br /&gt;            &amp;lt;warSourceDirectory&amp;gt;WebContent&amp;lt;/warSourceDirectory&amp;gt;&lt;br /&gt;            &amp;lt;webXml&amp;gt;src/PROD/web.xml&amp;lt;/webXml&amp;gt;&lt;br /&gt;            &amp;lt;filteringDeploymentDescriptors&amp;gt;true&amp;lt;/filteringDeploymentDescriptors&amp;gt;&lt;br /&gt;            &amp;lt;archive&amp;gt;&lt;br /&gt;               &amp;lt;manifest&amp;gt;&lt;br /&gt;                  &amp;lt;addDefaultImplementationEntries&amp;gt;true&amp;lt;/addDefaultImplementationEntries&amp;gt;&lt;br /&gt;               &amp;lt;/manifest&amp;gt;&lt;br /&gt;               &amp;lt;manifestEntries&amp;gt;&lt;br /&gt;                  &amp;lt;Implementation-Build&amp;gt;${buildNumber}&amp;lt;/Implementation-Build&amp;gt;&lt;br /&gt;               &amp;lt;/manifestEntries&amp;gt;&lt;br /&gt;            &amp;lt;/archive&amp;gt;&lt;br /&gt;         &amp;lt;/configuration&amp;gt;&lt;br /&gt;      &amp;lt;/plugin&amp;gt;&lt;br /&gt;&lt;/pre&gt;If your using eclipse to do development then you'll probably want to have 2 web.xml files. One that eclipse can read with the filtering (property subsititution turned off) and one for production builds. &lt;br /&gt;In&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2330120457456880954-5750724933459728564?l=devgrok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devgrok.blogspot.com/feeds/5750724933459728564/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://devgrok.blogspot.com/2010/02/using-richfaces-to-give-versioned-urls.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/5750724933459728564'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/5750724933459728564'/><link rel='alternate' type='text/html' href='http://devgrok.blogspot.com/2010/02/using-richfaces-to-give-versioned-urls.html' title='Using RichFaces to give versioned URL&apos;s'/><author><name>Christopher Watts</name><uri>http://www.blogger.com/profile/12923587712192007751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://3.bp.blogspot.com/_qoo3n1eKv3E/Swn9NTUeryI/AAAAAAAAC6A/qESuFc9W1CQ/S220/P9260160.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2330120457456880954.post-8889943960280972893</id><published>2010-02-04T18:55:00.001+11:00</published><updated>2010-02-04T19:08:27.637+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='HTML'/><title type='text'>Safari removed javascript API</title><content type='html'>In the latest version of Safari (WebKit) they have removed some deprecated javascript API &amp;amp; tags which can cause problems with older code. This is my attempt to keep track of them so I can search through the code and change it to use a newer method.&lt;br /&gt;&lt;br /&gt;Here is a list of what works in Firefox 3 or Internet Explorer but not Safari: &lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;document.[form name]&lt;/i&gt; where&lt;i&gt; [form name] &lt;/i&gt;matches the element &lt;i&gt;&amp;lt;form name='[form name]'&amp;gt;&lt;/i&gt;&lt;br /&gt;&lt;b&gt;Replacement:&lt;/b&gt;Use &lt;i&gt;document.getElementById()&lt;/i&gt; instead&lt;/li&gt;&lt;li&gt;&lt;a href="https://developer.mozilla.org/en/DOM/document.embeds"&gt;document.embeds&lt;/a&gt;&lt;br /&gt;&lt;b&gt;Replacement:&lt;/b&gt;&lt;br /&gt;Use &lt;i&gt;document.getElementById()&lt;/i&gt; instead&lt;/li&gt;&lt;li&gt;Form element's &lt;i&gt;id &lt;/i&gt;defaulted to their &lt;i&gt;name&lt;/i&gt;&lt;br /&gt;&lt;b&gt;Replacement:&lt;/b&gt;&lt;br /&gt;Manually specify the &lt;i&gt;id&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;&amp;lt;applet&amp;gt;&lt;/i&gt; tag&lt;br /&gt;Replacement:&lt;br /&gt;&lt;i&gt;&amp;lt;object&amp;gt;&lt;/i&gt; tag&lt;/li&gt;&lt;/ul&gt;That's it for the moment but I'll keep updating the list as I find them.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2330120457456880954-8889943960280972893?l=devgrok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devgrok.blogspot.com/feeds/8889943960280972893/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://devgrok.blogspot.com/2010/02/safari-removed-javascript-api.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/8889943960280972893'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/8889943960280972893'/><link rel='alternate' type='text/html' href='http://devgrok.blogspot.com/2010/02/safari-removed-javascript-api.html' title='Safari removed javascript API'/><author><name>Christopher Watts</name><uri>http://www.blogger.com/profile/12923587712192007751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://3.bp.blogspot.com/_qoo3n1eKv3E/Swn9NTUeryI/AAAAAAAAC6A/qESuFc9W1CQ/S220/P9260160.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2330120457456880954.post-2493548910632823812</id><published>2010-02-02T00:43:00.003+11:00</published><updated>2010-02-02T00:45:10.091+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JBoss'/><title type='text'>Building your own jbossall-client.jar</title><content type='html'>The newer versions of JBoss (I'm using 5.1.0 GA) very annoyingly have all the client jars split into at least 47 separate jars! Which is a bit rude when you consider the total number of jars they expect you to copy into your tomcat/lib dir is a whopping 93.&lt;br /&gt;&lt;br /&gt;JBoss are declined to make the client jars into a single file again as its meant to make it easier to upgrade... That's arguable but still leaves us with all these files to copy around. After searching the net I've found a rather nice solution which I have adapted below.&lt;br /&gt;The way I use it is as follows. I combine all &lt;code&gt;jboss*.jar&lt;/code&gt; files into a single jar and then copy the additional dependencies.&lt;br /&gt;&lt;br /&gt;Create a directory an empty directory and put the build.xml in it and create a /jboss dir. Copy all jboss &lt;code&gt;jboss*.jar&lt;/code&gt; from &lt;code&gt;jboss-5.1.0.GA/client&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;Create a /build.xml:&lt;br /&gt;&lt;pre class="brush: xml"&gt;&amp;lt;project default="combine"&gt;&lt;br /&gt;   &amp;lt;property name="temp.dir" value="unpacked" /&gt;&lt;br /&gt;   &amp;lt;property name="lib.dir" value="jboss" /&gt;&lt;br /&gt;   &amp;lt;property name="jar.filename" value="jbossall-client.jar" /&gt;&lt;br /&gt;&lt;br /&gt;   &amp;lt;target name="clean"&gt;&lt;br /&gt;      &amp;lt;delete dir="${temp.dir}" quiet="true" /&gt;&lt;br /&gt;      &amp;lt;delete file="${base.dir}/${jar.filename}" quiet="true" /&gt;&lt;br /&gt;   &amp;lt;/target&gt;&lt;br /&gt;   &lt;br /&gt;   &amp;lt;target name="unjar.jar"&gt;&lt;br /&gt;      &amp;lt;unjar dest="${temp.dir}"&gt;&lt;br /&gt;         &amp;lt;patternset&gt;&lt;br /&gt;            &amp;lt;exclude name="META-INF/MANIFEST.MF" /&gt;&lt;br /&gt;         &amp;lt;/patternset&gt;&lt;br /&gt;         &amp;lt;fileset dir="${lib.dir}"&gt;&lt;br /&gt;            &amp;lt;include name="**/*.jar" /&gt;&lt;br /&gt;         &amp;lt;/fileset&gt;&lt;br /&gt;      &amp;lt;/unjar&gt;&lt;br /&gt;   &amp;lt;/target&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;   &amp;lt;target name="combine" depends="unjar.jar"&gt;&lt;br /&gt;      &amp;lt;jar jarfile="${basedir}/${jar.filename}"&lt;br /&gt;         basedir="${temp.dir}" update="true"&lt;br /&gt;         compress="false"&gt;&lt;br /&gt;      &amp;lt;/jar&gt;&lt;br /&gt;   &amp;lt;/target&gt;&lt;br /&gt;&amp;lt;/project&gt;&lt;br /&gt;&lt;/pre&gt;It will extract and recombine the jar files for you.&lt;br /&gt;&lt;br /&gt;The dependencies I also copy across are:&lt;pre&gt;concurrent.jar&lt;br /&gt;ejb3-persistence.jar&lt;br /&gt;hibernate-annotations.jar&lt;br /&gt;javassist.jar&lt;br /&gt;jmx-client.jar&lt;br /&gt;jmx-invoker-adaptor-client.jar&lt;br /&gt;jnp-client.jar&lt;br /&gt;trove.jar&lt;br /&gt;xmlsec.jar&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2330120457456880954-2493548910632823812?l=devgrok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devgrok.blogspot.com/feeds/2493548910632823812/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://devgrok.blogspot.com/2010/02/building-your-own-jbossall-clientjar.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/2493548910632823812'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/2493548910632823812'/><link rel='alternate' type='text/html' href='http://devgrok.blogspot.com/2010/02/building-your-own-jbossall-clientjar.html' title='Building your own jbossall-client.jar'/><author><name>Christopher Watts</name><uri>http://www.blogger.com/profile/12923587712192007751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://3.bp.blogspot.com/_qoo3n1eKv3E/Swn9NTUeryI/AAAAAAAAC6A/qESuFc9W1CQ/S220/P9260160.JPG'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2330120457456880954.post-7861942006619671166</id><published>2010-02-01T15:26:00.001+11:00</published><updated>2010-02-01T15:26:26.538+11:00</updated><title type='text'>Automake unable to detect vendor on RedHat EL5</title><content type='html'>After chasing down some build problems with subversion 1.6.9 on EL5 I was noticing that it was detecting the system as &lt;code&gt;x86_65-unknown-linux-gnu&lt;/code&gt;. Worried that it would cause me later problems I started digging through the &lt;code&gt;configure&lt;/code&gt; script. It lead me to the &lt;code&gt;build/config.guess&lt;/code&gt; script.&lt;br /&gt;After spending too long searching the net and trying to resolve the issue, I just did this:&lt;br /&gt;&lt;pre&gt;subversion-1.6.9&gt;cp /usr/lib/rpm/config.guess ./build/config.guess&lt;/pre&gt;Basically overriding the one that came with the distro with redhat's hack.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2330120457456880954-7861942006619671166?l=devgrok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devgrok.blogspot.com/feeds/7861942006619671166/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://devgrok.blogspot.com/2010/02/automake-unable-to-detect-vendor-on.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/7861942006619671166'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/7861942006619671166'/><link rel='alternate' type='text/html' href='http://devgrok.blogspot.com/2010/02/automake-unable-to-detect-vendor-on.html' title='Automake unable to detect vendor on RedHat EL5'/><author><name>Christopher Watts</name><uri>http://www.blogger.com/profile/12923587712192007751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://3.bp.blogspot.com/_qoo3n1eKv3E/Swn9NTUeryI/AAAAAAAAC6A/qESuFc9W1CQ/S220/P9260160.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2330120457456880954.post-530408403214405450</id><published>2010-01-16T13:07:00.003+11:00</published><updated>2011-10-08T17:07:03.606+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JSF'/><title type='text'>Using a NavigiationHandler to do HTTP/HTTPS switching</title><content type='html'>In a project I was working on, we wanted the log in page and anything to do with payment to be secure using HTTPS, whilst the majority of the site would be unsecure using HTTP. JSF 1.2 doesn't really give you anyway of doing this other than manually&amp;nbsp;specifying&amp;nbsp;the full url for every single link and button on the site. This removes a lot of the&amp;nbsp;flexibility&amp;nbsp;and simplicity of JSF. I came up with a pretty good solution. For any link or action that you know will switch between secure and unsecure, which isn't that hard to know (if you design the site with that in mind), then you configure it to be a redirect. Then you create your own&amp;nbsp;navigation&amp;nbsp;handler which applies rules you create yourself, to determine which parts should be secure or not.&lt;br /&gt;&lt;br /&gt;This is a very simple solution that when a redirect occurs, it checks the path of the destination page (its viewId).&amp;nbsp;If it starts with "/secure" it gives a full HTTPS url and for all others, it gives a full HTTP url. To activate it, have a navigation rule with a redirect. e.g. a login button with a result "userLogin":&lt;br /&gt;&lt;pre class="brush:xml"&gt;&amp;lt;navigation-case&amp;gt;&lt;br /&gt; &amp;lt;from-outcome&amp;gt;userLogin&amp;lt;/from-outcome&amp;gt;&lt;br /&gt; &amp;lt;to-view-id&amp;gt;/secure/login.xhtml&amp;lt;/to-view-id&amp;gt;&lt;br /&gt; &amp;lt;redirect/&amp;gt;&lt;br /&gt;&amp;lt;/navigation-case&amp;gt;&lt;br /&gt;&amp;lt;navigation-case&amp;gt;&lt;br /&gt; &amp;lt;from-outcome&amp;gt;home&amp;lt;/from-outcome&amp;gt;&lt;br /&gt; &amp;lt;to-view-id&amp;gt;/index.xhtml&amp;lt;/to-view-id&amp;gt;&lt;br /&gt; &amp;lt;redirect/&amp;gt;&lt;br /&gt;&amp;lt;/navigation-case&amp;gt;&lt;/pre&gt;Then on successful login return result "home" to redirect back to HTTP.&lt;br /&gt;&lt;br /&gt;Next you'll need to create and configure your own navigation handler. The easiest way is to copy the entire contents of the mojarra NavigationHandlerImpl and change one line. In the handleNavigation function the line &lt;code&gt;String newPath = viewHandler.getActionURL(context, caseStruct.viewId);&lt;/code&gt; is replaced as shown below:&lt;br /&gt;&lt;pre class="brush:java"&gt;public void handleNavigation(FacesContext context, String fromAction, String outcome) {&lt;br /&gt;&lt;br /&gt;   // ...&lt;br /&gt;   &lt;br /&gt;   if (caseStruct != null) {&lt;br /&gt;      ViewHandler viewHandler = Util.getViewHandler(context);&lt;br /&gt;      assert (null != viewHandler);&lt;br /&gt;&lt;br /&gt;      if (caseStruct.navCase.hasRedirect()) {&lt;br /&gt;         // perform a 302 redirect.&lt;br /&gt;         // ---- start change ---&lt;br /&gt;         String newPath = prependSecure(context, viewHandler, caseStruct.viewId);&lt;br /&gt;         // ---- end change -----&lt;br /&gt;         &lt;br /&gt;   //....&lt;br /&gt;}&lt;/pre&gt;Download the full source &lt;a href="https://sites.google.com/site/devgrok/files/NavigationHandlerImpl.java"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Below is the additional code to support to &lt;code&gt;prependSecure&lt;/code&gt; function, that builds up a full url with scheme for the page being redirected to.&lt;br /&gt;&lt;pre class="brush:java"&gt;private static final String SCHEME_HTTP = "http";&lt;br /&gt;private static final String SCHEME_HTTPS = "https";&lt;br /&gt;private static final int HTTPS_DEFAULT_PORT = 443;&lt;br /&gt;private static final int HTTP_DEFAULT_PORT = 80;&lt;br /&gt;private static final String PREFIX_SECURE = "/secure/";&lt;br /&gt;&lt;br /&gt;private String prependSecure(FacesContext context, ViewHandler viewHandler,&lt;br /&gt;      String viewId) {&lt;br /&gt;   boolean isSecure = (viewId != null &amp;&amp; (viewId.startsWith(PREFIX_SECURE)));&lt;br /&gt;&lt;br /&gt;   String prefix = getServerUrlForceScheme(context, isSecure);&lt;br /&gt;&lt;br /&gt;   return prefix + viewHandler.getActionURL(context, viewId);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public static String getServerUrlForceScheme(FacesContext context,&lt;br /&gt;      boolean secure) {&lt;br /&gt;   String scheme;&lt;br /&gt;   int defaultPort;&lt;br /&gt;   if (secure) {&lt;br /&gt;      scheme = SCHEME_HTTPS;&lt;br /&gt;      defaultPort = HTTPS_DEFAULT_PORT;&lt;br /&gt;   } else {&lt;br /&gt;      scheme = SCHEME_HTTP;&lt;br /&gt;      defaultPort = HTTP_DEFAULT_PORT;&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   HttpServletRequest request = (HttpServletRequest) context&lt;br /&gt;         .getExternalContext().getRequest();&lt;br /&gt;&lt;br /&gt;   int port;&lt;br /&gt;   //use current port if known (ideally make this configuration driven)&lt;br /&gt;   if ((!SCHEME_HTTPS.equalsIgnoreCase(request.getScheme()) &amp;&amp; !secure)&lt;br /&gt;         || (!SCHEME_HTTP.equalsIgnoreCase(request.getScheme()) &amp;&amp; secure))&lt;br /&gt;      port = request.getServerPort();&lt;br /&gt;   else&lt;br /&gt;      port = defaultPort;&lt;br /&gt;&lt;br /&gt;   String basePath = scheme + "://" + request.getServerName()&lt;br /&gt;         + (defaultPort == port ? "" : ":" + port);&lt;br /&gt;&lt;br /&gt;   return basePath;&lt;br /&gt;}&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2330120457456880954-530408403214405450?l=devgrok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devgrok.blogspot.com/feeds/530408403214405450/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://devgrok.blogspot.com/2010/01/using-navigiationhandler-to-do.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/530408403214405450'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/530408403214405450'/><link rel='alternate' type='text/html' href='http://devgrok.blogspot.com/2010/01/using-navigiationhandler-to-do.html' title='Using a NavigiationHandler to do HTTP/HTTPS switching'/><author><name>Christopher Watts</name><uri>http://www.blogger.com/profile/12923587712192007751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://3.bp.blogspot.com/_qoo3n1eKv3E/Swn9NTUeryI/AAAAAAAAC6A/qESuFc9W1CQ/S220/P9260160.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2330120457456880954.post-2283307810306629205</id><published>2010-01-12T23:13:00.001+11:00</published><updated>2010-01-12T23:32:41.757+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SQL'/><title type='text'>Updating the nextval of all sequences in PostgreSQL</title><content type='html'>If you've been doing SQL level inserts for testing purposes, then when you go to use the sequences then they will have a nextval that already exists in your table.&lt;br /&gt;&lt;br /&gt;So below is a script which updates the nextval for all fields that were created using bigserial/serial:&lt;br /&gt;&lt;pre class="brush:sql"&gt;/* Updates all the sequences to have a next value of max+1 excluding the list passed */&lt;br /&gt;CREATE OR REPLACE FUNCTION fn_fixsequences(excludes text) RETURNS integer AS&lt;br /&gt;$BODY$&lt;br /&gt;DECLARE&lt;br /&gt;themax BIGINT;&lt;br /&gt;mytables RECORD;&lt;br /&gt;num integer;&lt;br /&gt;BEGIN&lt;br /&gt; num := 0;&lt;br /&gt; FOR mytables IN &lt;br /&gt;  select relname, ns.nspname, a.attname, pg_get_serial_sequence(c.relname, a.attname) as seq&lt;br /&gt;  FROM pg_catalog.pg_attribute a INNER JOIN &lt;br /&gt;   pg_catalog.pg_class c ON c.oid=a.attrelid&lt;br /&gt;    inner join pg_catalog.pg_attrdef d&lt;br /&gt;    on d.adrelid = a.attrelid AND d.adnum = a.attnum AND a.atthasdef&lt;br /&gt;       LEFT JOIN pg_catalog.pg_namespace ns ON ns.oid = c.relnamespace&lt;br /&gt;  WHERE &lt;br /&gt;    pg_catalog.pg_table_is_visible(c.oid)&lt;br /&gt;   and a.attnum &amp;gt; 0 AND NOT a.attisdropped  and atttypid=20&lt;br /&gt;   and relname not like 'pg_%' and relname not like excludes&lt;br /&gt;   and ns.nspname not in ('information_schema', 'pg_catalog')&lt;br /&gt;   and c.relkind='r'&lt;br /&gt;   and not pg_get_serial_sequence(c.relname, a.attname) is null&lt;br /&gt; LOOP&lt;br /&gt;      EXECUTE 'SELECT MAX('||mytables.attname||') FROM '||mytables.nspname||'.'||mytables.relname||';' INTO themax;&lt;br /&gt;      IF (themax is null OR themax &amp;lt; 0) THEN&lt;br /&gt;       themax := 0;&lt;br /&gt;      END IF;&lt;br /&gt;      themax := themax +1;&lt;br /&gt;      EXECUTE 'ALTER SEQUENCE ' || mytables.seq || ' RESTART WITH '||themax;&lt;br /&gt;      num := num + 1;&lt;br /&gt;  END LOOP;&lt;br /&gt; &lt;br /&gt;  RETURN num;&lt;br /&gt; &lt;br /&gt;END;&lt;br /&gt;$BODY$&lt;br /&gt;LANGUAGE 'plpgsql' VOLATILE;&lt;br /&gt;COMMENT ON FUNCTION fn_fixsequences() IS 'Updates all the sequences to have a next value of max+1 excluding the list passed';&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2330120457456880954-2283307810306629205?l=devgrok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devgrok.blogspot.com/feeds/2283307810306629205/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://devgrok.blogspot.com/2010/01/updating-nextval-of-all-sequences-in.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/2283307810306629205'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/2283307810306629205'/><link rel='alternate' type='text/html' href='http://devgrok.blogspot.com/2010/01/updating-nextval-of-all-sequences-in.html' title='Updating the nextval of all sequences in PostgreSQL'/><author><name>Christopher Watts</name><uri>http://www.blogger.com/profile/12923587712192007751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://3.bp.blogspot.com/_qoo3n1eKv3E/Swn9NTUeryI/AAAAAAAAC6A/qESuFc9W1CQ/S220/P9260160.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2330120457456880954.post-1905470045807056583</id><published>2010-01-09T00:09:00.000+11:00</published><updated>2010-01-09T00:09:59.405+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='EJB'/><category scheme='http://www.blogger.com/atom/ns#' term='JBoss'/><title type='text'>Getting JBoss Scheduler working</title><content type='html'>When using the &lt;code&gt;@Service&lt;/code&gt; annotation together with the scheduler has given me no end of trouble so I'd like to share my working configuration.&lt;br /&gt;&lt;br /&gt;It took me a while to get the objectName right. If your not using &lt;code&gt;@Service(objectName='name')&lt;/code&gt; but instead using &lt;code&gt;@Service(name='name')&lt;/code&gt; then the final object name is not the same as what they imply at &lt;a href="http://www.jboss.org/ejb3/docs/reference/build/reference/en/html/jboss_extensions.html"&gt;EJB Extensions Help&lt;/a&gt;.&lt;br /&gt;Instead I'd recommend going into the JMX console of the running server and searching for it manually, listed under 'jboss.j2ee' for the name you've specified AND &lt;b&gt;type=ManagementInterface&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;As well as defining the @Service, you'll also need to define the @Management.&lt;br /&gt;&lt;br /&gt;&lt;pre class="java" name="code"&gt;@Management(SampleServiceMBean.class)&lt;br /&gt;@Service(name = SampleServiceMBean.SERVICE_NAME)&lt;br /&gt;public class SampleServiceMBean implements SampleService&lt;br /&gt;{&lt;br /&gt; public final static String SERVICE_NAME = "SampleServiceMBean";&lt;br /&gt; &lt;br /&gt; public void process(ObjectName name, Date date)&lt;br /&gt; {&lt;br /&gt;  log.info("process {} {}", name, date);&lt;br /&gt; }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Then create a file the appropriate place&lt;br /&gt;e.g. MyEar.ear/MyEjb.jar/META-INF/myscheduler-service.xml:&lt;br /&gt;&lt;br /&gt;&lt;pre class="xml" name="code"&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;&lt;br /&gt;&amp;lt;server&amp;gt;&lt;br /&gt; &amp;lt;mbean code="org.jboss.varia.scheduler.Scheduler" name=":service=MyScheduler"&amp;gt;&lt;br /&gt;  &amp;lt;attribute name="StartAtStartup"&amp;gt;true&amp;lt;/attribute&amp;gt;&lt;br /&gt;  &amp;lt;attribute name="SchedulableMBean"&amp;gt;jboss.j2ee:ear=MyEar.ear,jar=MyEjb.jar,name=SampleServiceMBean,service=EJB3,type=ManagementInterface&amp;lt;/attribute&amp;gt;&lt;br /&gt;  &amp;lt;attribute name="SchedulableMBeanMethod"&amp;gt;process( SCHEDULER_NAME, DATE )&amp;lt;/attribute&amp;gt;&lt;br /&gt;  &amp;lt;attribute name="InitialStartDate"&amp;gt;NOW&amp;lt;/attribute&amp;gt;&lt;br /&gt;  &amp;lt;attribute name="SchedulePeriod"&amp;gt;60000&amp;lt;/attribute&amp;gt;&lt;br /&gt;  &amp;lt;attribute name="InitialRepetitions"&amp;gt;10&amp;lt;/attribute&amp;gt;&lt;br /&gt;  &amp;lt;attribute name="FixedRate"&amp;gt;true&amp;lt;/attribute&amp;gt;&lt;br /&gt;    &amp;lt;depends&amp;gt;&lt;br /&gt;      &amp;lt;mbean code="javax.management.timer.Timer" name="jboss:service=Timer"/&amp;gt;&lt;br /&gt;    &amp;lt;/depends&amp;gt;&lt;br /&gt; &amp;lt;/mbean&amp;gt;&lt;br /&gt;&amp;lt;/server&amp;gt;&amp;nbsp;&lt;/pre&gt;The parameter list threw me off for a while. If you get errors like &lt;code&gt;java.lang.IllegalArgumentException: Unable to find operation processPending(javax.management.ObjectName,java.util.Date)&lt;/code&gt;, the the key is the argument list (obviously).&lt;br /&gt;&lt;br /&gt;Good luck.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2330120457456880954-1905470045807056583?l=devgrok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devgrok.blogspot.com/feeds/1905470045807056583/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://devgrok.blogspot.com/2010/01/getting-jboss-scheduler-working.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/1905470045807056583'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/1905470045807056583'/><link rel='alternate' type='text/html' href='http://devgrok.blogspot.com/2010/01/getting-jboss-scheduler-working.html' title='Getting JBoss Scheduler working'/><author><name>Christopher Watts</name><uri>http://www.blogger.com/profile/12923587712192007751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://3.bp.blogspot.com/_qoo3n1eKv3E/Swn9NTUeryI/AAAAAAAAC6A/qESuFc9W1CQ/S220/P9260160.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2330120457456880954.post-4417608022846544131</id><published>2010-01-07T20:08:00.003+11:00</published><updated>2010-01-07T20:40:48.577+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JSF'/><title type='text'>Disabling RichFaces FacesBeanValidator</title><content type='html'>If you use the rich:ajaxValidator, for example:&lt;br /&gt;&lt;pre name="code" class="html"&gt;&amp;lt;rich:ajaxValidator event="onblur" /&amp;gt;&lt;br /&gt;&lt;/pre&gt;It automatically adds a FacesBeanValidator to the components list of validators. If you don't have javax.validation or Hibernate Validator setup then you'll get the following exception:&lt;br /&gt;&lt;pre&gt;2010-01-07 00:29:19,889 [http-8443-1] WARN  org.richfaces.validator.ObjectValidator - Hibernate Validator could not be instantiated, use stub instead&lt;br /&gt;javax.validation.ValidationException: Unable to find a default provider&lt;br /&gt; at javax.validation.Validation$GenericBootstrapImpl.configure(Validation.java:248)&lt;br /&gt; at javax.validation.Validation.buildDefaultValidatorFactory(Validation.java:115)&lt;br /&gt; at org.richfaces.validator.BeanValidator.&lt;init&gt;(BeanValidator.java:34)&lt;br /&gt; at org.richfaces.validator.ObjectValidator.createInstance(ObjectValidator.java:54)&lt;br /&gt; at org.richfaces.validator.ObjectValidator.getInstance(ObjectValidator.java:85)&lt;br /&gt; at org.richfaces.validator.FacesBeanValidator.validate(FacesBeanValidator.java:103)&lt;br /&gt; at org.richfaces.component.html.HtmlInputText.validateValue(HtmlInputText.java:52)&lt;br /&gt;&lt;/init&gt;&lt;/pre&gt;&lt;br /&gt;The way I'd like to be able to do it is:&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&amp;lt;managed-bean&amp;gt;&lt;br /&gt;  &amp;lt;description&amp;gt;&lt;br /&gt;   Override RichFaces dependance on hibernate validator and validation api. This stops boot up exceptions (errors once).&lt;br /&gt;  &amp;lt;/description&amp;gt;&lt;br /&gt;  &amp;lt;managed-bean-name&amp;gt;org.richfaces.validator.HibernateValidator&amp;lt;/managed-bean-name&amp;gt;&lt;br /&gt;  &amp;lt;managed-bean-class&amp;gt;org.richfaces.validator.NullValidator&amp;lt;/managed-bean-class&amp;gt;&lt;br /&gt;  &amp;lt;managed-bean-scope&amp;gt;application&amp;lt;/managed-bean-scope&amp;gt;&lt;br /&gt; &amp;lt;/managed-bean&amp;gt;&lt;br /&gt;&lt;/pre&gt;However, unless the bean is accessed by an EL expression like #{applicationScope['org.richfaces.validator.HibernateValidator']}, then it won't be instantiated and added to the application map.&lt;br /&gt;&lt;br /&gt;So the only other solution is to set it with code in a ContextListener:&lt;br /&gt;&lt;pre name="code" class="java"&gt;public void contextInitialized(ServletContextEvent event) {&lt;br /&gt;  event.getServletContext().setAttribute(&lt;br /&gt;    org.richfaces.validator.ObjectValidator.VALIDATOR_PARAM, &lt;br /&gt;    new org.richfaces.validator.NullValidator());&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;A bit of work just to hide an exception... And all this because I was chasing a red herring.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2330120457456880954-4417608022846544131?l=devgrok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devgrok.blogspot.com/feeds/4417608022846544131/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://devgrok.blogspot.com/2010/01/disabling-richfaces-facesbeanvalidator.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/4417608022846544131'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/4417608022846544131'/><link rel='alternate' type='text/html' href='http://devgrok.blogspot.com/2010/01/disabling-richfaces-facesbeanvalidator.html' title='Disabling RichFaces FacesBeanValidator'/><author><name>Christopher Watts</name><uri>http://www.blogger.com/profile/12923587712192007751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://3.bp.blogspot.com/_qoo3n1eKv3E/Swn9NTUeryI/AAAAAAAAC6A/qESuFc9W1CQ/S220/P9260160.JPG'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2330120457456880954.post-2363335854764898272</id><published>2009-12-02T11:26:00.030+11:00</published><updated>2010-09-18T18:51:38.873+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JSF'/><title type='text'>Friendly paths to access dynamic JSF content</title><content type='html'>JSF 1 is HTTP POST based and, as such, makes it hard to generate friendly/RESTful URLs that are meaningful to the user. Try to serve something like a content management system (CMS) using JSF and you immediately run into problems. However if you write a custom &lt;a href="http://java.sun.com/javaee/javaserverfaces/1.2/docs/api/javax/faces/application/ViewHandler.html"&gt;ViewHandler&lt;/a&gt;, you can translate the virtual url, such as &lt;code&gt;/page/about/contactUs&lt;/code&gt;, into a physical page (view), e.g. &lt;code&gt;/dynamicContent.xhtml&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;All cases where the ViewHandler references the viewId (which is just the full filename of the page its executing/referencing), need to be mapped correctly so that JSF opens the page that exists, while the user sees the content specified by the URL that maps to a database for example.&lt;br /&gt;&lt;br /&gt;Below is the view handler that wraps around the Facelets view handler to provide the described functionality.:&lt;br /&gt;&lt;pre class="brush:java"&gt;/**&lt;br /&gt; * View Handler that wraps around first Facelets then the default handler, to translate the virtual address of the content page to the physical xhtml&lt;br /&gt; * page that will serve it.&lt;br /&gt; * &lt;br /&gt; * @author Chris Watts&lt;br /&gt; */&lt;br /&gt;public class ParameterisedPathViewHandler extends ViewHandlerWrapper&lt;br /&gt;{&lt;br /&gt;   /** servletmapping for physical page */&lt;br /&gt;   private static final String PAGE_URL = "/dynamicPage.jsf";&lt;br /&gt;   /** physical page file name */&lt;br /&gt;   private static final String PAGE_FILE_NAME = "/dynamicContent.xhtml";&lt;br /&gt;   /** servletmapping prefix for served pages */&lt;br /&gt;   private static final String PAGE_PREFIX = "/page";&lt;br /&gt;   /** richfaces exclusion */&lt;br /&gt;   private static final String A4J_PREFIX = "/page/a4j/";&lt;br /&gt;   private ViewHandler wrappedHandler;&lt;br /&gt;&lt;br /&gt;   /**&lt;br /&gt;    * Constructor taking the previous view handler in the chain (called by JSF implementation).&lt;br /&gt;    * @param defaultHandler previous handler in the chain&lt;br /&gt;    */&lt;br /&gt;   public ParameterisedPathViewHandler(ViewHandler defaultHandler)&lt;br /&gt;   {&lt;br /&gt;      //put facelets in the chain.&lt;br /&gt;      //If using richfaces the context param org.ajax4jsf.VIEW_HANDLERS&lt;br /&gt;      //should be set to: "com.sun.facelets.FaceletViewHandler,net.devgrok.jsf.ParameterisedPathViewHandler"&lt;br /&gt;      //and the below code commented out.&lt;br /&gt;&lt;br /&gt;      FaceletViewHandler faceletHandler = new FaceletViewHandler(defaultHandler);&lt;br /&gt;      this.wrappedHandler = faceletHandler;&lt;br /&gt;//      this.wrappedHandler = defaultHandler; // to use richfaces chaining&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   @Override&lt;br /&gt;   protected ViewHandler getWrapped()&lt;br /&gt;   {&lt;br /&gt;      return wrappedHandler;&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   @Override&lt;br /&gt;   public UIViewRoot createView(FacesContext context, String viewId)&lt;br /&gt;   {&lt;br /&gt;      return wrappedHandler.createView(context, resolveUrl(context, viewId));&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   private boolean isContentPage(FacesContext context, String viewId)&lt;br /&gt;   {&lt;br /&gt;      String servlet = context.getExternalContext().getRequestServletPath();&lt;br /&gt;      if (servlet == null || servlet.length() == 0)&lt;br /&gt;         return false;&lt;br /&gt;      if (servlet.startsWith(A4J_PREFIX))&lt;br /&gt;         return false;&lt;br /&gt;      return servlet.startsWith(PAGE_PREFIX);&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   //Determine what physical page will serve the request.&lt;br /&gt;   private String resolveUrl(FacesContext context, String viewId)&lt;br /&gt;   {&lt;br /&gt;      if (!isContentPage(context, viewId))&lt;br /&gt;         // not content page so use original viewId&lt;br /&gt;         return viewId;&lt;br /&gt;&lt;br /&gt;      //store pageId in request map for later retrieval&lt;br /&gt;      Map&amp;lt;String, Object&amp;gt; requestMap = context.getExternalContext().getRequestMap();&lt;br /&gt;      String pageId;&lt;br /&gt;      //pageId is the document to be served&lt;br /&gt;      pageId = viewId.substring(1);&lt;br /&gt;      requestMap.put("pageId", pageId);&lt;br /&gt;      return PAGE_FILE_NAME;&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   //If is one of the dynamic content pages then actual url of xhtml file to handle it.&lt;br /&gt;   @Override&lt;br /&gt;   public String getActionURL(FacesContext context, String viewId)&lt;br /&gt;   {&lt;br /&gt;      if (isContentPage(context, viewId))&lt;br /&gt;         return getDynamicPageUrl(context, viewId);&lt;br /&gt;      else&lt;br /&gt;         return wrappedHandler.getActionURL(context, viewId);&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   private String getDynamicPageUrl(FacesContext context, String viewId)&lt;br /&gt;   {&lt;br /&gt;      return context.getExternalContext().getRequestContextPath() + PAGE_URL;&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   @Override&lt;br /&gt;   public UIViewRoot restoreView(FacesContext context, String viewId)&lt;br /&gt;   {&lt;br /&gt;      return wrappedHandler.restoreView(context, resolveUrl(context, viewId));&lt;br /&gt;   }&lt;br /&gt;}&lt;/pre&gt;&lt;h2&gt;Resources&lt;/h2&gt;Download the &lt;a href="http://sites.google.com/site/devgrok/files/friendlypaths-src.zip"&gt;source&lt;/a&gt; containing the above class and example usage.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2330120457456880954-2363335854764898272?l=devgrok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devgrok.blogspot.com/feeds/2363335854764898272/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://devgrok.blogspot.com/2009/12/friendly-paths-to-access-dynamic-jsf.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/2363335854764898272'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/2363335854764898272'/><link rel='alternate' type='text/html' href='http://devgrok.blogspot.com/2009/12/friendly-paths-to-access-dynamic-jsf.html' title='Friendly paths to access dynamic JSF content'/><author><name>Christopher Watts</name><uri>http://www.blogger.com/profile/12923587712192007751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://3.bp.blogspot.com/_qoo3n1eKv3E/Swn9NTUeryI/AAAAAAAAC6A/qESuFc9W1CQ/S220/P9260160.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2330120457456880954.post-2001349377618814797</id><published>2009-11-19T13:33:00.002+11:00</published><updated>2010-09-14T22:51:05.826+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tomcat'/><category scheme='http://www.blogger.com/atom/ns#' term='Google Guice'/><title type='text'>Undeploying Google Guice jar file locked</title><content type='html'>When trying to undeploy an webapp that uses Google Guice from an webapp server like Tomcat, you may notice that it doesn't undeploy properly. The problem seems to be related to &lt;code&gt;com.google.inject.internal.Finalizer&lt;/code&gt;, which is a Thread created to clean up after Guice is finished. However the thread doesn't stop properly.&lt;br /&gt;&lt;br /&gt;My solution is to modify this class (by just adding that individual source file to the project as I don't want to rebuild the whole project) adding a stop method that can be call from a &lt;code&gt;ServletContextListener.contextDestroyed()&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;My modified Finializer:&lt;br /&gt;&lt;pre class="brush: java"&gt;private boolean stop = false;&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt; * Loops continuously, pulling references off the queue and cleaning them up.&lt;br /&gt; */&lt;br /&gt;//  @SuppressWarnings("InfiniteLoopStatement")&lt;br /&gt;@Override&lt;br /&gt;public void run() {&lt;br /&gt;  try {&lt;br /&gt;    while (!stop) {&lt;br /&gt;      try {&lt;br /&gt;        cleanUp(queue.remove());&lt;br /&gt;      } catch (InterruptedException e) { /* ignore */ }&lt;br /&gt;    }&lt;br /&gt;  } catch (ShutDown shutDown) { /* ignore */ }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public void stopThread() {&lt;br /&gt;  this.stop = true;&lt;br /&gt;  this.interrupt();&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;Then from listener (in this case I've modified GuiceContextListener from GuiceSF, which seems to have now disappeared but you could write your own from scratch), you need to stop the thread:&lt;br /&gt;&lt;pre class="brush: java"&gt;public class GuiceContextListener implements ServletContextListener {&lt;br /&gt;  public void contextDestroyed(ServletContextEvent contextEvent)&lt;br /&gt;  {&lt;br /&gt;    ServletContext context = contextEvent.getServletContext();&lt;br /&gt;    //start custom code&lt;br /&gt;    &lt;br /&gt;    //first use the GuiceyFruit Injectors class to notify all objects their being destroyed&lt;br /&gt;    try&lt;br /&gt;    {&lt;br /&gt;      Injector injector = getInjector(context);&lt;br /&gt;      Injectors.close(injector);&lt;br /&gt;    }&lt;br /&gt;    catch (CloseFailedException e)&lt;br /&gt;    {&lt;br /&gt;      LOG.log(Level.SEVERE, "Guicesf finhised", e);&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    ThreadGroup root = Thread.currentThread().getThreadGroup().getParent();&lt;br /&gt;    while (root.getParent() != null)&lt;br /&gt;    {&lt;br /&gt;      root = root.getParent();&lt;br /&gt;    }&lt;br /&gt;  &lt;br /&gt;    //now find the thread&lt;br /&gt;    Thread thread = getThread(root, Finalizer.class.getName());&lt;br /&gt;    if (thread == null)&lt;br /&gt;    {&lt;br /&gt;      LOG.log(Level.INFO, "finalizer not found");&lt;br /&gt;    }&lt;br /&gt;    else&lt;br /&gt;    {&lt;br /&gt;      LOG.log(Level.INFO, "Stopping finalizer");&lt;br /&gt;      callMethod(thread, "stopThread");&lt;br /&gt;    }&lt;br /&gt;    //end custom code&lt;br /&gt;    context.removeAttribute(Injector.class.getName());&lt;br /&gt;    LOG.log(Level.INFO, "Guicesf finished");&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  private static Thread getThread(ThreadGroup group, String name)&lt;br /&gt;  {&lt;br /&gt;    int num = group.activeCount();&lt;br /&gt;    Thread[] threads = new Thread[num * 2];&lt;br /&gt;    num = group.enumerate(threads, true);&lt;br /&gt;    for (int i = 0; i &amp;lt; num; i++)&lt;br /&gt;    {&lt;br /&gt;      Thread thread = threads[i];&lt;br /&gt;      if (thread == null)&lt;br /&gt;      {&lt;br /&gt;      }&lt;br /&gt;      else if (thread.getName().equals(name))&lt;br /&gt;      {&lt;br /&gt;        return thread;&lt;br /&gt;      }&lt;br /&gt;    }&lt;br /&gt;    return null;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  private static void callMethod(Object obj, String methodName)&lt;br /&gt;  {&lt;br /&gt;    try&lt;br /&gt;    {&lt;br /&gt;      Class clazz = obj.getClass();&lt;br /&gt;      Method method = clazz.getMethod(methodName, (Class[]) null);&lt;br /&gt;      method.invoke(obj, (Object[]) null);&lt;br /&gt;    }&lt;br /&gt;    catch (Exception e)&lt;br /&gt;    {&lt;br /&gt;      LOG.log(Level.SEVERE, "callMethod caught exception", e);&lt;br /&gt;    }&lt;br /&gt;  }&lt;/pre&gt;&lt;br /&gt;Download the modified source: &lt;a href="http://sites.google.com/site/devgrok/files/undeploy_guice-src.zip"&gt;undeploy_guice-src.zip&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Other people have &lt;a href="http://code.google.com/p/google-guice/issues/detail?id=288"&gt;noticed the problem&lt;/a&gt;, which trace it to problems with FinalizableReferenceQueue. There is an attached patch which resolves the issue of having to manually stop the thread.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2330120457456880954-2001349377618814797?l=devgrok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devgrok.blogspot.com/feeds/2001349377618814797/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://devgrok.blogspot.com/2009/11/undeploying-google-guice-jar-file.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/2001349377618814797'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/2001349377618814797'/><link rel='alternate' type='text/html' href='http://devgrok.blogspot.com/2009/11/undeploying-google-guice-jar-file.html' title='Undeploying Google Guice jar file locked'/><author><name>Christopher Watts</name><uri>http://www.blogger.com/profile/12923587712192007751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://3.bp.blogspot.com/_qoo3n1eKv3E/Swn9NTUeryI/AAAAAAAAC6A/qESuFc9W1CQ/S220/P9260160.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2330120457456880954.post-3673580970382864689</id><published>2009-10-25T01:46:00.006+11:00</published><updated>2009-10-25T02:08:12.772+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JSF'/><category scheme='http://www.blogger.com/atom/ns#' term='Apache Tiles'/><title type='text'>Actions not being called when using 2 view tags</title><content type='html'>I had a problem where a command button's action was not being called on the managed bean.&lt;br /&gt;&lt;br /&gt;When using tiles inside JSF, you may have it set up so that you have a template.jsp and a body.jsp.&lt;br /&gt;The template.jsp, using tiles inserts body.jsp.&lt;br /&gt;&lt;br /&gt;template.jsp defines a &lt;span style="font-weight: bold;"&gt;&amp;lt;f:view&gt;&lt;/span&gt; tag as per normal.&lt;br /&gt;Inside body.jsp, whilst you don't technically need a &lt;span style="font-weight: bold;"&gt;&amp;lt;f:view&gt;&lt;/span&gt; tag, you may get some component (namely &lt;span style="font-weight: bold;"&gt;f:phaseListener&lt;/span&gt;) complaining about not having a view root, so you does it asks and defines the &lt;span style="font-weight: bold;"&gt;&amp;lt;f:view&gt;&lt;/span&gt; at the start of the file.&lt;br /&gt;&lt;br /&gt;You load up the page, everything renders correctly and you click a submit button. The form validation errors appear as normal, so you fill in some values and click submit again.&lt;br /&gt;This time, NOTHING.&lt;br /&gt;So you try turning on all the logging and still nothing seems wrong.&lt;br /&gt;&lt;br /&gt;This happened to me. I wasted quiet a few hours on this one: working out how to log things correctly using eclipse/tomcat and get Java Util Logging working etc. After a ton of breakpoints, it appeared that there were no 'events' cued for the view root to invoke in the &lt;span style="font-style: italic;"&gt;Invoke Application Phase&lt;/span&gt;. Some more breakpoints showed that the button was being decoded and an event was being added to the queue. However it wasn't in the main view root. Strange.&lt;br /&gt;&lt;br /&gt;After some pondering I decided that the problem must be that the included page wasn't sending the events up.&lt;br /&gt;&lt;br /&gt;So the solution:&lt;br /&gt;&lt;span style="font-style: italic;"&gt;When using tiles, inside the included page use &lt;span style="font-weight: bold;"&gt;&amp;lt;f:subview id="'body'"&gt;&lt;/span&gt; not &lt;span style="font-weight: bold;"&gt;&amp;lt;f:view&gt;&lt;/span&gt;.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;However, this means that you can't use a &lt;span style="font-weight: bold;"&gt;&amp;lt;f:phaseListener&gt;&lt;/span&gt; tag in the included page.&lt;br /&gt;&lt;br /&gt;I was using mojarra-1.2_12.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2330120457456880954-3673580970382864689?l=devgrok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devgrok.blogspot.com/feeds/3673580970382864689/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://devgrok.blogspot.com/2009/10/actions-not-being-called-when-using-2.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/3673580970382864689'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/3673580970382864689'/><link rel='alternate' type='text/html' href='http://devgrok.blogspot.com/2009/10/actions-not-being-called-when-using-2.html' title='Actions not being called when using 2 view tags'/><author><name>Christopher Watts</name><uri>http://www.blogger.com/profile/12923587712192007751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://3.bp.blogspot.com/_qoo3n1eKv3E/Swn9NTUeryI/AAAAAAAAC6A/qESuFc9W1CQ/S220/P9260160.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2330120457456880954.post-3848734864451861060</id><published>2009-09-02T08:21:00.004+10:00</published><updated>2010-09-14T00:25:44.646+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JSF'/><title type='text'>Calling JSF actions by URL</title><content type='html'>In JSF 1, there is no provided functionality to invoke an action (by this I mean a java function, not a JSF action invoked by a component). JSF 2 &lt;a href="http://andyschwartz.wordpress.com/2009/07/31/whats-new-in-jsf-2/#get"&gt;adds functionality&lt;/a&gt; to support this, through &lt;a href="https://javaserverfaces.dev.java.net/nonav/docs/2.0/pdldocs/facelets/f/viewParam.html"&gt;f:viewParam&lt;/a&gt; / &lt;a href="https://javaserverfaces.dev.java.net/nonav/docs/2.0/pdldocs/facelets/f/event.html"&gt;f:event&lt;/a&gt; and the &lt;a href="https://javaserverfaces.dev.java.net/nonav/docs/2.0/javadocs/javax/faces/event/PreRenderViewEvent.html"&gt;PreRenderViewEvent&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;However in JSF 1, you can bind a phase listener to a specific page using the &lt;a href="http://download.oracle.com/javaee/5/javaserverfaces/1.2/docs/tlddocs/f/phaseListener.html"&gt;f:phaseListener tag&lt;/a&gt; to call the code before the Render Phase. To make sure that the code is only called when the page is access via the url and not from a postback caused by a component you can use the function added in JSF 1.2:&amp;nbsp;&lt;a href="http://download.oracle.com/javaee/5/api/javax/faces/render/ResponseStateManager.html#isPostback%28javax.faces.context.FacesContext%29"&gt;ResponseStateManager.isPostback(FacesContext context)&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;First off we configure the phase listener in the page (action.xhtml):&lt;br /&gt;&lt;pre&gt;&amp;lt;html xmlns="http://www.w3.org/1999/xhtml"&lt;br /&gt; xmlns:ui="http://java.sun.com/jsf/facelets"&lt;br /&gt; xmlns:f="http://java.sun.com/jsf/core"&amp;gt;&lt;br /&gt;&amp;lt;f:phaselistener binding="#{urlActionBean.listener}" /&amp;gt;&lt;/pre&gt;&lt;br /&gt;Next is the phase listener and action code: &lt;br /&gt;&lt;pre class="brush: java"&gt;public class UrlActionBean&lt;br /&gt;{&lt;br /&gt;   /** value of request paramer somevalue=value */&lt;br /&gt;   @NamedEL("param.somevalue")&lt;br /&gt;   private String someValue;&lt;br /&gt;   &lt;br /&gt;   /**&lt;br /&gt;    * Listener activated on render phase calling when not postback.&lt;br /&gt;    */&lt;br /&gt;   public PhaseListener getListener()&lt;br /&gt;   {&lt;br /&gt;      return new PhaseListener() {&lt;br /&gt;         public void beforePhase(PhaseEvent event)&lt;br /&gt;         {&lt;br /&gt;            //only ever call from a 'GET' request (ie not action pressed).&lt;br /&gt;            if (!isPostBack())&lt;br /&gt;               processAction();&lt;br /&gt;         }&lt;br /&gt;&lt;br /&gt;         public PhaseId getPhaseId()&lt;br /&gt;         {&lt;br /&gt;            return PhaseId.RENDER_RESPONSE;&lt;br /&gt;         }&lt;br /&gt;      &lt;br /&gt;         public void beforePhase(PhaseEvent event)&lt;br /&gt;         {&lt;br /&gt;         }&lt;br /&gt;      };&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   public static boolean isPostBack()&lt;br /&gt;   {&lt;br /&gt;      FacesContext context = FacesContext.getCurrentInstance();&lt;br /&gt;      return context.getRenderKit().getResponseStateManager().isPostback(context);&lt;br /&gt;   }&lt;br /&gt;      &lt;br /&gt;   /**&lt;br /&gt;    * Called after values injected, automatically calls&lt;br /&gt;    */&lt;br /&gt;   public void processAction()&lt;br /&gt;   {&lt;br /&gt;      //only do something if value provided&lt;br /&gt;      if (someValue == null || someValue.length() == 0)&lt;br /&gt;      {&lt;br /&gt;         //ignore&lt;br /&gt;         return;&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;      String forward = null;&lt;br /&gt;      String viewId = WebUtil.viewId();&lt;br /&gt;      // do action based on viewId. This allows the bean to be used by multiple pages.&lt;br /&gt;      // store result of action&lt;br /&gt;      if ("action".equals(viewId))&lt;br /&gt;         forward = doAction();&lt;br /&gt;         &lt;br /&gt;      //forward to page&lt;br /&gt;      if (forward != null)&lt;br /&gt;      {&lt;br /&gt;         redirect(forward);&lt;br /&gt;         return;&lt;br /&gt;      }&lt;br /&gt;   }&lt;br /&gt;   &lt;br /&gt;   /**&lt;br /&gt;    * Causes the navigation handler to switch pages / send redirect.&lt;br /&gt;    * @param outcome page result mapped in faces-config.xml&lt;br /&gt;    */&lt;br /&gt;   public static void redirect(String outcome)&lt;br /&gt;   {&lt;br /&gt;      FacesContext context = FacesContext.getCurrentInstance();&lt;br /&gt;      context.getApplication().getNavigationHandler().handleNavigation(context, null, outcome);&lt;br /&gt;   }   &lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;The listener is a render phase listener, that only calls the action handling when it isn't a postback. The action handling code then checks that the required parameter is supplied and then calls an action based on the viewId. This allows for multiple views to use the same bean, but you could have one bean per url and hence not need this check. The field &lt;code&gt;someValue&lt;/code&gt;, gets injected the request parameter named &lt;code&gt;'somevalue'&lt;/code&gt; and since it is injected the bean needs to be request scoped as the injection only occurs when the bean is first created.&lt;br /&gt;&lt;br /&gt;In this I use the Guice injection of EL expressions &lt;a href="http://devgrok.blogspot.com/2009/07/jsf-injecting-managed-beans-into.html"&gt;described here&lt;/a&gt;, to inject request parameters, however they could be looked up using the ELContext if you can't use this method.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2330120457456880954-3848734864451861060?l=devgrok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devgrok.blogspot.com/feeds/3848734864451861060/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://devgrok.blogspot.com/2009/12/calling-jsf-actions-by-url.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/3848734864451861060'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/3848734864451861060'/><link rel='alternate' type='text/html' href='http://devgrok.blogspot.com/2009/12/calling-jsf-actions-by-url.html' title='Calling JSF actions by URL'/><author><name>Christopher Watts</name><uri>http://www.blogger.com/profile/12923587712192007751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://3.bp.blogspot.com/_qoo3n1eKv3E/Swn9NTUeryI/AAAAAAAAC6A/qESuFc9W1CQ/S220/P9260160.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2330120457456880954.post-8804326918837542059</id><published>2009-08-05T21:19:00.012+10:00</published><updated>2011-10-26T11:00:07.686+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Eclipse'/><title type='text'>Eclipse Plugins</title><content type='html'>After having my elcipse install crashing several times, I thought it a good idea to compile a easily accessible list of plugins I use.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Log4E&lt;/h3&gt;Allows loggers to be added to classes, replaces System.out and printStackTrace etc&lt;br /&gt;Website: &lt;a href="http://log4e.jayefem.de/content/view/3/2/"&gt;http://log4e.jayefem.de/content/view/3/2/&lt;/a&gt;&lt;br /&gt;Update site: &lt;b&gt;http://log4e.jayefem.de/update&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Log4Eclipse&lt;/h3&gt;Log4j socket appender host - allows log4j to send log messages directly to eclipse (no need to inspect log files). I have rebuilt it using log4j 1.2.15 see below.&lt;br /&gt;Website: &lt;a href="http://www.nitwit.de/log4eclipse/"&gt;http://www.nitwit.de/log4eclipse/&lt;/a&gt;&lt;br /&gt;My build: &lt;a href="http://sites.google.com/site/devgrok/files/log4eclipse_0.4.0.jar"&gt;log4eclipse_0.4.0.jar&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Subclipse&lt;/h3&gt;Subversion client&lt;br /&gt;Website: &lt;a href="http://subclipse.tigris.org/"&gt;http://subclipse.tigris.org/&lt;/a&gt;&lt;br /&gt;&lt;b&gt;v1.6&lt;/b&gt; Update site: &lt;b&gt;http://subclipse.tigris.org/update_1.6.&lt;/b&gt;x&lt;br /&gt;&lt;b&gt;v1.8&lt;/b&gt; Update site: &lt;b&gt;http://subclipse.tigris.org/update_1.8.x&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;JBoss Tools&lt;/h3&gt;Tools for JBoss server and JSF/Richfaces/Facelets editors. Plus a lot of others (I just use the richfaces plugin).&lt;br /&gt;Website: &lt;a href="http://www.jboss.org/tools"&gt;http://www.jboss.org/tools&lt;/a&gt;&lt;br /&gt;Update site: http://download.jboss.org/jbosstools/updates/stable/&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;TestNG &lt;/h3&gt;Plugin to allow execution of testNg (and Junit) tests directly from eclipse.&lt;br /&gt;Website: &lt;a href="http://testng.org/"&gt;http://testng.org&lt;/a&gt;&lt;br /&gt;Update site: &lt;b&gt;http://beust.com/eclipse&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;M2Eclipse&lt;/h3&gt;Maven integration with eclipse, I mainly use it as a pom file editor.&lt;br /&gt;Website: &lt;a href="http://m2eclipse.sonatype.org/"&gt;http://m2eclipse.sonatype.org/&lt;/a&gt;&lt;br /&gt;Update site: &lt;b&gt;http://m2eclipse.sonatype.org/sites/m2e&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Html Tidy&lt;/h3&gt;Based on JTidy, an HTML formatter for eclipse because eclipse's xml/html formatter sucks.&lt;br /&gt;Website: &lt;a href="http://eclipsetidy.sourceforge.net/"&gt;http://eclipsetidy.sourceforge.net/&lt;/a&gt;&lt;br /&gt;Download: &lt;a href="http://sourceforge.net/projects/eclipsetidy/files/eclipsetidy/"&gt;Zipped update-site&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;JUtils toString Generator&lt;/h3&gt;Website: &lt;a href="http://eclipse-jutils.sourceforge.net/"&gt;http://eclipse-jutils.sourceforge.net/&lt;/a&gt;&lt;br /&gt;Download: &lt;a href="http://sourceforge.net/projects/eclipse-jutils/files/eclipse-jutils/eclipse-jutils%20plugin%20v3.1/org.adarsh.jutils_3.1.0.zip/download"&gt;Extract into eclipse directory&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;FindBugs&lt;/h3&gt;A useful static code analysis for finding common coding errors.&lt;br /&gt;Website: &lt;a href="http://findbugs.sourceforge.net/"&gt;http://findbugs.sourceforge.net/&lt;/a&gt;&lt;a href="http://eclipsetidy.sourceforge.net/"&gt;&lt;/a&gt;&lt;br /&gt;Update site: &lt;b&gt;http://findbugs.cs.umd.edu/eclipse&lt;/b&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2330120457456880954-8804326918837542059?l=devgrok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devgrok.blogspot.com/feeds/8804326918837542059/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://devgrok.blogspot.com/2009/08/eclipse-plugins.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/8804326918837542059'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/8804326918837542059'/><link rel='alternate' type='text/html' href='http://devgrok.blogspot.com/2009/08/eclipse-plugins.html' title='Eclipse Plugins'/><author><name>Christopher Watts</name><uri>http://www.blogger.com/profile/12923587712192007751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://3.bp.blogspot.com/_qoo3n1eKv3E/Swn9NTUeryI/AAAAAAAAC6A/qESuFc9W1CQ/S220/P9260160.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2330120457456880954.post-6038480887806184052</id><published>2009-07-30T05:11:00.016+10:00</published><updated>2009-11-01T00:00:17.391+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='logging'/><category scheme='http://www.blogger.com/atom/ns#' term='Eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='Tomcat'/><title type='text'>Multiple Log4J instances in a WebApp</title><content type='html'>Many times I've come across the classic problem of different logging instances in an web app server. Most of them involve classloader conflicts:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The webapp has log4j.jar but the webapp has bundled log4j.jar as well and you get errors.&lt;/li&gt;&lt;li&gt;OR you have the log4j.jar in the application server's shared library directory and you have 2 webapps but the configuration conflict - or even just a configuration for the application server itself and one for the webapp.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;I've finally come across a solution for log4j. It involves using a repository selector based on a context, this is fully described here - &lt;a href="http://www.qos.ch/logging/sc.jsp"&gt;Supporting the log4j RepositorySelector in Servlet Containers&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;So the solution to stop conflicts and independently configure each application is this.&lt;br /&gt;First put ALL logging jars in the shared library directory including (&lt;code&gt;log4j.jar, slf4j-api.jar, slf4j-log4j.jar, commons-logging.jar,&lt;/code&gt; etc). This ensures that if they one of the libraries is loaded in the main classloader it can access the other jars.&lt;br /&gt;Next is a little extension for log4j: &lt;a href="http://code.google.com/p/log4j-contrib/"&gt;log4j-contrib&lt;/a&gt;. Put its jar into the shared library as well.&lt;br /&gt;&lt;br /&gt;Next you have to configure each individual app. Add the following to the web.xml (at the top so it is the first called).&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&amp;lt;!-- Use log4j.properties from the classpath --&gt;&lt;br /&gt;&amp;lt;context-param&gt;&lt;br /&gt;&amp;lt;param-name&gt;log4jConfigLocations&amp;lt;/param-name&gt;&lt;br /&gt;&amp;lt;param-value&gt;logj.properties&amp;lt;/param-value&gt;&lt;br /&gt;&amp;lt;/context-param&gt;&lt;br /&gt;&amp;lt;listener&gt;&lt;br /&gt;&amp;lt;listener-class&gt;com.mathieucarbou.log4j.web.ContextLoggingListener&amp;lt;/listener-class&gt;&lt;br /&gt;&amp;lt;/listener&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;If you want to have Tomcat use log4j (not just the apps), then add the following configuration:&lt;br /&gt;&lt;br /&gt;For catalina.bat add somewhere in the file (line 119):&lt;pre&gt;rem JavaUtilLogging to SLF4J required to be on classpath.&lt;br /&gt;set CLASSPATH=%CLASSPATH%;%CATALINA_HOME%\lib\jul-to-slf4j-1.5.6.jar;%CATALINA_HOME%\lib\slf4j-api-1.5.6.jar;%CATALINA_HOME%\lib\slf4j-log4j12-1.5.6.jar;%CATALINA_HOME%\lib\log4j-1.2.15.jar&lt;/pre&gt;&lt;br /&gt;Or under linux, catalina.sh add somewhere appropriate (line 163):&lt;br /&gt;&lt;pre&gt;# JavaUtilLogging to SLF4J required to be on classpath.&lt;br /&gt;CLASSPATH="$CLASSPATH":"$CATALINA_HOME"/lib/jul-to-slf4j-1.5.6.jar:"$CATALINA_HOME"/lib/slf4j-api-1.5.6.jar:"$CATALINA_HOME"/lib/slf4j-log4j12-1.5.6.jar:"$CATALINA_HOME"/lib/log4j-1.2.15.jar&lt;/pre&gt;&lt;br /&gt;Additionally if you put the log4j.properties in somewhere other than CATALINA_HOME/lib then you'll need to add that directory to the classpath. e.g. &lt;pre&gt;rem if you put it in /conf&lt;br /&gt;set CLASSPATH=%CLASSPATH%;%CATALINA_HOME%\conf&lt;/pre&gt;&lt;br /&gt;Now alter conf/logging.properties and replace the entire contents with:&lt;pre&gt;handlers = org.slf4j.bridge.SLF4JBridgeHandler&lt;br /&gt;.handlers = org.slf4j.bridge.SLF4JBridgeHandler&lt;/pre&gt;&lt;br /&gt;And that's it for the command line.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Running it from Eclipse&lt;/h2&gt;Eclipse has a guide how to set it up at &lt;a href="http://wiki.eclipse.org/WTP_Tomcat_FAQ#How_do_I_enable_the_JULI_logging_in_a_Tomcat_5.5_Server_instance.3F"&gt;Enable JULI logging in Eclipse&lt;/a&gt;. To set it up, with the configuration files stored in the workspace under Servers for a server named "Tomcat6-Localhost" add the following to the end of the Server's launch configuration arguments:&lt;br /&gt;&lt;pre&gt;-Dlog4j.configuration="log4j.properties"&lt;br /&gt;-Djava.util.logging.config.file="${workspace_loc:Servers/Tomcat6-Localhost-config/logging.properties}"&lt;br /&gt;-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager&lt;/pre&gt;Copy in logging.properties and log4.properties into the workspace configuration directory as per the command line version.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Note:&lt;/span&gt; the argument &lt;span style="font-style: italic;"&gt;-Dlog4j.configuration&lt;/span&gt;, sets the file name to search for on the Tomcat start up classpath. You CANNOT specify the exact file to load, instead you have to add the folder as a class folder (add external folder in eclipse), in order for it to be located.&lt;br /&gt;&lt;br /&gt;Under the launch configuration classpath, add the following jars/folders:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;jdk:&lt;/span&gt;lib/tools.jar&lt;/li&gt;&lt;li&gt;bin/bootstrap.ja&lt;/li&gt;&lt;li&gt;lib/jul-to-slf4j-1.5.6.jar&lt;/li&gt;&lt;li&gt;lib/slf4j-api-1.5.6.jar&lt;/li&gt;&lt;li&gt;lib/slf4j-log4j12-1.5.6.jar&lt;/li&gt;&lt;li&gt;lib/log4j-1.2.15.jar&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;workspace:&lt;/span&gt;Servers/Tomcat6-Localhost-config&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2330120457456880954-6038480887806184052?l=devgrok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devgrok.blogspot.com/feeds/6038480887806184052/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://devgrok.blogspot.com/2009/07/multiple-log4j-instances-in-webapp.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/6038480887806184052'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/6038480887806184052'/><link rel='alternate' type='text/html' href='http://devgrok.blogspot.com/2009/07/multiple-log4j-instances-in-webapp.html' title='Multiple Log4J instances in a WebApp'/><author><name>Christopher Watts</name><uri>http://www.blogger.com/profile/12923587712192007751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://3.bp.blogspot.com/_qoo3n1eKv3E/Swn9NTUeryI/AAAAAAAAC6A/qESuFc9W1CQ/S220/P9260160.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2330120457456880954.post-1606702270774920256</id><published>2009-07-13T02:08:00.007+10:00</published><updated>2010-10-21T23:40:29.311+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JSF'/><title type='text'>Access Control in JSF using a PhaseListener</title><content type='html'>After doing a quick search of the web, I did not find any nice solutions to implementing access control in JSF. Using a servlet filter mapping seemed inadequate, and there wasn't any obvious place to start.&lt;br /&gt;&lt;br /&gt;I initially tried using a custom NavigationHandler, however that is only used after an action is performed (e.g. &lt;code&gt;#{someBean.action}&lt;/code&gt;), and not for directly accessing a URL (e.g. typing in /test.faces). Some more searching revealed that a PhaseListener was the place to do it. After checking the JSF lifecycles I determined that &lt;code&gt;RESTORE_VIEW&lt;/code&gt; was the correct place to do it - ALL pages go through at least the &lt;code&gt;RESTORE_VIEW&lt;/code&gt; and &lt;code&gt;RENDER_VIEW&lt;/code&gt; phases. &lt;br /&gt;You can check the viewId in the afterPhase (as the view has been loaded in this phase, hence can't check in beforePhase) and redirect using the navigation handler as nesecary.&lt;br /&gt;&lt;br /&gt;Below is my implementation of it. I used a flexible inclusion/exclusion filter so I can make the rules as complex as I want. This implementation determines the highest level required for each URL and checks the current security level and redirects accordingly.&lt;br /&gt;Alternatively, you could check each level inidividually - starting with &lt;code&gt;LOGGED_IN&lt;/code&gt;, checking if the user is logged in and working up.&lt;br /&gt;&lt;pre name="code" class="java"&gt;package devgrok.jsf;&lt;br /&gt;&lt;br /&gt;import static devgrok.jsf.AccessControlPhaseListener.AccessLevel.ADMIN;&lt;br /&gt;import static devgrok.jsf.AccessControlPhaseListener.AccessLevel.LOGGED_IN;&lt;br /&gt;import static devgrok.jsf.AccessControlPhaseListener.AccessLevel.NONE;&lt;br /&gt;&lt;br /&gt;import java.util.ArrayList;&lt;br /&gt;import java.util.HashMap;&lt;br /&gt;import java.util.List;&lt;br /&gt;&lt;br /&gt;import javax.faces.application.FacesMessage;&lt;br /&gt;import javax.faces.context.FacesContext;&lt;br /&gt;import javax.faces.event.PhaseEvent;&lt;br /&gt;import javax.faces.event.PhaseId;&lt;br /&gt;import javax.faces.event.PhaseListener;&lt;br /&gt;import javax.servlet.http.HttpSession;&lt;br /&gt;&lt;br /&gt;import org.slf4j.Logger;&lt;br /&gt;import org.slf4j.LoggerFactory;&lt;br /&gt;&lt;br /&gt;import com.sun.faces.util.MessageFactory;&lt;br /&gt;&lt;br /&gt;import devgrok.jsf.SessionForm;&lt;br /&gt;import devgrok.jsf.UrlFilter;&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt; * Phase Listener that checks the viewId (URL) against a set of filters to determine the required access level. If the&lt;br /&gt; * correct level is not there then redirect.&lt;br /&gt; * &lt;br /&gt; * See {@link UrlFilter} for details on the url matching.&lt;br /&gt; * &lt;br /&gt; * @author Chris Watts 2009&lt;br /&gt; * &lt;br /&gt; */&lt;br /&gt;public class AccessControlPhaseListener implements PhaseListener&lt;br /&gt;{&lt;br /&gt;  /** Logger for this class */&lt;br /&gt;  private static final Logger log = LoggerFactory.getLogger(AccessControlPhaseListener.class);&lt;br /&gt;&lt;br /&gt;  /** */&lt;br /&gt;  private static final long serialVersionUID = 1L;&lt;br /&gt;  private final static String SESSION_BEAN = "sessionBean";&lt;br /&gt;  private final HashMap&amp;lt;AccessLevel, List&amp;lt;UrlFilter&gt;&gt; levelFilters = new HashMap&amp;lt;AccessLevel, List&amp;lt;UrlFilter&gt;&gt;();&lt;br /&gt;&lt;br /&gt;  public enum AccessLevel&lt;br /&gt;  {&lt;br /&gt;    NONE, LOGGED_IN, USER_ACTIVE, ADMIN;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  /**&lt;br /&gt;    * &lt;br /&gt;    */&lt;br /&gt;  public AccessControlPhaseListener()&lt;br /&gt;  {&lt;br /&gt;    initLevels();&lt;br /&gt;    &lt;br /&gt;    requires(LOGGED_IN)&lt;br /&gt;      .include("*")&lt;br /&gt;      .exclude("/index.xhtml")&lt;br /&gt;      .exclude("/login.xhtml")&lt;br /&gt;      .exclude("/user/newUser.xhtml");&lt;br /&gt;&lt;br /&gt;    requires(USER_ACTIVE)&lt;br /&gt;      .include("/user/*")&lt;br /&gt;      .exclude("/user/newUser.xhtml");&lt;br /&gt;&lt;br /&gt;    requires(ADMIN)&lt;br /&gt;      .include("/admin/*");&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  private void initLevels()&lt;br /&gt;  {&lt;br /&gt;    AccessLevel[] levels = AccessLevel.values();&lt;br /&gt;    for (int i = 1; i &amp;lt; levels.length; i++)&lt;br /&gt;    {&lt;br /&gt;      levelFilters.put(levels[i], new ArrayList&amp;lt;UrlFilter&gt;());&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  private UrlFilter requires(AccessLevel level)&lt;br /&gt;  {&lt;br /&gt;    //ALL is default&lt;br /&gt;    if (level == NONE)&lt;br /&gt;      return null;&lt;br /&gt;&lt;br /&gt;    UrlFilter filter = new UrlFilter();&lt;br /&gt;    List&amp;lt;UrlFilter&gt; list = levelFilters.get(level);&lt;br /&gt;    list.add(filter);&lt;br /&gt;    return filter;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  /*&lt;br /&gt;   * (non-Javadoc)&lt;br /&gt;   * &lt;br /&gt;   * @see javax.faces.event.PhaseListener#afterPhase(javax.faces.event.PhaseEvent)&lt;br /&gt;   */&lt;br /&gt;  public void afterPhase(PhaseEvent event)&lt;br /&gt;  {&lt;br /&gt;    try&lt;br /&gt;    {&lt;br /&gt;      //check have correct access&lt;br /&gt;      FacesContext context = event.getFacesContext();&lt;br /&gt;      HttpSession session = (HttpSession) context.getExternalContext().getSession(true);&lt;br /&gt;      SessionForm sessionBean = (SessionForm) session.getAttribute(SESSION_BEAN);&lt;br /&gt;      if (sessionBean == null)&lt;br /&gt;      {&lt;br /&gt;        log.error("Could not obtain instance of sessionBean");&lt;br /&gt;        return;&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;      //can't use this here. only valid at render response phase?&lt;br /&gt;      String viewId = context.getViewRoot().getViewId();&lt;br /&gt;      AccessLevel required = requiredLevel(viewId);&lt;br /&gt;      log.debug("Required level={} for viewId={}", required, viewId);&lt;br /&gt;&lt;br /&gt;      //check if page require access:&lt;br /&gt;      switch (required) {&lt;br /&gt;      case NONE:&lt;br /&gt;        break;&lt;br /&gt;      case LOGGED_IN:&lt;br /&gt;        if (!sessionBean.isLoggedIn())&lt;br /&gt;          redirectLogin(event.getFacesContext(), sessionBean);&lt;br /&gt;        break;&lt;br /&gt;      case USER_ACTIVE:&lt;br /&gt;        if (!sessionBean.isActive())&lt;br /&gt;          redirectActive(event.getFacesContext());&lt;br /&gt;        break;&lt;br /&gt;      case ADMIN:&lt;br /&gt;        if (!sessionBean.isAdmin())&lt;br /&gt;          redirectAdmin(event.getFacesContext());&lt;br /&gt;        break;&lt;br /&gt;      default:&lt;br /&gt;        //error&lt;br /&gt;        log.error("huh?");&lt;br /&gt;        throw new IllegalArgumentException("Not a valid access level");&lt;br /&gt;      }&lt;br /&gt;    }&lt;br /&gt;    catch (Exception e)&lt;br /&gt;    {&lt;br /&gt;      // TODO Auto-generated catch block&lt;br /&gt;      log.error("beforePhase caught exception", e);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  /*&lt;br /&gt;   * (non-Javadoc)&lt;br /&gt;   * &lt;br /&gt;   * @see javax.faces.event.PhaseListener#beforePhase(javax.faces.event.PhaseEvent)&lt;br /&gt;   */&lt;br /&gt;  public void beforePhase(PhaseEvent event)&lt;br /&gt;  {&lt;br /&gt;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  private void redirectLogin(FacesContext context, SessionForm sessionForm)&lt;br /&gt;  {&lt;br /&gt;    //trigger login popup to be shown on render.&lt;br /&gt;    sessionForm.logIn();&lt;br /&gt;    addError(context, "access.loginrequired");&lt;br /&gt;    context.getApplication().getNavigationHandler().handleNavigation(context, null, "index");&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  private void redirectActive(FacesContext context)&lt;br /&gt;  {&lt;br /&gt;    addError(context, "access.activerequired");&lt;br /&gt;    context.getApplication().getNavigationHandler().handleNavigation(context, null, "userActivate");&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  private void redirectAdmin(FacesContext context)&lt;br /&gt;  {&lt;br /&gt;    addError(context, "access.adminrequired");&lt;br /&gt;    context.getApplication().getNavigationHandler().handleNavigation(context, null, "home");&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  /**&lt;br /&gt;   * Add keyed error/message.&lt;br /&gt;   * &lt;br /&gt;   * @param level&lt;br /&gt;   * @param key&lt;br /&gt;   *           message key&lt;br /&gt;   */&lt;br /&gt;  private void addError(FacesContext context, String key)&lt;br /&gt;  {&lt;br /&gt;    FacesMessage fMessage = MessageFactory.getMessage(key);&lt;br /&gt;    if (fMessage != null)&lt;br /&gt;    {&lt;br /&gt;      FacesContext facesContext = FacesContext.getCurrentInstance();&lt;br /&gt;      fMessage.setSeverity(FacesMessage.SEVERITY_ERROR);&lt;br /&gt;      facesContext.addMessage(null, fMessage);&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  /**&lt;br /&gt;   * Checks defined filters for view id, checks starting at the highest level down to NONE.&lt;br /&gt;   * &lt;br /&gt;   * @return the matching level or {@link AccessLevel#NONE} if none matching.&lt;br /&gt;   */&lt;br /&gt;  private AccessLevel requiredLevel(String viewId)&lt;br /&gt;  {&lt;br /&gt;    AccessLevel[] levels = AccessLevel.values();&lt;br /&gt;    for (int i = levels.length - 1; i &gt; 0; i--)&lt;br /&gt;    {&lt;br /&gt;      if (checkLevel(levels[i], viewId))&lt;br /&gt;        return levels[i];&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    return AccessLevel.NONE;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  private boolean checkLevel(AccessLevel level, String viewId)&lt;br /&gt;  {&lt;br /&gt;    return matchUri(levelFilters.get(level), viewId);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  private boolean matchUri(List&amp;lt;UrlFilter&gt; list, String uri)&lt;br /&gt;  {&lt;br /&gt;    for (UrlFilter filter : list)&lt;br /&gt;    {&lt;br /&gt;      if (filter.matches(uri))&lt;br /&gt;        return true;&lt;br /&gt;    }&lt;br /&gt;    return false;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  /*&lt;br /&gt;   * (non-Javadoc)&lt;br /&gt;   * &lt;br /&gt;   * @see javax.faces.event.PhaseListener#getPhaseId()&lt;br /&gt;   */&lt;br /&gt;  public PhaseId getPhaseId()&lt;br /&gt;  {&lt;br /&gt;    //ALL access go through RESTORE_VIEW and RENDER_VIEW (even direct url)&lt;br /&gt;    return PhaseId.RESTORE_VIEW;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;}&lt;/pre&gt;&lt;pre name="code" class="java"&gt;package devgrok.jsf;&lt;br /&gt;&lt;br /&gt;import java.util.ArrayList;&lt;br /&gt;import java.util.regex.Pattern;&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt; * An inclusion/exclusion filterset, similar to ant's fileset but does not support directories in the same style(**,&lt;br /&gt; * etc).&lt;br /&gt; * &lt;br /&gt; * For example:&lt;br /&gt; * &amp;lt;ul&gt;&lt;br /&gt; * &amp;lt;li&gt;/servlet/* matches all urls starting with "/servlet/" e.g. /servlet/this.html&lt;br /&gt; * &amp;lt;li&gt;*.do matches all urls that end in ".do" - e.g. mypage.do&lt;br /&gt; * &amp;lt;li&gt;/servlet/*.do matches all urls starting with "/servlet/" and end in ".do"  - e.g. /servlet/mypage.do&lt;br /&gt; * &amp;lt;/ul&gt;&lt;br /&gt; * &lt;br /&gt; * @author Chris Watts 2009&lt;br /&gt; * &lt;br /&gt; */&lt;br /&gt;public class UrlFilter&lt;br /&gt;{&lt;br /&gt;  private ArrayList&amp;lt;Pattern&gt; include = new ArrayList&amp;lt;Pattern&gt;();&lt;br /&gt;  private ArrayList&amp;lt;Pattern&gt; exclude = new ArrayList&amp;lt;Pattern&gt;();&lt;br /&gt;&lt;br /&gt;  public UrlFilter()&lt;br /&gt;  {&lt;br /&gt;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  /**&lt;br /&gt;   * Include the wildcard(*) built pattern.&lt;br /&gt;   * &lt;br /&gt;   * @param pattern&lt;br /&gt;   * @return&lt;br /&gt;   */&lt;br /&gt;  public UrlFilter include(String pattern)&lt;br /&gt;  {&lt;br /&gt;    include.add(generateExpression(pattern));&lt;br /&gt;    return this;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  /**&lt;br /&gt;   * Exclude the wildcard(*) built pattern.&lt;br /&gt;   * &lt;br /&gt;   * @param pattern&lt;br /&gt;   * @return&lt;br /&gt;   */&lt;br /&gt;  public UrlFilter exclude(String pattern)&lt;br /&gt;  {&lt;br /&gt;    exclude.add(generateExpression(pattern));&lt;br /&gt;    return this;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  /**&lt;br /&gt;   * Checks to see if uri matches at least ONE inclusion filter and doesn't match ANY exclusion filters.&lt;br /&gt;   * &lt;br /&gt;   * @param uri&lt;br /&gt;   * @return&lt;br /&gt;   */&lt;br /&gt;  public boolean matches(String uri)&lt;br /&gt;  {&lt;br /&gt;    boolean match = false;&lt;br /&gt;&lt;br /&gt;    //check inclusions&lt;br /&gt;    for (Pattern pattern : include)&lt;br /&gt;    {&lt;br /&gt;      match = match || pattern.matcher(uri).matches();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    if (!match)&lt;br /&gt;      return false;&lt;br /&gt;&lt;br /&gt;    //check exclusions&lt;br /&gt;    for (Pattern pattern : exclude)&lt;br /&gt;    {&lt;br /&gt;      match = match &amp;&amp; !pattern.matcher(uri).matches();&lt;br /&gt;    }&lt;br /&gt;    return match;&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  /** regular expression special character */&lt;br /&gt;  private static char[] specialChars = { '[', '\\', '^', '$', '.', '|', '?', '*', '+', '(', ')' };&lt;br /&gt;&lt;br /&gt;  /**&lt;br /&gt;   * &lt;br /&gt;   * @param input&lt;br /&gt;   * @return&lt;br /&gt;   */&lt;br /&gt;  private static Pattern generateExpression(String input)&lt;br /&gt;  {&lt;br /&gt;    StringBuilder sb = new StringBuilder();&lt;br /&gt;    for (int i = 0; i &amp;lt; input.length(); i++)&lt;br /&gt;    {&lt;br /&gt;      char letter = input.charAt(i);&lt;br /&gt;      if (letter == '*')&lt;br /&gt;      {&lt;br /&gt;        sb.append(".*");&lt;br /&gt;      }&lt;br /&gt;      else if (contains(specialChars, letter))&lt;br /&gt;      {&lt;br /&gt;        sb.append("\\" + letter);&lt;br /&gt;      }&lt;br /&gt;      else&lt;br /&gt;      {&lt;br /&gt;        sb.append(letter);&lt;br /&gt;      }&lt;br /&gt;    }&lt;br /&gt;    return Pattern.compile(sb.toString());&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  private static boolean contains(char[] array, char value)&lt;br /&gt;  {&lt;br /&gt;    if (array == null || array.length == 0)&lt;br /&gt;    {&lt;br /&gt;      return false;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    for (int i = 0; i &amp;lt; array.length; i++)&lt;br /&gt;    {&lt;br /&gt;      char o = array[i];&lt;br /&gt;      if (o == value)&lt;br /&gt;      {&lt;br /&gt;        return true;&lt;br /&gt;      }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    return false;&lt;br /&gt;  }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;strong&gt;Update 2010/10/21:&lt;/strong&gt; Here is a zip of &lt;a href="https://sites.google.com/site/devgrok/files/access_control-src.zip"&gt;the source&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2330120457456880954-1606702270774920256?l=devgrok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devgrok.blogspot.com/feeds/1606702270774920256/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://devgrok.blogspot.com/2009/07/access-control-using-phaselistener.html#comment-form' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/1606702270774920256'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/1606702270774920256'/><link rel='alternate' type='text/html' href='http://devgrok.blogspot.com/2009/07/access-control-using-phaselistener.html' title='Access Control in JSF using a PhaseListener'/><author><name>Christopher Watts</name><uri>http://www.blogger.com/profile/12923587712192007751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://3.bp.blogspot.com/_qoo3n1eKv3E/Swn9NTUeryI/AAAAAAAAC6A/qESuFc9W1CQ/S220/P9260160.JPG'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2330120457456880954.post-3213560145983601287</id><published>2009-07-13T01:12:00.008+10:00</published><updated>2010-09-18T16:47:51.876+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JSF'/><category scheme='http://www.blogger.com/atom/ns#' term='Google Guice'/><title type='text'>JSF - Injecting Managed Beans into Managed Beans</title><content type='html'>Using Google Guice and JSF with something like &lt;a href="http://code.google.com/p/guicesf/"&gt;GuiceSF&lt;/a&gt; to inject the JSF managed beans (backing beans) gives you a lot of power over the injection. However, by doing so JSF no longer resolves the EL expressions from faces-config.xml and injects them into the managed beans. An easy way around this, and somewhat cleaner, is to create an annotation that is 'bound' to an EL expression. To do so requires the use of &lt;a href="http://code.google.com/p/guiceyfruit/"&gt;GuiceyFruit's&lt;/a&gt; extensions to Guice.&lt;br /&gt;&lt;br /&gt;First create the annotation:&lt;br /&gt;&lt;pre class="brush: java"&gt;import static java.lang.annotation.ElementType.FIELD;&lt;br /&gt;import static java.lang.annotation.ElementType.METHOD;&lt;br /&gt;import static java.lang.annotation.ElementType.PARAMETER;&lt;br /&gt;import static java.lang.annotation.RetentionPolicy.RUNTIME;&lt;br /&gt;&lt;br /&gt;import java.lang.annotation.Retention;&lt;br /&gt;import java.lang.annotation.Target;&lt;br /&gt;&lt;br /&gt;import com.google.inject.BindingAnnotation;&lt;br /&gt;&lt;br /&gt;/** &lt;br /&gt; * Injection by expression language.&lt;br /&gt; * @see com.google.inject.name.Named&lt;br /&gt; */&lt;br /&gt;@BindingAnnotation&lt;br /&gt;@Target( { FIELD, PARAMETER, METHOD })&lt;br /&gt;@Retention(RUNTIME)&lt;br /&gt;public @interface NamedEL&lt;br /&gt;{&lt;br /&gt;   /** expression language (without the #{}). */&lt;br /&gt;   String value();&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;Next you configure the annotation and the provider inside your module:&lt;br /&gt;&lt;pre class="brush: java"&gt;public final class GuiceModule extends GuiceyFruitModule&lt;br /&gt;{&lt;br /&gt;   @Override&lt;br /&gt;   protected void configure()&lt;br /&gt;   {&lt;br /&gt;      bindAnnotationInjector(NamedEL.class, ELProvider.class);&lt;br /&gt;   }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;And finally the provider:&lt;br /&gt;&lt;pre class="brush: java"&gt;public class ELProvider extends AnnotationMemberProviderSupport&amp;lt;NamedEL&amp;gt;&lt;br /&gt;{&lt;br /&gt;   /** Logger for this class */&lt;br /&gt;   private static final Logger log = LoggerFactory.getLogger(ELProvider.class);&lt;br /&gt;&lt;br /&gt;   private Injector injector;&lt;br /&gt;   private FacesContext context;&lt;br /&gt;&lt;br /&gt;   @Inject&lt;br /&gt;   public ELProvider(Injector injector)&lt;br /&gt;   {&lt;br /&gt;      this.injector = injector;&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   public FacesContext getContext()&lt;br /&gt;   {&lt;br /&gt;      return context;&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   @Inject(optional = true)&lt;br /&gt;   public void setContext(FacesContext context)&lt;br /&gt;   {&lt;br /&gt;      this.context = context;&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   public boolean isNullParameterAllowed(NamedEL annotation, Method method, Class&amp;lt;?&amp;gt; parameterType, int parameterIndex)&lt;br /&gt;   {&lt;br /&gt;      return false;&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   protected Object provide(NamedEL resource, Member member, TypeLiteral&amp;lt;?&amp;gt; requiredType, Class&amp;lt;?&amp;gt; memberType, Annotation[] annotations)&lt;br /&gt;   {&lt;br /&gt;      String name = getName(resource, member);&lt;br /&gt;&lt;br /&gt;      Binding&amp;lt;?&amp;gt; binding = Injectors.getBinding(injector, Key.get(requiredType, Names.named(name)));&lt;br /&gt;      if (binding != null)&lt;br /&gt;      {&lt;br /&gt;         return binding.getProvider().get();&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;      try&lt;br /&gt;      {&lt;br /&gt;         if (context == null)&lt;br /&gt;         {&lt;br /&gt;            context = FacesContext.getCurrentInstance();&lt;br /&gt;         }&lt;br /&gt;         return getBean(name, requiredType.getRawType());&lt;br /&gt;      }&lt;br /&gt;      catch (ProvisionException e)&lt;br /&gt;      {&lt;br /&gt;         throw e;&lt;br /&gt;      }&lt;br /&gt;      catch (Exception e)&lt;br /&gt;      {&lt;br /&gt;         throw new ProvisionException("Failed to find name '" + name + "' ExpressionResolver. Cause: " + e, e);&lt;br /&gt;      }&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   String getName(NamedEL resource, Member member)&lt;br /&gt;   {&lt;br /&gt;      String answer = resource.value();&lt;br /&gt;      if (answer == null || answer.length() == 0)&lt;br /&gt;      {&lt;br /&gt;         answer = member.getName();&lt;br /&gt;      }&lt;br /&gt;      if (answer == null || answer.length() == 0)&lt;br /&gt;      {&lt;br /&gt;         throw new IllegalArgumentException("No name defined");&lt;br /&gt;      }&lt;br /&gt;      return answer;&lt;br /&gt;   }&lt;br /&gt;   &lt;br /&gt;   private &amp;lt;T&amp;gt; T getBean(String expr, Class&amp;lt;T&amp;gt; expected)&lt;br /&gt;   {&lt;br /&gt;      try&lt;br /&gt;      {&lt;br /&gt;         Application app = context.getApplication();&lt;br /&gt;         ValueExpression ve = app.getExpressionFactory().createValueExpression(context.getELContext(), "#{" + expr + "}", expected);&lt;br /&gt;         return (T) ve.getValue(context.getELContext());&lt;br /&gt;      }&lt;br /&gt;      catch (RuntimeException e)&lt;br /&gt;      {&lt;br /&gt;         log.error("getBean caught RuntimeException", e);&lt;br /&gt;         throw e;&lt;br /&gt;      }&lt;br /&gt;   }&lt;br /&gt;}&lt;/pre&gt;It uses a custom FacesContext provider bound to &lt;code&gt;ServletScopes.REQUEST&lt;/code&gt; but because its optional it defaults to looking it up the standard JSF way. This allows startup time initialisation of singletons, which occurs outside the request scope.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Usage&lt;/h2&gt;To use it is pretty simple. Say you had a bean called mybean, then the following would inject it during the normal creation time (e.g. when first referencing a session scoped bean).&lt;br /&gt;&lt;pre class="brush: java"&gt;/** managed bean 'mybean' */&lt;br /&gt;@NamedEL("mybean")&lt;br /&gt;private String mybean;&lt;br /&gt;&lt;br /&gt;/** request parameter 'key' */&lt;br /&gt;@NamedEL("param.key")&lt;br /&gt;private String paramKey;&lt;/pre&gt;The second reference is a nifty trick which injects the value of the request parameter 'key'.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Resources&lt;/h2&gt;Guicesf seems to be down so here are my copies of them (slightly modified). &lt;a href="http://sites.google.com/site/devgrok/files/guicesf-0.1.jar"&gt;binary&lt;/a&gt; &lt;a href="http://sites.google.com/site/devgrok/files/guicesf-0.1-sources.jar"&gt;source&lt;/a&gt;&lt;br /&gt;Source for this example: &lt;a href='http://sites.google.com/site/devgrok/files/guice-injection-src.zip'&gt;download source&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2330120457456880954-3213560145983601287?l=devgrok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devgrok.blogspot.com/feeds/3213560145983601287/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://devgrok.blogspot.com/2009/07/jsf-injecting-managed-beans-into.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/3213560145983601287'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/3213560145983601287'/><link rel='alternate' type='text/html' href='http://devgrok.blogspot.com/2009/07/jsf-injecting-managed-beans-into.html' title='JSF - Injecting Managed Beans into Managed Beans'/><author><name>Christopher Watts</name><uri>http://www.blogger.com/profile/12923587712192007751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://3.bp.blogspot.com/_qoo3n1eKv3E/Swn9NTUeryI/AAAAAAAAC6A/qESuFc9W1CQ/S220/P9260160.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2330120457456880954.post-1645660642477422298</id><published>2009-07-08T00:22:00.008+10:00</published><updated>2010-04-21T01:12:28.975+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='EJB'/><title type='text'>EJB3 Stateful Session Beans with ejbCreate</title><content type='html'>I had trouble obtaining a stateful session bean using the EJB3 pattern when trying to pass initial data to it. You can use injection to create instances of stateful beans by simply declaring an instance variable in a bean, for example: &lt;code&gt;@EJB MyStatefulLocal mylocal;&lt;/code&gt;. But this doesn't allow you to pass any data on creation. The answer is to use a EJBLocalHome interface like in EJB2 but it's a bit complicated with all the annotations. The ejbCreate method from EJB2.1 is called create in the local home interface and called whatever you want in the bean itself (as long as it is annotated with &lt;code&gt;@Init&lt;/code&gt; Below is an example. You can download the source here: &lt;a href='http://sites.google.com/site/devgrok/files/ejb3-stateful-create.zip'&gt;download source&lt;/a&gt;.&lt;br /&gt;&lt;pre class="brush: java"&gt;/** Local Interface. Dummy interface to enable us to return the Business interface. */&lt;br /&gt;public interface MyStatefulLocalEjb2 extends EJBLocalObject, MyStatefulLocal &lt;br /&gt;{}&lt;/pre&gt;&lt;br /&gt;&lt;pre class="brush: java"&gt;/** Local Business Interface. Put business method definitions here */&lt;br /&gt;public interface MyStatefulLocal&lt;br /&gt;{}&lt;/pre&gt;&lt;br /&gt;&lt;pre class="brush: java"&gt;/** Define method(s) which create the EJB. Must be of name create&lt;xxx&gt;([optional parameters]), &lt;xxx&gt; can be anything e.g. createMyBean(). */&lt;br /&gt;public interface MyStatefulLocalHome extends EJBLocalHome&lt;br /&gt;{&lt;br /&gt;   public MyStatefulLocalEjb2 create(MyEntity initialData);&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;pre class="brush: java"&gt;/** This is the EJB itself, note that it implements the "Local Business Interface" not the "Local Interface". */&lt;br /&gt;@Stateful&lt;br /&gt;@LocalHome(MyStatefulLocalHome.class)&lt;br /&gt;public class MyStatefulBean implements MyStatefulLocal&lt;br /&gt;{&lt;br /&gt;   /** matches method in {@link MyStatefulLocalHome#create(MyEntity)} */&lt;br /&gt;   @Init&lt;br /&gt;   public void init(MyEntity initialData)&lt;br /&gt;   {&lt;br /&gt;   }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;pre class="brush: java"&gt;/** This shows using it from another session bean or message bean. */&lt;br /&gt;public class SomeBean&lt;br /&gt;{&lt;br /&gt;   @EJB&lt;br /&gt;   private MyStatefulLocalHome home;&lt;br /&gt;&lt;br /&gt;   public void obtainStateful()&lt;br /&gt;   {&lt;br /&gt;      MyEntity initialData = new MyEntity();&lt;br /&gt;      MyStatefulLocal myStateful = home.create(initialData);&lt;br /&gt;   }&lt;br /&gt;}&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2330120457456880954-1645660642477422298?l=devgrok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devgrok.blogspot.com/feeds/1645660642477422298/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://devgrok.blogspot.com/2009/07/ejb3-stateful-session-beans-with.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/1645660642477422298'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/1645660642477422298'/><link rel='alternate' type='text/html' href='http://devgrok.blogspot.com/2009/07/ejb3-stateful-session-beans-with.html' title='EJB3 Stateful Session Beans with ejbCreate'/><author><name>Christopher Watts</name><uri>http://www.blogger.com/profile/12923587712192007751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://3.bp.blogspot.com/_qoo3n1eKv3E/Swn9NTUeryI/AAAAAAAAC6A/qESuFc9W1CQ/S220/P9260160.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2330120457456880954.post-4832906264487017443</id><published>2009-07-02T00:33:00.005+10:00</published><updated>2010-06-01T14:16:29.477+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='EJB'/><category scheme='http://www.blogger.com/atom/ns#' term='Google Guice'/><title type='text'>Reacquiring a Stateful Session Bean on NoSuchEJBException</title><content type='html'>In the current project I'm working on I'm using a Tomcat server connecting to a remote JBoss instance. We're using a Stateful Session Bean (SFSB) to hold the session information for the current user for authentication/access control purposes. The bean is stored in tomcat within the session (within a session-scoped managed bean actually) and generally it works fine.&lt;br /&gt;However, if the bean is destroyed on the server then, as per the EJB specification, an NoSuchEJBException is thrown. This could be handled individually by catching the exception, printing a user friendly message and getting a new instance of the session bean. However, it you've got several method calls across multiple classes, having this try/catch code throughout all the classes bloats the code and just plain looks ugly.&lt;br /&gt;&lt;br /&gt;I wanted a solution where I didn't need to touch the module variable that stored the EJB given to me by jboss - I wanted it to obtain a new instance itself. The reason being, if I have this instance shared across multiple JSF managed beans (some stored in session-scope, some in request), the other classes shouldn't have to know that a new instance of the EJB was obtained.&lt;br /&gt;&lt;br /&gt;The solution is to use a nifty feature of Java reflection API - a Proxy that passes calls to a &lt;code&gt;InvocationHandler&lt;/code&gt; instance that you write. Actually the EJB instance JBoss's context factory provides you is a &lt;code&gt;Proxy&lt;/code&gt; (and the same is true for other app servers), which makes wrapping it even easier. Observe:&lt;br /&gt;First create a class that implements &lt;code&gt;InvocationHandler&lt;/code&gt; and a custom interface we'll use to directly access the handler called &lt;code&gt;StatefulProxy&lt;/code&gt;:&lt;pre name="code" class="java"&gt;package devgrok.proxy;&lt;br /&gt;&lt;br /&gt;import java.io.Serializable;&lt;br /&gt;import java.lang.reflect.InvocationHandler;&lt;br /&gt;import java.lang.reflect.Method;&lt;br /&gt;import java.lang.reflect.Proxy;&lt;br /&gt;&lt;br /&gt;import javax.ejb.NoSuchEJBException;&lt;br /&gt;import javax.naming.Context;&lt;br /&gt;import javax.naming.InitialContext;&lt;br /&gt;import javax.naming.NamingException;&lt;br /&gt;&lt;br /&gt;import org.slf4j.Logger;&lt;br /&gt;import org.slf4j.LoggerFactory;&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt;* Utility wrapper, automatically obtains a new instance of the session bean when the existing instance is lost. Uses&lt;br /&gt;* jndi to obtain new instance.&lt;br /&gt;* @author Chris Watts 2009&lt;br /&gt;*/&lt;br /&gt;public class JndiRemoteProxyInvocationHandler implements InvocationHandler, StatefulProxy, Serializable&lt;br /&gt;{&lt;br /&gt;/** Logger for this class */&lt;br /&gt;private static final Logger log = LoggerFactory.getLogger(JndiRemoteProxyInvocationHandler.class);&lt;br /&gt;&lt;br /&gt;private Proxy remoteBean = null;&lt;br /&gt;private final String jndiName;&lt;br /&gt;&lt;br /&gt;/*&lt;br /&gt;* (non-Javadoc)&lt;br /&gt;* &lt;br /&gt;* @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])&lt;br /&gt;*/&lt;br /&gt;public Object invoke(Object proxy, Method method, Object[] args) throws Throwable&lt;br /&gt;{&lt;br /&gt;if (method.getDeclaringClass().equals(StatefulProxy.class))&lt;br /&gt;return method.invoke(this, args);&lt;br /&gt;&lt;br /&gt;if (remoteBean == null)&lt;br /&gt;getNewInstance();&lt;br /&gt;&lt;br /&gt;try&lt;br /&gt;{&lt;br /&gt;//relay it on to JBoss's handler&lt;br /&gt;InvocationHandler handler = Proxy.getInvocationHandler(remoteBean);&lt;br /&gt;return handler.invoke(remoteBean, method, args);&lt;br /&gt;}&lt;br /&gt;catch (NoSuchEJBException e)&lt;br /&gt;{&lt;br /&gt;log.warn("caught exception {}", e.toString());&lt;br /&gt;remoteBean = null;&lt;br /&gt;throw e;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt;* Constructs the proxy, obtaining the instance from the given jndi name.&lt;br /&gt;* @param jndiName&lt;br /&gt;*/&lt;br /&gt;public JndiRemoteProxyInvocationHandler(String jndiName)&lt;br /&gt;{&lt;br /&gt;this.jndiName = jndiName;&lt;br /&gt;getNewInstance();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt;* Obtains a new instance of the bean from the context.&lt;br /&gt;* @return&lt;br /&gt;*/&lt;br /&gt;public void getNewInstance()&lt;br /&gt;{&lt;br /&gt;try&lt;br /&gt;{&lt;br /&gt;Context context = new InitialContext();&lt;br /&gt;this.remoteBean = (Proxy) context.lookup("java:/comp/env/" + jndiName);&lt;br /&gt;}&lt;br /&gt;catch (NamingException e)&lt;br /&gt;{&lt;br /&gt;log.warn("caught exception {}", e.toString());&lt;br /&gt;throw new RuntimeException(e);&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public Object getRemoteBean()&lt;br /&gt;{&lt;br /&gt;return remoteBean;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public void clearInstance()&lt;br /&gt;{&lt;br /&gt;remoteBean = null;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;Next the interface to provide access to the utility methods:&lt;pre name="code" class="java"&gt;package devgrok.proxy;&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt;* Interface to allow calls to the InvocationHandler for the stateful bean proxy.&lt;br /&gt;* @author Chris Watts 2009&lt;br /&gt;*/&lt;br /&gt;public interface StatefulProxy&amp;lt;T&gt;&lt;br /&gt;{&lt;br /&gt;/**&lt;br /&gt;* Get a new instance of the underlying class.&lt;br /&gt;*/&lt;br /&gt;public void getNewInstance();&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt;* Returns the remote bean.&lt;br /&gt;* &lt;br /&gt;* @return&lt;br /&gt;*/&lt;br /&gt;public T getRemoteBean();&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt;* Clears the stored instance of the bean (useful for logout/cleanup).&lt;br /&gt;*/&lt;br /&gt;public void clearInstance();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;Now all that is left is obtaining an instance. Since I'm using Google Guice I wrote a provider (aka a factory) but you could easily adapt it:&lt;pre name="code" class="java"&gt;package devgrok.proxy;&lt;br /&gt;&lt;br /&gt;import java.lang.reflect.Proxy;&lt;br /&gt;&lt;br /&gt;import com.google.inject.Provider;&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt;* A guice provider, providing a proxied EJB looked up by JNDI.&lt;br /&gt;* @author Chris Watts 2009&lt;br /&gt;*/&lt;br /&gt;public class ProxyProvider&amp;lt;T&gt; implements Provider&amp;lt;T&gt;&lt;br /&gt;{&lt;br /&gt;private final String jndiName;&lt;br /&gt;private final Class&amp;lt;T&gt; clazz;&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt;* @param jndiName&lt;br /&gt;* @param clazz&lt;br /&gt;*/&lt;br /&gt;public ProxyProvider(String jndiName, Class&amp;lt;T&gt; clazz)&lt;br /&gt;{&lt;br /&gt;this.jndiName = jndiName;&lt;br /&gt;this.clazz = clazz;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;/*&lt;br /&gt;* (non-Javadoc)&lt;br /&gt;* &lt;br /&gt;* @see com.google.inject.Provider#get()&lt;br /&gt;*/&lt;br /&gt;public T get()&lt;br /&gt;{&lt;br /&gt;return (T) Proxy.newProxyInstance(clazz.getClassLoader(), new Class[] { clazz, StatefulProxy.class },&lt;br /&gt;new JndiRemoteProxyInvocationHandler(jndiName));&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;}&lt;/pre&gt;To bind it:&lt;pre name="code" class="java"&gt;bind(MySessionRemote.class).toProvider(new ProxyProvider&amp;lt;MySessionRemote&gt;("ejb/myEjb", MySessionRemote.class)).in(ServletScopes.SESSION);&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2330120457456880954-4832906264487017443?l=devgrok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devgrok.blogspot.com/feeds/4832906264487017443/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://devgrok.blogspot.com/2009/07/reacquiring-stateful-session-bean-on.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/4832906264487017443'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/4832906264487017443'/><link rel='alternate' type='text/html' href='http://devgrok.blogspot.com/2009/07/reacquiring-stateful-session-bean-on.html' title='Reacquiring a Stateful Session Bean on NoSuchEJBException'/><author><name>Christopher Watts</name><uri>http://www.blogger.com/profile/12923587712192007751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://3.bp.blogspot.com/_qoo3n1eKv3E/Swn9NTUeryI/AAAAAAAAC6A/qESuFc9W1CQ/S220/P9260160.JPG'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2330120457456880954.post-7338833434808192702</id><published>2009-06-21T20:00:00.003+10:00</published><updated>2010-09-13T22:41:39.975+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='EJB'/><category scheme='http://www.blogger.com/atom/ns#' term='JSF'/><category scheme='http://www.blogger.com/atom/ns#' term='Tomcat'/><title type='text'>Tomcat - load &amp; bind an external naming context</title><content type='html'>In my previous post &lt;a href="http://devgrok.blogspot.com/2009/06/injecting-remote-jboss-ejb-3-beans-into.html"&gt;Injecting JBoss EJB3 beans into Tomcat6&lt;/a&gt;, I used Tomcat's ability to bind EJB's to the local JNDI context by specifying JBoss' NamingContextFactory and the URL to the EJB. However in the process of using it, I discovered a problem with &lt;a href="http://java.sun.com/javaee/5/docs/tutorial/doc/bnbly.html#bnbma"&gt;Stateful Session Beans&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I was getting &lt;code&gt;NoSuchEJBException&lt;/code&gt; - either after a redeploy to JBoss, or calling the &lt;code&gt;@Remove&lt;/code&gt; annotated method on the session bean. A lot of debugging later, I discovered that the cause was that Tomcat was initially storing a ejb ref (&lt;code&gt;org.apache.EjbRef&lt;/code&gt;) in the context and when first accessed it looks up the EJB using the factory and then replaces the reference in the context with the instance of the EJB. Every subsequent lookup in the context returns the same instance.&lt;br /&gt;&lt;br /&gt;This however breaks the JEE5 contract:&lt;br /&gt;&lt;pre class="bz_comment_text"&gt;FROM JSR 220: NOTE: When a stateful session bean is looked up or otherwise&lt;br /&gt;obtained through the explicit JNDI lookup mechanisms, the container must&lt;br /&gt;provide a new stateful session bean instance, as required by the Java EE&lt;br /&gt;specification (Section “Java Naming and Directory Interface (JNDI) Naming&lt;br /&gt;Context” [12]).&lt;br /&gt;&lt;/pre&gt;I initially tried a few hacks to stop Tomcat 6 storing the instance and only keeping the ref, but I was worried about the lag every I required a new instance. Each time it creates a context factory, EJB factory etc to look up the EJB. If you were manually doing the lookup using a custom service locator, you would create a singleton service locator and stores a initial context with the remote app server's details pumped in. Thus everytime you wanted an instance a single call to the existing context would be all that was required.&lt;br /&gt;&lt;br /&gt;My solution I felt was to bind an external context naming tree to the local naming tree. That way you could reference any external object easily on the external context with just a @EJB ref. The resulting patch is located &lt;a href="https://issues.apache.org/bugzilla/show_bug.cgi?id=47396"&gt;here&lt;/a&gt;, it is against Tomcat 6.0.20. You can also download my precompiled binary:&lt;br /&gt;&lt;a href="http://sites.google.com/site/devgrok/files/catalina.jar"&gt;catalina.jar&lt;/a&gt;&lt;br /&gt;And the source:&lt;br /&gt;&lt;a href="http://sites.google.com/site/devgrok/files/apache-tomcat-6.0.20-src-chris.zip"&gt;apache-tomcat-6.0.20-src&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;To use it create a context.xml:&lt;br /&gt;&lt;pre class="xml" name="code"&gt;&amp;lt;Context&amp;gt;&lt;br /&gt;   &amp;lt;!-- Binds the remote context tree starting at myear to local name java:/comp/env/ejb. --&amp;gt;&lt;br /&gt;   &amp;lt;Resource name="ejb" type="javax.naming.Context" factory="org.jnp.interfaces.NamingContextFactory" URL="jnp://apphost:1099/myear"/&amp;gt;&lt;br /&gt;&amp;lt;/Context&amp;gt;&lt;/pre&gt;Next if you want to reference a bean which has a &lt;code&gt;@Stateful(mappedName="myear/myBean")&lt;/code&gt;, using the following in your JSF/contains managed bean: &lt;br /&gt;&lt;pre class="brush: java" name="code"&gt;public class TomcatManagedBean&lt;br /&gt;{&lt;br /&gt;   @EJB(name="ejb/myBean")&lt;br /&gt;   private MyBeanRemote session;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2330120457456880954-7338833434808192702?l=devgrok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devgrok.blogspot.com/feeds/7338833434808192702/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://devgrok.blogspot.com/2009/07/tomcat-load-bind-external-naming.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/7338833434808192702'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/7338833434808192702'/><link rel='alternate' type='text/html' href='http://devgrok.blogspot.com/2009/07/tomcat-load-bind-external-naming.html' title='Tomcat - load &amp; bind an external naming context'/><author><name>Christopher Watts</name><uri>http://www.blogger.com/profile/12923587712192007751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://3.bp.blogspot.com/_qoo3n1eKv3E/Swn9NTUeryI/AAAAAAAAC6A/qESuFc9W1CQ/S220/P9260160.JPG'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2330120457456880954.post-7126170958639458392</id><published>2009-06-18T20:43:00.008+10:00</published><updated>2010-02-02T21:25:47.220+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='EJB'/><category scheme='http://www.blogger.com/atom/ns#' term='JSF'/><category scheme='http://www.blogger.com/atom/ns#' term='Tomcat'/><title type='text'>Injecting JBoss EJB3 beans into Tomcat6</title><content type='html'>Injecting EJB's into a managed bean (a bean spawned by appserver, of a JSF managed bean) inside an application server is simple:&lt;br /&gt;&lt;pre class="java" name="code"&gt;public class AppManagedBean&lt;br /&gt;{&lt;br /&gt;   @EJB(mappedName="ejb/myBean")&lt;br /&gt;   private MyBeanRemote session;&lt;/pre&gt;The container looks up the mapped bean and injects it. Easy.&lt;br /&gt;&lt;br /&gt;However in tomcat it gets a little messy. Tomcat doesn't document how to inject them. It assumes something annotated with &lt;span style="font-weight: bold;"&gt;@EJB&lt;/span&gt; is in the context somewhere and tries to look it up.&lt;br /&gt;It has &lt;a href="http://tomcat.apache.org/tomcat-6.0-doc/jndi-datasource-examples-howto.html"&gt;documented&lt;/a&gt; how to lookup ejb's by defining entries in your context.xml or server.xml. But there isn't anything documented for defining EJB's. Looking at the soure it has support for &lt;span style="font-weight: bold;"&gt;&amp;lt;Ejb/&amp;gt;&lt;/span&gt; references but no real clue on how to configure it. So after stepping through the code I came up with the following soloution:&lt;br /&gt;&lt;br /&gt;My environment is JBoss 5 running remotely (on localhost). A seperate instance of Tomcat 6. In it I have defined a session bean:&lt;br /&gt;&lt;pre class="java" name="code"&gt;@Stateful(mappedName="userSession")&lt;br /&gt;public class UserSessionBean implements UserSessionRemote &lt;/pre&gt;This bean is used by a JSF backing bean (i.e. a managed bean):&lt;br /&gt;&lt;pre class="java" name="code"&gt;public class TomcatManagedBean&lt;br /&gt;{&lt;br /&gt;   @EJB(name="ejb/myBean")&lt;br /&gt;   private MyBeanRemote session;&lt;/pre&gt;In order for this bean to bound to the context, you need to configure Tomcat. There are 2 ways: in the server.xml or in the context.xml&lt;br /&gt;I find that putting it in META-INF/context.xml is the easiest, as it gets reloaded nicely in Eclipse. The name="ejb/myBean" corresponds to the name attribute in the &amp;lt;Ejb/&amp;gt; below. In the URL is the appserver name, port, then the mapped name (it could be myProject/ejb/bean or whatever you feel like) - as long as it matched the mappedName on the EJB.&lt;br /&gt;&lt;pre class="xml" name="code"&gt;&amp;lt;Context&amp;gt;&lt;br /&gt;   &amp;lt;!-- Makes Tomcat manage the ejb for you. --&amp;gt;&lt;br /&gt;   &amp;lt;Ejb name="ejb/myBean" type="Session" factory="org.jnp.interfaces.NamingContextFactory" URL="jnp://localhost:1099/userSession" /&amp;gt;&lt;br /&gt;&amp;lt;/Context&amp;gt;&lt;/pre&gt;&lt;b&gt;Update 2010/02/02:&lt;/b&gt; Correct the mappedName in AppManagedBean&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2330120457456880954-7126170958639458392?l=devgrok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devgrok.blogspot.com/feeds/7126170958639458392/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://devgrok.blogspot.com/2009/06/injecting-remote-jboss-ejb-3-beans-into.html#comment-form' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/7126170958639458392'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/7126170958639458392'/><link rel='alternate' type='text/html' href='http://devgrok.blogspot.com/2009/06/injecting-remote-jboss-ejb-3-beans-into.html' title='Injecting JBoss EJB3 beans into Tomcat6'/><author><name>Christopher Watts</name><uri>http://www.blogger.com/profile/12923587712192007751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://3.bp.blogspot.com/_qoo3n1eKv3E/Swn9NTUeryI/AAAAAAAAC6A/qESuFc9W1CQ/S220/P9260160.JPG'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2330120457456880954.post-3073580900270709509</id><published>2009-06-14T02:01:00.002+10:00</published><updated>2009-07-08T00:54:23.518+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Eclipse'/><title type='text'>Change user name in eclipse</title><content type='html'>The code comment templates are handy for inserting the author of a class, which is handy in rather large projects. For example, here is my template for types(classes):&lt;pre name="code" class="java"&gt;/**&lt;br /&gt; * @author ${user}&lt;br /&gt; *&lt;br /&gt; * ${tags}&lt;br /&gt; */&lt;/pre&gt;&lt;br /&gt;However under windows (and probably *nix as well) it just inserts the current user name. But I want it always to display my real name - which is more meaningful when employees come and go.&lt;br /&gt;&lt;br /&gt;You can change it by passing this argument on the comment line:&lt;br /&gt;You need to put it at the end of your command line.&lt;br /&gt;&lt;code&gt;eclipse.exe -vmargs -Duser.name="You real name"&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2330120457456880954-3073580900270709509?l=devgrok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devgrok.blogspot.com/feeds/3073580900270709509/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://devgrok.blogspot.com/2009/06/change-user-name-in-eclipse.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/3073580900270709509'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/3073580900270709509'/><link rel='alternate' type='text/html' href='http://devgrok.blogspot.com/2009/06/change-user-name-in-eclipse.html' title='Change user name in eclipse'/><author><name>Christopher Watts</name><uri>http://www.blogger.com/profile/12923587712192007751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://3.bp.blogspot.com/_qoo3n1eKv3E/Swn9NTUeryI/AAAAAAAAC6A/qESuFc9W1CQ/S220/P9260160.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2330120457456880954.post-6514977621176060319</id><published>2009-06-12T21:06:00.005+10:00</published><updated>2009-07-08T00:50:25.253+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='EJB'/><category scheme='http://www.blogger.com/atom/ns#' term='Google Guice'/><title type='text'>A few good Guice Tutorials</title><content type='html'>I came across these rather good Guice tutorials in trying to find a way to integrate Google Guice in an application server (EJB3).&lt;br /&gt;&lt;br /&gt;&lt;a href="http://musingsofaprogrammingaddict.blogspot.com/2008/12/from-0-to-guice-in-15-minutes.html"&gt;Part 1: a quick intro&lt;/a&gt;.&lt;br /&gt;&lt;a href="http://musingsofaprogrammingaddict.blogspot.com/2009/01/guice-tutorial-part-2-method.html"&gt;Part 2: method interceptors&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;This was the tricky one, how to inject EJB's which are created by the container without having to have every class extend a base class with a @PostConstruct annotated method to do the injecting. The solution was to use the new interceptors introduced into JEE 5.&lt;br /&gt;&lt;a href="http://musingsofaprogrammingaddict.blogspot.com/2009/03/guice-tutorial-part-3-integrating-guice.html"&gt;Part 3 – Integrating Guice with EJB&lt;/a&gt;&lt;br /&gt;If you want a little background, see &lt;a href="http://docs.jboss.org/ejb3/app-server/tutorial/interceptor/interceptor.html"&gt;EJB Interceptors&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2330120457456880954-6514977621176060319?l=devgrok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devgrok.blogspot.com/feeds/6514977621176060319/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://devgrok.blogspot.com/2009/06/few-good-guice-tutorials.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/6514977621176060319'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/6514977621176060319'/><link rel='alternate' type='text/html' href='http://devgrok.blogspot.com/2009/06/few-good-guice-tutorials.html' title='A few good Guice Tutorials'/><author><name>Christopher Watts</name><uri>http://www.blogger.com/profile/12923587712192007751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://3.bp.blogspot.com/_qoo3n1eKv3E/Swn9NTUeryI/AAAAAAAAC6A/qESuFc9W1CQ/S220/P9260160.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2330120457456880954.post-5330405311787188887</id><published>2009-06-06T22:53:00.015+10:00</published><updated>2010-09-13T22:47:22.310+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JSF'/><title type='text'>CommandButton not calling action when using immediate and rendered</title><content type='html'>I came across a problem with using a custom command component, that when using immediate it wasn't calling the action I had bound to it. I started resolving the issue and discovered my decode code wasn't being called. I had create a custom button, cannibalising and extending the original CommandButton component. Due to my lack of understanding of setting up renderkits, I gave up and  hacked in a renderer:&lt;br /&gt;&lt;pre class="brush: java"&gt;public class ImageButton extends HtmlCommandButton&lt;br /&gt;{&lt;br /&gt;   private ImageButtonRenderer render = new ImageButtonRenderer();&lt;br /&gt;   &lt;br /&gt;   @Override&lt;br /&gt;   public void decode(FacesContext context)&lt;br /&gt;   {&lt;br /&gt;      render.decode(context, this);&lt;br /&gt;   }&lt;br /&gt;   &lt;br /&gt;   @Override&lt;br /&gt;   public void encodeBegin(FacesContext context) throws IOException&lt;br /&gt;   {&lt;br /&gt;      render.encodeBegin(context, this);&lt;br /&gt;   }&lt;/pre&gt;This resulted in decode not always working. I came across this &lt;a href="http://blogs.steeplesoft.com/jsf-component-writing-check-list/"&gt;nice summary&lt;/a&gt; of how to write a custom component and altered my code accordingly. Decode worked but the action was still not called. Thought the cause was just with immediate="true". So I swtiched to using a standard commandButton for testing.&lt;br /&gt;&lt;pre name="code" class="html"&gt;&amp;lt;h:inputhidden value="#{testBean.add}" immediate="true" /&gt;&lt;br /&gt;&amp;lt;h:commandbutton value="Delete" immediate="true" rendered="#{!testBean.add}" /&gt;&lt;br /&gt;&lt;/pre&gt;However the command button was still not being decoded, as I thought immediate on the attribute should work but for the 2nd time I've misunderstood &lt;a href="http://wiki.apache.org/myfaces/How_The_Immediate_Attribute_Works"&gt;how it works&lt;/a&gt; for input components. Immediate on input components only changes priority of validation, it doesn't cause them to update the model any earlier.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;UIComponentBase.processDecodes:1018&lt;/span&gt; calls&lt;span style="font-family:courier new;"&gt; isRendered()&lt;/span&gt; - which returns false as the &lt;span style="font-style: italic;"&gt;Update Model Values&lt;/span&gt;&lt;strong&gt;&lt;/strong&gt; phase hasn't been applied. Which skips the decode of the the component. Which clearly isn't right. Whether it was rendered or not should be remembered from the Render phase during the decode(&lt;span style="font-style: italic;"&gt;Apply Request Values&lt;/span&gt;) phase. In the following phases it should be calculated from the EL binding. This to me seems a bug in the specification or the implementation.&lt;br /&gt;&lt;br /&gt;So how to use a model value for the rendered attribute for a button with immediate on?&lt;br /&gt;&lt;br /&gt;The answer use Tomahawk's &lt;a href="http://myfaces.apache.org/tomahawk-project/tomahawk12/tagdoc/t_saveState.html"&gt;saveState&lt;/a&gt; tag. The state is maintained on the server side, and as long as it is put before the other tags that need it, it will restore the model/attribute to the same value it was after the &lt;span style="font-style: italic;"&gt;Render &lt;/span&gt;phase during the &lt;span style="font-style: italic;"&gt;Apply Request Values&lt;/span&gt; phase. Thus when it goes to decode the button, the same values that were used to calculate the rendered during the previous rendering to create this page are used.&lt;br /&gt;&lt;pre name="code" class="html"&gt;&amp;lt;t:savestate value="#{testBean.add}" /&gt;&lt;br /&gt;&amp;lt;h:commandbutton value="Delete" immediate="true" rendered="#{!testBean.add}" /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2330120457456880954-5330405311787188887?l=devgrok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devgrok.blogspot.com/feeds/5330405311787188887/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://devgrok.blogspot.com/2009/06/commandbutton-not-calling-action-when.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/5330405311787188887'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/5330405311787188887'/><link rel='alternate' type='text/html' href='http://devgrok.blogspot.com/2009/06/commandbutton-not-calling-action-when.html' title='CommandButton not calling action when using immediate and rendered'/><author><name>Christopher Watts</name><uri>http://www.blogger.com/profile/12923587712192007751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://3.bp.blogspot.com/_qoo3n1eKv3E/Swn9NTUeryI/AAAAAAAAC6A/qESuFc9W1CQ/S220/P9260160.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2330120457456880954.post-3635507082976359705</id><published>2009-06-06T02:57:00.006+10:00</published><updated>2009-06-13T03:22:52.904+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='EJB'/><title type='text'>ClassCastException with PortableRemoteObject.narrow() EJB2/EJB3</title><content type='html'>After switching to JBoss 5 and recreating my EAR project inside eclipse, I started getting ClassCastException:&lt;br /&gt;&lt;pre&gt;java.lang.ClassCastException&lt;br /&gt;  at com.sun.corba.se.impl.javax.rmi.PortableRemoteObject.narrow(PortableRemoteObject.java:229)&lt;br /&gt;  at javax.rmi.PortableRemoteObject.narrow(PortableRemoteObject.java:137)&lt;/pre&gt;&lt;pre class="java" name="code"&gt;Object obj = initialContext.lookup(ejbReferenceComponent);&lt;br /&gt;MyEJBRemoteHome home = javax.rmi.PortableRemoteObject.narrow(obj, MyEJBRemoteHome.class);&lt;/pre&gt;&lt;br /&gt;After looking around, the cause of it is how the app server determines whether to give you a EJBHome instance which you have to use .narrow() then .create() to get a reference to the bean for EJB2 vs returning a proxy to the bean itself for EJB3. JBoss has some information on referencing &lt;a href="http://www.jboss.org/file-access/default/members/jbossejb3/freezone/docs/tutorial/1.0.8/html/EJB2.1_and_EJB3_references.html"&gt;EJB3 from EJB2 environments&lt;/a&gt; and vice-versa. &lt;br /&gt;&lt;br /&gt;The summary generally is if the application.xml has the EJB2 header then it gives you an EJBHome interface.&lt;br /&gt;If the ear's ejb-jar has the EJB3 header then it gives you a proxy to the bean itself (no need for narrow/create).&lt;br /&gt;&lt;br /&gt;The lack of a more intelligent error from PortableRemoteObject is a bit annoying. However here is a generic solution for cases when your switching between environments:&lt;pre name="code" class="java"&gt;public &amp;lt;T, S extends EJBHome&gt; T lookupEJB(String ejbReferenceComponent, Class&amp;lt;S&gt; homeClass, Class&amp;lt;T&gt; ejbClass)&lt;br /&gt;   throws NamingException, IllegalArgumentException, SecurityException, IllegalAccessException, InvocationTargetException,&lt;br /&gt;   NoSuchMethodException&lt;br /&gt;{&lt;br /&gt;  log.debug("{}", initialContext.getEnvironment());&lt;br /&gt;  java.lang.Object remote = initialContext.lookup(ejbReferenceComponent);&lt;br /&gt;&lt;br /&gt;  if (ejbClass.isInstance(remote))&lt;br /&gt;    return (T) remote;&lt;br /&gt;&lt;br /&gt;  S home = (S) PortableRemoteObject.narrow(remote, homeClass);&lt;br /&gt;&lt;br /&gt;  return (T) home.getClass().getMethod("create", (Class[]) null).invoke(home, (Object[]) null);&lt;br /&gt;}&lt;/pre&gt;Of course the simplest approach is to convert it all to EJB3 and you won't have to worry :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2330120457456880954-3635507082976359705?l=devgrok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devgrok.blogspot.com/feeds/3635507082976359705/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://devgrok.blogspot.com/2009/06/classcastexception-with.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/3635507082976359705'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/3635507082976359705'/><link rel='alternate' type='text/html' href='http://devgrok.blogspot.com/2009/06/classcastexception-with.html' title='ClassCastException with PortableRemoteObject.narrow() EJB2/EJB3'/><author><name>Christopher Watts</name><uri>http://www.blogger.com/profile/12923587712192007751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://3.bp.blogspot.com/_qoo3n1eKv3E/Swn9NTUeryI/AAAAAAAAC6A/qESuFc9W1CQ/S220/P9260160.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2330120457456880954.post-7739304164930114752</id><published>2009-03-24T08:44:00.004+11:00</published><updated>2009-06-13T05:13:47.485+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Unit Testing'/><category scheme='http://www.blogger.com/atom/ns#' term='JDBC'/><title type='text'>Simple transactional unit testing database</title><content type='html'>Last week I wrote a post about using Google Guice to perform &lt;a href="http://devgrok.blogspot.com/2009/03/lightweight-transaction-handling-in.html"&gt;transaction handling using interceptors&lt;/a&gt;.&lt;br /&gt;When it came time to write some database level unit tests, I wanted to have the same kind of simple transaction handling so that every unit test is rolled back on completion. Rolling back the changes each test makes is necessary for the tests to be &lt;span style="font-weight: bold;"&gt;repeatable&lt;/span&gt; and &lt;span style="font-weight: bold;"&gt;consistent&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;TestNG provides convenient way to do processing before and after each method is called using &lt;span style="font-weight: bold;"&gt;@BeforeMethod&lt;/span&gt; and &lt;span style="font-weight: bold;"&gt;@AfterMethod&lt;/span&gt;. All you need to do is annotate methods that you want automatically rolled back with &lt;span style="font-weight: bold;"&gt;@Transactional&lt;/span&gt; then check for it and act accordingly. The same could be done with JUnit using a &lt;span style="font-style: italic;"&gt;RunListener&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Below is my implementation. I use just one connection per unit test, it can easily be adapted across multiple connections.&lt;pre name="code" class="java"&gt;public abstract class BaseUtilTest&lt;br /&gt;{&lt;br /&gt;  private static final Logger log = Logger.getLogger(BaseUtilTest.class);&lt;br /&gt;  protected Connection con;&lt;br /&gt;&lt;br /&gt;  @BeforeClass&lt;br /&gt;  public void init()&lt;br /&gt;  {&lt;br /&gt;    Injector myInjector = Guice.createInjector(new TestModule());&lt;br /&gt;    myInjector.injectMembers(this);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  @BeforeMethod&lt;br /&gt;  public void before(Method method) throws Exception&lt;br /&gt;  {&lt;br /&gt;    con = ConnectionUtils.getConnection();&lt;br /&gt;    if (method.isAnnotationPresent(Transactional.class))&lt;br /&gt;    {&lt;br /&gt;      //do transactional&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  @AfterMethod&lt;br /&gt;  public void after(Method method, ITestContext context) throws Exception&lt;br /&gt;  {&lt;br /&gt;    if (method.isAnnotationPresent(Transactional.class))&lt;br /&gt;    {&lt;br /&gt;      //rollback any changes&lt;br /&gt;      rollback();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    ITestResult result = Reporter.getCurrentTestResult();&lt;br /&gt;    if (!result.isSuccess() &amp;&amp; result.getThrowable() != null)&lt;br /&gt;    {&lt;br /&gt;      log.error(method.toGenericString(), result.getThrowable());&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  void rollback()&lt;br /&gt;  {&lt;br /&gt;    if (con == null)&lt;br /&gt;    {&lt;br /&gt;      log.warn("No bound connection to rollback");&lt;br /&gt;      return;&lt;br /&gt;    }&lt;br /&gt;    log.info("Rolling back transaction");&lt;br /&gt;    try&lt;br /&gt;    {&lt;br /&gt;      con.rollback();&lt;br /&gt;    }&lt;br /&gt;    catch (SQLException e)&lt;br /&gt;    {&lt;br /&gt;      log.warn(e);&lt;br /&gt;    }&lt;br /&gt;  }  &lt;br /&gt;}&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2330120457456880954-7739304164930114752?l=devgrok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devgrok.blogspot.com/feeds/7739304164930114752/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://devgrok.blogspot.com/2009/03/simple-transactional-unit-testing.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/7739304164930114752'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/7739304164930114752'/><link rel='alternate' type='text/html' href='http://devgrok.blogspot.com/2009/03/simple-transactional-unit-testing.html' title='Simple transactional unit testing database'/><author><name>Christopher Watts</name><uri>http://www.blogger.com/profile/12923587712192007751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://3.bp.blogspot.com/_qoo3n1eKv3E/Swn9NTUeryI/AAAAAAAAC6A/qESuFc9W1CQ/S220/P9260160.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2330120457456880954.post-859466423326825888</id><published>2009-03-20T13:19:00.011+11:00</published><updated>2010-09-13T22:56:37.578+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JSF'/><category scheme='http://www.blogger.com/atom/ns#' term='JDBC'/><category scheme='http://www.blogger.com/atom/ns#' term='Google Guice'/><title type='text'>Lightweight transaction handling in Tomcat</title><content type='html'>With Enterprise Java Beans (EJB) used with Container-Managed Transactions (CMT), transactions are transparently handled by the application server. When a method is marked with &lt;code&gt;@TransactionAttribute(REQUIRED)&lt;/code&gt; then it starts a transaction (if one is not already started) and on competition of the method commits it (if it created the transaction). If an exception occurs, then the container rolls back the transaction. The beauty of it, is that it requires no extra code, just a single annotation.&lt;br /&gt;&lt;br /&gt;However, if running outside an application server, e.g. in a Tomcat only environment, then container managed transactions cannot be used. The common approach would be to use Spring.&lt;br /&gt;Spring provides the same functionality as EJB's but with a few drawbacks. It requires a large number of libraries to be included in your classpath plus a cumbersome to maintain configuration file just to set up some basic transaction handling. Spring does have its advantages but is overkill in a lot of cases.&lt;br /&gt;&lt;br /&gt;Enter &lt;a href="http://code.google.com/p/google-guice/"&gt;Google Guice&lt;/a&gt;. Google's dependancy injection 'framework'.&lt;br /&gt;&lt;br /&gt;Guice and be configured as simply or as complex as you want.&lt;br /&gt;In the most simple case, guice requires very little configuration. Unless specified, all beans have no scope. That is, they are single use - new instances are created for each injection. POJO services that don't implement an interface don't even need to be named. If you so chose, you could create an empty configuration Module and let everything auto-wire.&lt;br /&gt;&lt;br /&gt;Onto transaction handling.&lt;br /&gt;Guice 1 doesn't provide any mechanism to perform transaction handling. However it turns out that doesn't matter as it takes very little effort to implement a simple transaction handler.&lt;br /&gt;The trick is to define an annotation, then bind an interceptor to all methods that are annotated. The interception is done at load time, so all the complex matching is done once with Guice's internal CGLib proxies created.&lt;br /&gt;&lt;br /&gt;First create the annotation to use (you could use JEE ones if you wanted but would need to put them in the class path).&lt;br /&gt;&lt;pre name="code" class="java"&gt;@Retention(RetentionPolicy.RUNTIME)&lt;br /&gt;@Target( { ElementType.METHOD, ElementType.TYPE })&lt;br /&gt;public @interface Transactional&lt;br /&gt;{&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Next define your &lt;code&gt;Module&lt;/code&gt;. Modules are Guice's configuration.&lt;br /&gt;&lt;pre name="code" class="java"&gt;import static com.google.inject.matcher.Matchers.annotatedWith;&lt;br /&gt;import static com.google.inject.matcher.Matchers.subclassesOf;&lt;br /&gt;&lt;br /&gt;import org.owatta.service.AbstractService;&lt;br /&gt;import org.owatta.annotation.Transactional;&lt;br /&gt;&lt;br /&gt;import com.google.inject.AbstractModule;&lt;br /&gt;&lt;br /&gt;public class ServiceModule extends AbstractModule&lt;br /&gt;   {&lt;br /&gt;   @Override&lt;br /&gt;   protected void configure()&lt;br /&gt;   {&lt;br /&gt;      //this line tells guice to bind TransactionInterceptor to any class&lt;br /&gt;      //that is a subclass of AbstractService and is annotated with @Transactional&lt;br /&gt;      //the subclassesOf() could be replaced with Matchers.any()&lt;br /&gt;      bindInterceptor(subclassesOf(AbstractService.class), annotatedWith(Transactional.class), new TransactionInterceptor());&lt;br /&gt;   }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;Next create your interceptor. Since I only need to handle transaction directly on a connection my transaction interceptor requires little work.&lt;br /&gt;&lt;pre class="brush: java"&gt;/**&lt;br /&gt;*&lt;br /&gt;*/&lt;br /&gt;package org.owatta.modules;&lt;br /&gt;&lt;br /&gt;import java.sql.Connection;&lt;br /&gt;import java.sql.SQLException;&lt;br /&gt;&lt;br /&gt;import org.aopalliance.intercept.MethodInterceptor;&lt;br /&gt;import org.aopalliance.intercept.MethodInvocation;&lt;br /&gt;import org.apache.log4j.Logger;&lt;br /&gt;import org.owatta.web.FacesFilter;&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt;* Simple transaction interceptor. Commits on success, rolls back on error.&lt;br /&gt;* @author Chris Watts&lt;br /&gt;*/&lt;br /&gt;public class TransactionInterceptor implements MethodInterceptor&lt;br /&gt;{&lt;br /&gt;   private final static Logger log = Logger.getLogger(TransactionInterceptor.class);&lt;br /&gt;&lt;br /&gt;   public Object invoke(MethodInvocation arg0) throws Throwable&lt;br /&gt;   {&lt;br /&gt;      Object returnValue = null;&lt;br /&gt;      try&lt;br /&gt;      {&lt;br /&gt;         returnValue = arg0.proceed();&lt;br /&gt;         Connection con = FacesFilter.getConnection();&lt;br /&gt;         if (con == null)&lt;br /&gt;         {&lt;br /&gt;            log.warn("No bound connection to rollback");&lt;br /&gt;         }&lt;br /&gt;         else&lt;br /&gt;         {&lt;br /&gt;            try&lt;br /&gt;            {&lt;br /&gt;               con.commit();&lt;br /&gt;            }&lt;br /&gt;            catch (SQLException e)&lt;br /&gt;            {&lt;br /&gt;               log.error("Error commiting transaction, rolling back", e);&lt;br /&gt;               //make sure the caller knows the commit failed&lt;br /&gt;               throw new RuntimeException(e);&lt;br /&gt;            }&lt;br /&gt;         }&lt;br /&gt;         return returnValue;&lt;br /&gt;      }&lt;br /&gt;      catch (Throwable t)&lt;br /&gt;      {&lt;br /&gt;         rollback();&lt;br /&gt;         throw t;&lt;br /&gt;      }&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   /**&lt;br /&gt;    * perform rollback&lt;br /&gt;    */&lt;br /&gt;   void rollback()&lt;br /&gt;   {&lt;br /&gt;      Connection con = FacesFilter.getConnection();&lt;br /&gt;      if (con == null)&lt;br /&gt;      {&lt;br /&gt;         log.warn("No bound connection to rollback");&lt;br /&gt;         return;&lt;br /&gt;      }&lt;br /&gt;      log.info("Rolling back transaction");&lt;br /&gt;      try&lt;br /&gt;      {&lt;br /&gt;         con.rollback();&lt;br /&gt;      }&lt;br /&gt;      catch (SQLException e)&lt;br /&gt;      {&lt;br /&gt;         log.warn(e);&lt;br /&gt;      }&lt;br /&gt;   }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;Since I'm using JSF, I'm using &lt;a href="http://code.google.com/p/guicesf/"&gt;GuiceSF &lt;/a&gt;as a variable resolver in order to inject the managed beans. I put the following in my web.xml:&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&amp;lt;!-- guice / jsf --&gt;&lt;br /&gt;&amp;lt;context-param&gt;&lt;br /&gt;   &amp;lt;param-name&gt;com.guicesf.Modules&amp;lt;/param-name&gt;&lt;br /&gt;   &amp;lt;param-value&gt;com.google.inject.servlet.ServletModule,org.owatta.modules.ServiceModule&amp;lt;/param-value&gt;&lt;br /&gt;&amp;lt;/context-param&gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;!-- Entity Manager Filter declaration --&gt;&lt;br /&gt;&amp;lt;filter&gt;&lt;br /&gt;   &amp;lt;filter-name&gt;GuiceFilter&amp;lt;/filter-name&gt;&lt;br /&gt;   &amp;lt;filter-class&gt;com.google.inject.servlet.GuiceFilter&amp;lt;/filter-class&gt;&lt;br /&gt;&amp;lt;/filter&gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;filter-mapping&gt;&lt;br /&gt;   &amp;lt;filter-name&gt;GuiceFilter&amp;lt;/filter-name&gt;&lt;br /&gt;   &amp;lt;url-pattern&gt;*.faces&amp;lt;/url-pattern&gt;&lt;br /&gt;&amp;lt;/filter-mapping&gt;&lt;/pre&gt;&lt;br /&gt;This is actually 2 parts. The first part configures GuiceSF, the 2nd configures Guice so it can use request / session scoped beans. Depending on your needs this may not be necessary.&lt;br /&gt;The final JSF step is to configure the variable resolver, add the following to faces-config.xml:&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&amp;lt;application&gt;&lt;br /&gt;&amp;lt;!-- injector for managed beans --&gt;&lt;br /&gt;&amp;lt;el-resolver&gt;com.guicesf.GuiceResolver&amp;lt;/el-resolver&gt;&lt;br /&gt;&amp;lt;/application&gt;&lt;/pre&gt;The final step is to put the required jars on the class path:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;guice-1.0.jar&lt;/li&gt;&lt;li&gt;aopalliance.jar&lt;/li&gt;&lt;li&gt;guice-servlet-1.0.jar (only required if you want servlet scope handling)&lt;/li&gt;&lt;li&gt;guicesf-0.1.jar (for JSF integration)&lt;/li&gt;&lt;/ul&gt;The elegance of this solution is that it is VERY lightweight, very little lock-in and complete control.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2330120457456880954-859466423326825888?l=devgrok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devgrok.blogspot.com/feeds/859466423326825888/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://devgrok.blogspot.com/2009/03/lightweight-transaction-handling-in.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/859466423326825888'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/859466423326825888'/><link rel='alternate' type='text/html' href='http://devgrok.blogspot.com/2009/03/lightweight-transaction-handling-in.html' title='Lightweight transaction handling in Tomcat'/><author><name>Christopher Watts</name><uri>http://www.blogger.com/profile/12923587712192007751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://3.bp.blogspot.com/_qoo3n1eKv3E/Swn9NTUeryI/AAAAAAAAC6A/qESuFc9W1CQ/S220/P9260160.JPG'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2330120457456880954.post-7792054446372682476</id><published>2009-01-31T07:07:00.008+11:00</published><updated>2009-06-12T07:55:59.187+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tomcat'/><title type='text'>Logging Tomcat 6 startup via log4j</title><content type='html'>For a recent task I had the need to log the tomcat startup process via log4j (so I could view it in eclipse using the log4eclipse plugin).&lt;br /&gt;The simple copying log4j.properties and log4j.jar into TOMCAT/lib didn't work as it had for previous versions.&lt;br /&gt;After some quick digging around I finally read the right section of the &lt;a href="http://tomcat.apache.org/tomcat-6.0-doc/logging.html"&gt;documentation&lt;/a&gt;. The steps are pretty easy to follow.&lt;br /&gt;&lt;br /&gt;The jar of juli (their logger) that comes with the standard build doesn't allow for commons-logging.&lt;br /&gt;To get it to work you need to download the source and compile the extras commons-logging.&lt;br /&gt;Which is a simple:&lt;br /&gt;&lt;pre&gt;ant download&lt;br /&gt;ant build-only&lt;br /&gt;ant -f extras.xml commons-logging&lt;/pre&gt;Next:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Replace &lt;code&gt;$CATALINA_HOME/bin/tomcat-juli.jar&lt;/code&gt; with         &lt;code&gt;output/extras/tomcat-juli.jar&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;Place &lt;code&gt;output/extras/tomcat-juli-adapters.jar&lt;/code&gt; in          $CATALINA_HOME/lib.&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;For apache-tomcat-6.0.14-src you'll need to change build.properties.default line 45:&lt;br /&gt;&lt;pre&gt;jdt.loc=http://archive.eclipse.org/eclipse/downloads/drops/R-3.2.2-200702121330/eclipse-JDT-3.2.2.zip&lt;/pre&gt;&lt;br /&gt;Additionally as of apache-tomcat-6.0.18-src, there are errors compiling the target build-tomcat-dbcp using JDK 1.6; &lt;span style="font-weight: bold;"&gt;so use JDK 1.5&lt;/span&gt; to do the 'ant download' step (or all).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2330120457456880954-7792054446372682476?l=devgrok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devgrok.blogspot.com/feeds/7792054446372682476/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://devgrok.blogspot.com/2009/01/logging-tomcat-6-startup-via-log4j.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/7792054446372682476'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/7792054446372682476'/><link rel='alternate' type='text/html' href='http://devgrok.blogspot.com/2009/01/logging-tomcat-6-startup-via-log4j.html' title='Logging Tomcat 6 startup via log4j'/><author><name>Christopher Watts</name><uri>http://www.blogger.com/profile/12923587712192007751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://3.bp.blogspot.com/_qoo3n1eKv3E/Swn9NTUeryI/AAAAAAAAC6A/qESuFc9W1CQ/S220/P9260160.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2330120457456880954.post-4439875792978301989</id><published>2008-12-09T08:36:00.002+11:00</published><updated>2009-06-12T07:55:15.345+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Unit Testing'/><category scheme='http://www.blogger.com/atom/ns#' term='Spring MVC'/><category scheme='http://www.blogger.com/atom/ns#' term='Spring'/><title type='text'>Integration testing Spring MVC without web server</title><content type='html'>Unit testing is very useful for finding bugs in isolated pieces of code and for checking whether a method obeys its contract. However, testing the configuration of an app or testing how a framework like Spring MVC calls or manipulates the data passed in.&lt;br /&gt;&lt;br /&gt;This is where integration testing comes in. Testing the app with everything wired in. End to end testing. This usually entails a tester firing up the browser and working through a list of test cases. This can be automated with something similar Test Director or made into JUnit test cases using HtmlUnit or HttpUnit.&lt;br /&gt;&lt;br /&gt;Creating a test case using HtmlUnit (or HttpUnit if you want to do more work) can be quiet tedious and time consuming. However there is a way to programmatically invoke the Spring's servlet and obtain the response object without having to parse html. By invoking it directly you gain a level of control, and the testing can be more specific. The downside is that you don't test the JSP files, though I'm sure there are ways to do that too.&lt;br /&gt;&lt;br /&gt;When it came to actually setting up the environment to perform the test, I discovered this was the one area where Spring's test framework is lacking. So I ended up extending the framework to perform the necessary tasks.&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;&lt;br /&gt;Loading The Web Application Context&lt;/span&gt;&lt;br /&gt;The first hurdle encountered was trying to load the correct application context.&lt;br /&gt;The test framework, by default loads the &lt;code&gt;GenericXmlContextLoader&lt;/code&gt;. However the &lt;code&gt;DispatcherServlet&lt;/code&gt; expects to a &lt;code&gt;XmlWebApplicationContext&lt;/code&gt; to be loaded. No problem, the annotation &lt;code&gt;@ContextConfiguration&lt;/code&gt; allows a custom loader to be specified.&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;@RunWith(SpringJUnit4ClassRunner.class)&lt;br /&gt;@ContextConfiguration(locations = { "classpath:/common-beans.xml", "classpath:/myservlet-test.xml" }, loader = WebAppLoader.class)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Just extend &lt;code&gt;AbstractContextLoader&lt;/code&gt;, override &lt;code&gt;loadContext()&lt;/code&gt;, create an instance of &lt;code&gt;XmlWebApplicationContext&lt;/code&gt; create a &lt;code&gt;MockServletContext&lt;/code&gt; set the &lt;code&gt;ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE&lt;/code&gt; to be the new context. Next obtain a reference to the servlet that was defined in the &lt;strong&gt;myservlet-test.xml&lt;/strong&gt;&lt;pre name="code" class="xml"&gt;&lt;br /&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&gt;&lt;br /&gt;&amp;lt;beans xmlns="http://www.springframework.org/schema/beans"&lt;br /&gt;xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&lt;br /&gt;xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"&gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;!-- ========================= SERVLET ========================= --&gt;&lt;br /&gt;&amp;lt;bean id="aptt" class="org.springframework.web.servlet.DispatcherServlet"&gt;&lt;br /&gt;&amp;lt;/bean&gt;&lt;br /&gt;&amp;lt;/beans&gt;&lt;br /&gt;&lt;/pre&gt;As long as you set the servlet context's path to be the web directory of the project your testing then all the relevant configuration files will be loaded.&lt;br /&gt;Here is the loader:&lt;pre name="code" class="java"&gt;&lt;br /&gt;/**&lt;br /&gt;* @author Chris Watts&lt;br /&gt;*&lt;br /&gt;*/&lt;br /&gt;public class WebAppLoader extends AbstractContextLoader&lt;br /&gt;{&lt;br /&gt;   /** Application root directory (usually project/web). */&lt;br /&gt;   protected String basePath = "../myproj/web";&lt;br /&gt;   /**&lt;br /&gt;    * set to false for each servlet to load an additional context (the way&lt;br /&gt;    * {@link DispatcherServlet} works by default). Useful if you want to load&lt;br /&gt;    * the servlet's context in the main context.&lt;br /&gt;    */&lt;br /&gt;   protected boolean shareContext = false;&lt;br /&gt;   private static final Logger logger = Logger.getLogger(WebAppLoader.class);&lt;br /&gt;   /** attribute name to pass context via */&lt;br /&gt;   private static final String CONTEXT_PATH = "com.example.WebApplicationContext";&lt;br /&gt;&lt;br /&gt;   /**&lt;br /&gt;    * {@inheritDoc}&lt;br /&gt;    *&lt;br /&gt;    * @see org.springframework.test.context.support.AbstractContextLoader#getResourceSuffix()&lt;br /&gt;    */&lt;br /&gt;   @Override&lt;br /&gt;   protected String getResourceSuffix()&lt;br /&gt;   {&lt;br /&gt;       return "-context.xml";&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   /**&lt;br /&gt;    * {@inheritDoc}&lt;br /&gt;    *&lt;br /&gt;    * @see org.springframework.test.context.ContextLoader#loadContext(java.lang.String[])&lt;br /&gt;    */&lt;br /&gt;   @SuppressWarnings("unchecked")&lt;br /&gt;   public XmlWebApplicationContext loadContext(String... locations) throws Exception&lt;br /&gt;   {&lt;br /&gt;       if (logger.isDebugEnabled())&lt;br /&gt;       {&lt;br /&gt;           logger.debug("Loading ApplicationContext for locations ["&lt;br /&gt;                   + StringUtils.arrayToCommaDelimitedString(locations) + "].");&lt;br /&gt;       }&lt;br /&gt;&lt;br /&gt;       //resolve absolute path&lt;br /&gt;       File path = ResourceUtils.getFile(basePath);&lt;br /&gt;       if (!path.exists())&lt;br /&gt;           throw new FileNotFoundException("base path does not exist; " + basePath);&lt;br /&gt;       basePath = "file:" + path.getAbsolutePath();&lt;br /&gt;      &lt;br /&gt;       XmlWebApplicationContext appContext = new XmlWebApplicationContext();&lt;br /&gt;      &lt;br /&gt;       MockServletContext servletContext = new MockServletContext(basePath);&lt;br /&gt;       servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, appContext);&lt;br /&gt;&lt;br /&gt;       if (shareContext)&lt;br /&gt;       {&lt;br /&gt;           servletContext.setAttribute(CONTEXT_PATH, appContext);&lt;br /&gt;       }&lt;br /&gt;&lt;br /&gt;       appContext.setServletContext(servletContext);&lt;br /&gt;       appContext.setConfigLocations(locations);&lt;br /&gt;       appContext.refresh();&lt;br /&gt;       appContext.registerShutdownHook();&lt;br /&gt;&lt;br /&gt;       Map&amp;lt;String, DispatcherServlet&gt; map = appContext.getBeansOfType(DispatcherServlet.class);&lt;br /&gt;       for (Entry&amp;lt;String, DispatcherServlet&gt; entry : map.entrySet())&lt;br /&gt;       {&lt;br /&gt;           DispatcherServlet servlet = entry.getValue();&lt;br /&gt;           String servletName = entry.getKey();&lt;br /&gt;          &lt;br /&gt;           if (shareContext)&lt;br /&gt;               servlet.setContextAttribute(CONTEXT_PATH);&lt;br /&gt;          &lt;br /&gt;           MockServletConfig servletConfig = new MockServletConfig(servletContext, servletName);&lt;br /&gt;           servlet.init(servletConfig);&lt;br /&gt;       }&lt;br /&gt;&lt;br /&gt;       return appContext;&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Now the class to call the dispatcher and perform the test:&lt;pre name="code" class="java"&gt;&lt;br /&gt;@RunWith(SpringJUnit4ClassRunner.class)&lt;br /&gt;@ContextConfiguration(locations = { "classpath:/common-beans.xml", "classpath:/myservlet-test.xml" }, loader = WebAppLoader.class)&lt;br /&gt;public class MyServletTester&lt;br /&gt;{&lt;br /&gt;   /** TILES_STACK. */&lt;br /&gt;   private static final String TILES_STACK = "org.apache.tiles.AttributeContext.STACK";&lt;br /&gt;   protected final Logger log = Logger.getLogger(getClass());&lt;br /&gt;   /** the servlet */&lt;br /&gt;   @Autowired&lt;br /&gt;   protected DispatcherServlet servlet;&lt;br /&gt;   /** user session info, session scoped. */&lt;br /&gt;   @Autowired&lt;br /&gt;   protected UserSession userSession;&lt;br /&gt;   /** request scoped bean */&lt;br /&gt;   protected MessageList messages;&lt;br /&gt;   /** */&lt;br /&gt;   protected MockHttpServletRequest request;&lt;br /&gt;   /** */&lt;br /&gt;   protected MockHttpServletResponse response;&lt;br /&gt;   /** special util extending RequestDispatcher to capture forward() data. */&lt;br /&gt;   protected RequestCopyingDispatcher requestDispatcher = new RequestCopyingDispatcher();&lt;br /&gt;&lt;br /&gt;   public void onStart() throws Exception&lt;br /&gt;   {&lt;br /&gt;       request = null;&lt;br /&gt;       response = null;&lt;br /&gt;       // obtain bean stored in the servlet's own context&lt;br /&gt;       messages = (MessageList) servlet.getWebApplicationContext().getBean("messages");&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt; * Perform the actual test.&lt;br /&gt; */&lt;br /&gt;   @Test&lt;br /&gt;   public void welcomePageLoggedIn() throws Exception&lt;br /&gt;   {&lt;br /&gt;       HashMap&amp;lt;String, String&gt; parameters = new HashMap&amp;lt;String, String&gt;();&lt;br /&gt;       MockHttpServletResponse ret = process("/home.do", parameters, true);&lt;br /&gt;       checkTilesResponse(response, request, "/jsp/tiles/mainLayout.jsp", "/jsp/welcomePage.jsp");&lt;br /&gt;   }&lt;br /&gt;  &lt;br /&gt;   protected MockHttpServletResponse process(String uri, Map&amp;lt;String, String&gt; reqParams, boolean loggedIn)&lt;br /&gt;           throws Exception&lt;br /&gt;   {&lt;br /&gt;       MockInterceptingRequest req = new MockInterceptingRequest("GET", uri);&lt;br /&gt;       MockHttpServletResponse res = new MockHttpServletResponse();&lt;br /&gt;       req.setRequestDispatcher(requestDispatcher);&lt;br /&gt;&lt;br /&gt;       //used for accessing request scoped proxied beans&lt;br /&gt;       WebRequest webRequest = new ServletWebRequest(req, res);&lt;br /&gt;       RequestContextHolder.setRequestAttributes(webRequest);&lt;br /&gt;&lt;br /&gt;       req.addParameters(reqParams);&lt;br /&gt;       HttpSession session = req.getSession();&lt;br /&gt;       if (loggedIn)&lt;br /&gt;       {&lt;br /&gt;           //set properties to indicate logged in&lt;br /&gt;       }&lt;br /&gt;&lt;br /&gt;       //call&lt;br /&gt;       servlet.service(req, res);&lt;br /&gt;&lt;br /&gt;       response = res;&lt;br /&gt;       request = req;&lt;br /&gt;       //done&lt;br /&gt;       return res;&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   public void checkResponse(MockHttpServletResponse response, MockHttpServletRequest request)&lt;br /&gt;           throws Exception&lt;br /&gt;   {&lt;br /&gt;       assertThat("ret", response, notNullValue());&lt;br /&gt;       assertThat("status code", response.getStatus(), equalTo(200));&lt;br /&gt;       assertThat("getErrorMessage", response.getErrorMessage(), nullValue());&lt;br /&gt;       assertThat("redirect", response.getRedirectedUrl(), nullValue());&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt; * Checks the response and request of the call.&lt;br /&gt; */&lt;br /&gt;   public void checkTilesResponse(MockHttpServletResponse response, MockHttpServletRequest request,&lt;br /&gt;           String template, String page) throws Exception&lt;br /&gt;   {&lt;br /&gt;       checkResponse(response, request);&lt;br /&gt;&lt;br /&gt;       assertThat("forward", response.getForwardedUrl(), equalTo(template));&lt;br /&gt;&lt;br /&gt;       //Attributes from the dispatcher tiles calls&lt;br /&gt;       Stack tilesStack;&lt;br /&gt;       tilesStack = (Stack) requestDispatcher.getCapturedAttributes().get(TILES_STACK);&lt;br /&gt;       assertThat(TILES_STACK, tilesStack, notNullValue());&lt;br /&gt;       assertThat("stack.isEmpty", tilesStack.isEmpty(), not(equalTo(true)));&lt;br /&gt;       if (log.isDebugEnabled())&lt;br /&gt;           log.debug(Arrays.toString(tilesStack.toArray()));&lt;br /&gt;      &lt;br /&gt;       BasicAttributeContext tilesContext = (BasicAttributeContext) tilesStack.pop();&lt;br /&gt;       if (log.isDebugEnabled())&lt;br /&gt;           log.debug(toString(tilesContext));&lt;br /&gt;      &lt;br /&gt;       assertThat("tiles.body", tilesContext.getAttribute("body"), notNullValue());&lt;br /&gt;       String body = (String) tilesContext.getAttribute("body").getValue();&lt;br /&gt;       assertThat("body", body, equalTo(page));&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   protected void debugAttributes()&lt;br /&gt;   {&lt;br /&gt;       Enumeration&amp;lt;String&gt; names = request.getAttributeNames();&lt;br /&gt;       while (names.hasMoreElements())&lt;br /&gt;       {&lt;br /&gt;           String name = names.nextElement();&lt;br /&gt;           log.debug(name + ":" + request.getAttribute(name));&lt;br /&gt;       }&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   public static String toString(BasicAttributeContext cntx)&lt;br /&gt;   {&lt;br /&gt;       StringBuilder sb = new StringBuilder();&lt;br /&gt;       sb.append("TilesAttributes: {");&lt;br /&gt;&lt;br /&gt;       Iterator&amp;lt;String&gt; i = cntx.getAttributeNames();&lt;br /&gt;       boolean hasNext = i.hasNext();&lt;br /&gt;       while (hasNext)&lt;br /&gt;       {&lt;br /&gt;           String key = i.next();&lt;br /&gt;           Attribute value = cntx.getAttribute(key);&lt;br /&gt;           sb.append(key);&lt;br /&gt;           sb.append("=");&lt;br /&gt;           sb.append(value);&lt;br /&gt;           hasNext = i.hasNext();&lt;br /&gt;           if (hasNext)&lt;br /&gt;               sb.append(", ");&lt;br /&gt;       }&lt;br /&gt;&lt;br /&gt;       sb.append("}");&lt;br /&gt;       return sb.toString();&lt;br /&gt;   }   &lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2330120457456880954-4439875792978301989?l=devgrok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devgrok.blogspot.com/feeds/4439875792978301989/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://devgrok.blogspot.com/2008/08/integration-testing-spring-mvc-without.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/4439875792978301989'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/4439875792978301989'/><link rel='alternate' type='text/html' href='http://devgrok.blogspot.com/2008/08/integration-testing-spring-mvc-without.html' title='Integration testing Spring MVC without web server'/><author><name>Christopher Watts</name><uri>http://www.blogger.com/profile/12923587712192007751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://3.bp.blogspot.com/_qoo3n1eKv3E/Swn9NTUeryI/AAAAAAAAC6A/qESuFc9W1CQ/S220/P9260160.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2330120457456880954.post-8782926077592674903</id><published>2008-12-03T05:56:00.011+11:00</published><updated>2010-09-13T23:03:38.945+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JDBC'/><category scheme='http://www.blogger.com/atom/ns#' term='Spring'/><category scheme='http://www.blogger.com/atom/ns#' term='SQL'/><title type='text'>Getting sql parameters from CallableStatementCreatorFactory</title><content type='html'>I had a massive headache trying to work out what data was passed to a procedure call that was using Spring's JdbcTemplate. The problem was, the parameters can be passed in as a map, so all you have is a set of names and value with no idea what order they go in. If you have a lot of statements to sift through then manually rebuilding the sql to execute is a pain.&lt;br /&gt;&lt;br /&gt;After trying many times to work out a way to extend CallableStatementCreatorFactory in order to pull out the information to build an sql statement I eventually reverted to just replacing the whole source file.&lt;br /&gt;Below is the resulting file, with date formatting (and select from dual) directed towards Oracle. Still useful for other vendors as it's pretty simple to adjust. I have no idea why this or something like it wasn't included in spring.&lt;br /&gt;&lt;pre class="brush: java"&gt;/*&lt;br /&gt; * Copyright 2002-2006 the original author or authors.&lt;br /&gt; *&lt;br /&gt; * Licensed under the Apache License, Version 2.0 (the "License");&lt;br /&gt; * you may not use this file except in compliance with the License.&lt;br /&gt; * You may obtain a copy of the License at&lt;br /&gt; *&lt;br /&gt; *      http://www.apache.org/licenses/LICENSE-2.0&lt;br /&gt; *&lt;br /&gt; * Unless required by applicable law or agreed to in writing, software&lt;br /&gt; * distributed under the License is distributed on an "AS IS" BASIS,&lt;br /&gt; * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.&lt;br /&gt; * See the License for the specific language governing permissions and&lt;br /&gt; * limitations under the License.&lt;br /&gt; */&lt;br /&gt;package org.springframework.jdbc.core;&lt;br /&gt; &lt;br /&gt;import java.math.BigDecimal;&lt;br /&gt;import java.sql.CallableStatement;&lt;br /&gt;import java.sql.Connection;&lt;br /&gt;import java.sql.ResultSet;&lt;br /&gt;import java.sql.SQLException;&lt;br /&gt;import java.text.SimpleDateFormat;&lt;br /&gt;import java.util.ArrayList;&lt;br /&gt;import java.util.Date;&lt;br /&gt;import java.util.HashMap;&lt;br /&gt;import java.util.LinkedList;&lt;br /&gt;import java.util.List;&lt;br /&gt;import java.util.Map;&lt;br /&gt; &lt;br /&gt;import org.apache.log4j.Logger;&lt;br /&gt;import org.springframework.dao.InvalidDataAccessApiUsageException;&lt;br /&gt;import org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor;&lt;br /&gt; &lt;br /&gt;/**&lt;br /&gt;* Helper class that can efficiently create multiple CallableStatementCreator objects with different&lt;br /&gt;* parameters based on a SQL statement and a single set of parameter declarations.&lt;br /&gt;*&lt;br /&gt;* CW: updated to include debug which outputs an excutable sql statement with parameters substituted&lt;br /&gt;*&lt;br /&gt;* @author Rod Johnson&lt;br /&gt;* @author Thomas Risberg&lt;br /&gt;* @author Juergen Hoeller&lt;br /&gt;* @author Chris Watts&lt;br /&gt;*/&lt;br /&gt;public class CallableStatementCreatorFactory&lt;br /&gt;{&lt;br /&gt;   private static final Logger logger = Logger.getLogger(CallableStatementCreatorFactory.class);&lt;br /&gt; &lt;br /&gt;   /** The SQL call string, which won't change when the parameters change. */&lt;br /&gt;   private final String callString;&lt;br /&gt; &lt;br /&gt;   /** List of SqlParameter objects. May not be &amp;lt;code&amp;gt;null&amp;lt;/code&amp;gt;. */&lt;br /&gt;   private final List declaredParameters;&lt;br /&gt; &lt;br /&gt;   private int resultSetType = ResultSet.TYPE_FORWARD_ONLY;&lt;br /&gt; &lt;br /&gt;   private boolean updatableResults = false;&lt;br /&gt; &lt;br /&gt;   private NativeJdbcExtractor nativeJdbcExtractor;&lt;br /&gt; &lt;br /&gt;   /**&lt;br /&gt;    * Create a new factory. Will need to add parameters via the addParameter() method or have no&lt;br /&gt;    * parameters.&lt;br /&gt;    */&lt;br /&gt;   public CallableStatementCreatorFactory(String callString)&lt;br /&gt;   {&lt;br /&gt;       this.callString = callString;&lt;br /&gt;       this.declaredParameters = new LinkedList();&lt;br /&gt;   }&lt;br /&gt; &lt;br /&gt;   /**&lt;br /&gt;    * Create a new factory with sql and the given parameters.&lt;br /&gt;    *&lt;br /&gt;    * @param callString&lt;br /&gt;    *            the SQL call string&lt;br /&gt;    * @param declaredParameters&lt;br /&gt;    *            list of SqlParameter objects&lt;br /&gt;    */&lt;br /&gt;   public CallableStatementCreatorFactory(String callString, List declaredParameters)&lt;br /&gt;   {&lt;br /&gt;       this.callString = callString;&lt;br /&gt;       this.declaredParameters = declaredParameters;&lt;br /&gt;   }&lt;br /&gt; &lt;br /&gt;   /**&lt;br /&gt;    * Add a new declared parameter. Order of parameter addition is significant.&lt;br /&gt;    */&lt;br /&gt;   public void addParameter(SqlParameter param)&lt;br /&gt;   {&lt;br /&gt;       this.declaredParameters.add(param);&lt;br /&gt;   }&lt;br /&gt; &lt;br /&gt;   /**&lt;br /&gt;    * Set whether to use prepared statements that return a specific type of ResultSet.&lt;br /&gt;    *&lt;br /&gt;    * @param resultSetType&lt;br /&gt;    *            the ResultSet type&lt;br /&gt;    * @see java.sql.ResultSet#TYPE_FORWARD_ONLY&lt;br /&gt;    * @see java.sql.ResultSet#TYPE_SCROLL_INSENSITIVE&lt;br /&gt;    * @see java.sql.ResultSet#TYPE_SCROLL_SENSITIVE&lt;br /&gt;    */&lt;br /&gt;   public void setResultSetType(int resultSetType)&lt;br /&gt;   {&lt;br /&gt;       this.resultSetType = resultSetType;&lt;br /&gt;   }&lt;br /&gt; &lt;br /&gt;   /**&lt;br /&gt;    * Set whether to use prepared statements capable of returning updatable ResultSets.&lt;br /&gt;    */&lt;br /&gt;   public void setUpdatableResults(boolean updatableResults)&lt;br /&gt;   {&lt;br /&gt;       this.updatableResults = updatableResults;&lt;br /&gt;   }&lt;br /&gt; &lt;br /&gt;   /**&lt;br /&gt;    * Specify the NativeJdbcExtractor to use for unwrapping CallableStatements, if any.&lt;br /&gt;    */&lt;br /&gt;   public void setNativeJdbcExtractor(NativeJdbcExtractor nativeJdbcExtractor)&lt;br /&gt;   {&lt;br /&gt;       this.nativeJdbcExtractor = nativeJdbcExtractor;&lt;br /&gt;   }&lt;br /&gt; &lt;br /&gt;   /**&lt;br /&gt;    * Return a new CallableStatementCreator instance given this parameters.&lt;br /&gt;    *&lt;br /&gt;    * @param inParams&lt;br /&gt;    *            List of parameters. May be &amp;lt;code&amp;gt;null&amp;lt;/code&amp;gt;.&lt;br /&gt;    */&lt;br /&gt;   public CallableStatementCreator newCallableStatementCreator(Map inParams)&lt;br /&gt;   {&lt;br /&gt;       return new CallableStatementCreatorImpl(inParams != null ? inParams : new HashMap());&lt;br /&gt;   }&lt;br /&gt; &lt;br /&gt;   /**&lt;br /&gt;    * Return a new CallableStatementCreator instance given this parameter mapper.&lt;br /&gt;    *&lt;br /&gt;    * @param inParamMapper&lt;br /&gt;    *            ParameterMapper implementation that will return a Map of parameters. May not be&lt;br /&gt;    *            &amp;lt;code&amp;gt;null&amp;lt;/code&amp;gt;.&lt;br /&gt;    */&lt;br /&gt;   public CallableStatementCreator newCallableStatementCreator(ParameterMapper inParamMapper)&lt;br /&gt;   {&lt;br /&gt;       return new CallableStatementCreatorImpl(inParamMapper);&lt;br /&gt;   }&lt;br /&gt; &lt;br /&gt;   /**&lt;br /&gt;    * CallableStatementCreator implementation returned by this class.&lt;br /&gt;    */&lt;br /&gt;   private class CallableStatementCreatorImpl implements CallableStatementCreator, SqlProvider,&lt;br /&gt;           ParameterDisposer&lt;br /&gt;   {&lt;br /&gt; &lt;br /&gt;       private ParameterMapper inParameterMapper;&lt;br /&gt; &lt;br /&gt;       private Map inParameters;&lt;br /&gt; &lt;br /&gt;       /**&lt;br /&gt;        * Create a new CallableStatementCreatorImpl.&lt;br /&gt;        *&lt;br /&gt;        * @param inParamMapper&lt;br /&gt;        *            ParameterMapper implementation for mapping input parameters. May not be&lt;br /&gt;        *            &amp;lt;code&amp;gt;null&amp;lt;/code&amp;gt;.&lt;br /&gt;        */&lt;br /&gt;       public CallableStatementCreatorImpl(ParameterMapper inParamMapper)&lt;br /&gt;       {&lt;br /&gt;           this.inParameterMapper = inParamMapper;&lt;br /&gt;       }&lt;br /&gt; &lt;br /&gt;       /**&lt;br /&gt;        * Create a new CallableStatementCreatorImpl.&lt;br /&gt;        *&lt;br /&gt;        * @param inParams&lt;br /&gt;        *            list of SqlParameter objects. May not be &amp;lt;code&amp;gt;null&amp;lt;/code&amp;gt;.&lt;br /&gt;        */&lt;br /&gt;       public CallableStatementCreatorImpl(Map inParams)&lt;br /&gt;       {&lt;br /&gt;           this.inParameters = inParams;&lt;br /&gt;       }&lt;br /&gt; &lt;br /&gt;       public CallableStatement createCallableStatement(Connection con) throws SQLException&lt;br /&gt;       {&lt;br /&gt;           // If we were given a ParameterMapper - we must let the mapper do its thing to create the Map.&lt;br /&gt;           if (this.inParameterMapper != null)&lt;br /&gt;           {&lt;br /&gt;               this.inParameters = this.inParameterMapper.createMap(con);&lt;br /&gt;           }&lt;br /&gt;           else&lt;br /&gt;           {&lt;br /&gt;               if (this.inParameters == null)&lt;br /&gt;               {&lt;br /&gt;                   throw new InvalidDataAccessApiUsageException(&lt;br /&gt;                           "A ParameterMapper or a Map of parameters must be provided");&lt;br /&gt;               }&lt;br /&gt;           }&lt;br /&gt; &lt;br /&gt;           CallableStatement cs = null;&lt;br /&gt;           if (resultSetType == ResultSet.TYPE_FORWARD_ONLY &amp;&amp; !updatableResults)&lt;br /&gt;           {&lt;br /&gt;               cs = con.prepareCall(callString);&lt;br /&gt;           }&lt;br /&gt;           else&lt;br /&gt;           {&lt;br /&gt;               cs = con.prepareCall(callString, resultSetType, updatableResults ? ResultSet.CONCUR_UPDATABLE&lt;br /&gt;                       : ResultSet.CONCUR_READ_ONLY);&lt;br /&gt;           }&lt;br /&gt; &lt;br /&gt;           // Determine CallabeStatement to pass to custom types.&lt;br /&gt;           CallableStatement csToUse = cs;&lt;br /&gt;           if (nativeJdbcExtractor != null)&lt;br /&gt;           {&lt;br /&gt;               csToUse = nativeJdbcExtractor.getNativeCallableStatement(cs);&lt;br /&gt;           }&lt;br /&gt; &lt;br /&gt;           int sqlColIndx = 1;&lt;br /&gt;           ArrayList&amp;lt;Object&amp;gt; parameterValues = new ArrayList&amp;lt;Object&amp;gt;();&lt;br /&gt;           for (int i = 0; i &amp;lt; declaredParameters.size(); i++)&lt;br /&gt;           {&lt;br /&gt;               SqlParameter declaredParameter = (SqlParameter) declaredParameters.get(i);&lt;br /&gt;               if (!declaredParameter.isResultsParameter())&lt;br /&gt;               {&lt;br /&gt;                   // So, it's a call parameter - part of the call string.&lt;br /&gt;                   // Get the value - it may still be null.&lt;br /&gt;                   Object inValue = this.inParameters.get(declaredParameter.getName());&lt;br /&gt;                   if (declaredParameter instanceof ResultSetSupportingSqlParameter)&lt;br /&gt;                   {&lt;br /&gt;                       // It's an output parameter: SqlReturnResultSet parameters already excluded.&lt;br /&gt;                       // It need not (but may be) supplied by the caller.&lt;br /&gt;                       if (declaredParameter instanceof SqlOutParameter)&lt;br /&gt;                       {&lt;br /&gt;                           parameterValues.add(null);// out parameters&lt;br /&gt;                           if (declaredParameter.getTypeName() != null)&lt;br /&gt;                           {&lt;br /&gt;                               cs.registerOutParameter(sqlColIndx, declaredParameter.getSqlType(),&lt;br /&gt;                                       declaredParameter.getTypeName());&lt;br /&gt;                           }&lt;br /&gt;                           else&lt;br /&gt;                           {&lt;br /&gt;                               if (declaredParameter.getScale() != null)&lt;br /&gt;                               {&lt;br /&gt;                                   cs.registerOutParameter(sqlColIndx, declaredParameter.getSqlType(),&lt;br /&gt;                                           declaredParameter.getScale().intValue());&lt;br /&gt;                               }&lt;br /&gt;                               else&lt;br /&gt;                               {&lt;br /&gt;                                   cs.registerOutParameter(sqlColIndx, declaredParameter.getSqlType());&lt;br /&gt;                               }&lt;br /&gt;                           }&lt;br /&gt;                           if ((declaredParameter).isInputValueProvided() || inValue != null)&lt;br /&gt;                           {&lt;br /&gt;                               StatementCreatorUtils.setParameterValue(csToUse, sqlColIndx,&lt;br /&gt;                                       declaredParameter, inValue);&lt;br /&gt;                           }&lt;br /&gt;                       }&lt;br /&gt;                   }&lt;br /&gt;                   else&lt;br /&gt;                   {&lt;br /&gt;                       // It's an input parameter- must be supplied by the caller.&lt;br /&gt;                       if (!this.inParameters.containsKey(declaredParameter.getName()))&lt;br /&gt;                       {&lt;br /&gt;                           throw new InvalidDataAccessApiUsageException("Required input parameter '"&lt;br /&gt;                                   + declaredParameter.getName() + "' is missing");&lt;br /&gt;                       }&lt;br /&gt;                       StatementCreatorUtils.setParameterValue(csToUse, sqlColIndx, declaredParameter,&lt;br /&gt;                               inValue);&lt;br /&gt;                       parameterValues.add(inValue);// out parameters&lt;br /&gt;                   }&lt;br /&gt;                   sqlColIndx++;&lt;br /&gt;               }&lt;br /&gt;           }&lt;br /&gt; &lt;br /&gt;           if (logger.isDebugEnabled())&lt;br /&gt;           {&lt;br /&gt;               logger.debug(buildCallableSql(callString, parameterValues));&lt;br /&gt;           }&lt;br /&gt;           return cs;&lt;br /&gt;       }&lt;br /&gt; &lt;br /&gt;       public String getSql()&lt;br /&gt;       {&lt;br /&gt;           return callString;&lt;br /&gt;       }&lt;br /&gt; &lt;br /&gt;       public void cleanupParameters()&lt;br /&gt;       {&lt;br /&gt;           if (this.inParameters != null)&lt;br /&gt;           {&lt;br /&gt;               StatementCreatorUtils.cleanupParameters(this.inParameters.values());&lt;br /&gt;           }&lt;br /&gt;       }&lt;br /&gt; &lt;br /&gt;       public String toString()&lt;br /&gt;       {&lt;br /&gt;           StringBuffer buf = new StringBuffer(&lt;br /&gt;                   "CallableStatementCreatorFactory.CallableStatementCreatorImpl: sql=[");&lt;br /&gt;           buf.append(callString).append("]; parameters=").append(this.inParameters);&lt;br /&gt;           return buf.toString();&lt;br /&gt;       }&lt;br /&gt;   }&lt;br /&gt; &lt;br /&gt;   private static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");&lt;br /&gt; &lt;br /&gt;   public static String buildCallableSql(String sql, List&amp;lt;Object&amp;gt; orderedParams)&lt;br /&gt;   {&lt;br /&gt;       //StringBuilder sb = new StringBuilder(sql);&lt;br /&gt;       String sqlStr = sql;&lt;br /&gt;       if (sqlStr.startsWith("{? = call "))&lt;br /&gt;       {&lt;br /&gt;           //remove first (output parameter)&lt;br /&gt;           orderedParams.remove(0);&lt;br /&gt;           sqlStr = sqlStr.substring("{? = call ".length());&lt;br /&gt;           sqlStr = sqlStr.substring(0, sqlStr.length() - 1);&lt;br /&gt;           sqlStr = "select " + sqlStr + " from dual;";&lt;br /&gt;       }&lt;br /&gt;       for (Object val : orderedParams)&lt;br /&gt;       {&lt;br /&gt;           String value;&lt;br /&gt;           if (val == null)&lt;br /&gt;               value = "null";&lt;br /&gt;           else if (val instanceof String)&lt;br /&gt;               value = "'" + ((String) val).replace("'", "''") + "'"; //escape&lt;br /&gt;           else if (val instanceof Date)&lt;br /&gt;               value = "TO_DATE('" + dateFormat.format((Date) val) + "', 'YYYY/MM/DD HH24:MI:SS')";&lt;br /&gt;           else if (val instanceof Integer || val instanceof Long || val instanceof BigDecimal&lt;br /&gt;                   || val instanceof Double)&lt;br /&gt;               value = val.toString().replace("'", "''"); //escape&lt;br /&gt;           else&lt;br /&gt;               value = "'" + val.toString().replace("'", "''") + "'"; //escape&lt;br /&gt; &lt;br /&gt;           sqlStr = sqlStr.replaceFirst("[?]", value);&lt;br /&gt;       }&lt;br /&gt;       return sqlStr;&lt;br /&gt;   }&lt;br /&gt;}&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2330120457456880954-8782926077592674903?l=devgrok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devgrok.blogspot.com/feeds/8782926077592674903/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://devgrok.blogspot.com/2008/12/getting-sql-parameters-from.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/8782926077592674903'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/8782926077592674903'/><link rel='alternate' type='text/html' href='http://devgrok.blogspot.com/2008/12/getting-sql-parameters-from.html' title='Getting sql parameters from CallableStatementCreatorFactory'/><author><name>Christopher Watts</name><uri>http://www.blogger.com/profile/12923587712192007751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://3.bp.blogspot.com/_qoo3n1eKv3E/Swn9NTUeryI/AAAAAAAAC6A/qESuFc9W1CQ/S220/P9260160.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2330120457456880954.post-4315319795473244204</id><published>2008-11-26T02:27:00.009+11:00</published><updated>2009-06-12T07:53:39.681+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Spring'/><category scheme='http://www.blogger.com/atom/ns#' term='Hibernate'/><title type='text'>Hibernate's Criteria API</title><content type='html'>Hibernate has a &lt;a href="http://www.hibernate.org/hib_docs/v3/api/org/hibernate/Criteria.html"&gt;Criteria&lt;/a&gt; API which allows you to dynamic build up filter conditions and set various join options. It is perfectly suited for flexible searches on entities, however there are areas in falls down in and the documentation is scarce.&lt;br /&gt;Criteria instances can be either created from the hibernate Session or a DetachedCriteria can be created for later execution or for passing into Spring's &lt;a href="http://static.springframework.org/spring/docs/2.5.x/api/org/springframework/orm/hibernate3/HibernateTemplate.html#findByCriteria%28org.hibernate.criterion.DetachedCriteria%29"&gt;HibernateTemplate&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The first thing that is explicitly mentioned is that references to properties can only be one deep, properties on child entities must be mapped via &lt;span style="font-weight: bold;"&gt;createAlias &lt;/span&gt;/ &lt;span style="font-weight: bold;"&gt;createCriteria &lt;/span&gt;call. For example, the following will give a "&lt;span style="font-style: italic;"&gt;org.hibernate.QueryException: could not resolve property: child.property of: com.example.model.Parent&lt;/span&gt;".&lt;br /&gt;&lt;pre name="code" class="java"&gt;DetachedCriteria criteria = DetachedCriteria.forClass(Parent.class,"parent");&lt;br /&gt;criteria.add(Restrictions.eq("parent.child.property", "somevalue");&lt;/pre&gt;&lt;br /&gt;Instead the child entity must be explicitly join by calling the following:&lt;br /&gt;&lt;pre name="code" class="java"&gt;DetachedCriteria criteria = DetachedCriteria.forClass(Parent.class,"parent");&lt;br /&gt;criteria.createAlias("parent.child","thechild");&lt;br /&gt;criteria.add(Restrictions.eq("thechild.property", "somevalue");&lt;/pre&gt;&lt;br /&gt;Creating a join is not nesecary, if just the identifier is being referenced:&lt;br /&gt;&lt;pre name="code" class="java"&gt;DetachedCriteria criteria = DetachedCriteria.forClass(Parent.class,"parent");&lt;br /&gt;criteria.add(Restrictions.eq("parent.child.id", 1);&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Add an IN condition.&lt;/span&gt;&lt;br /&gt;To add a "&lt;span style="font-style: italic;"&gt;where field in subquery&lt;/span&gt;", two separate criteria are required. One for the main (root) entity, and the other to retrieve the values for the IN list.&lt;br /&gt;The following retrives the orders for which it has an order item which the product has a stock level of ZERO. The result transformer is used to only retrieve one row per entity, instead of having multiple rows as a result of the join on a one-to-many relationship.&lt;br /&gt;&lt;pre name="code" class="java"&gt;DetachedCriteria ids = DetachedCriteria.forClass(ProductStock.class, "stock");&lt;br /&gt;ids.add(Restrictions.eq("stock.stockLevel", 0));&lt;br /&gt;ids.setProjection(Property.forName("productId"));&lt;br /&gt;&lt;br /&gt;DetachedCriteria criteria = DetachedCriteria.forClass(Order.class, "order");&lt;br /&gt;criteria.createAlias("order.orderItems", "items", CriteriaSpecification.LEFT_JOIN);&lt;br /&gt;criteria.add(Subqueries.propertyIn("items.productId", ids));&lt;br /&gt;criteria.setResultTransformer(Criteria.ROOT_ENTITY);&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Performing a WHERE EXISTS&lt;/span&gt;&lt;br /&gt;An exists is a variation on the above query, sometimes useful when the join could be large, or when it simply results in a faster execution.&lt;br /&gt;&lt;pre name="code" class="java"&gt;DetachedCriteria ids = DetachedCriteria.forClass(ProductStock.class, "stock");&lt;br /&gt;ids.add(Restrictions.eqProperty("stock.productId", "items.productId"));&lt;br /&gt;ids.add(Restrictions.eq("stock.stockLevel", 0));&lt;br /&gt;&lt;br /&gt;DetachedCriteria criteria = DetachedCriteria.forClass(Order.class, "order");&lt;br /&gt;criteria.createAlias("order.orderItems", "items", CriteriaSpecification.LEFT_JOIN);&lt;br /&gt;criteria.add(Subqueries.exists(ids));&lt;/pre&gt;&lt;br /&gt;However you cannot do arbitrary joins between 2 unassociated tables. All associations have to be defined in the mapping files before a criteria can be joined (i.e. a createAlias), the IN and EXISTS are the only other alternative.&lt;br /&gt;There are other limitations which I have had to circumvent by either doing extra set mappings or extending Hibernate's classes.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2330120457456880954-4315319795473244204?l=devgrok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devgrok.blogspot.com/feeds/4315319795473244204/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://devgrok.blogspot.com/2008/11/hibernates-criteria-api.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/4315319795473244204'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/4315319795473244204'/><link rel='alternate' type='text/html' href='http://devgrok.blogspot.com/2008/11/hibernates-criteria-api.html' title='Hibernate&apos;s Criteria API'/><author><name>Christopher Watts</name><uri>http://www.blogger.com/profile/12923587712192007751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://3.bp.blogspot.com/_qoo3n1eKv3E/Swn9NTUeryI/AAAAAAAAC6A/qESuFc9W1CQ/S220/P9260160.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2330120457456880954.post-1526572369753472659</id><published>2008-11-19T04:04:00.005+11:00</published><updated>2009-06-12T07:53:23.232+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Hibernate'/><title type='text'>Hibernate's Lazy Loading Quirks</title><content type='html'>I have come across two problems which have caused me no end of grief which turned out to be pretty simple.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;LazyInitializationException&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;When using the Spring &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;OpenSessionInViewFilter&lt;/span&gt;, I refer to lazily initialised properties (mapped as &lt;span style="font-style: italic;"&gt;many-to-one&lt;/span&gt; or &lt;span style="font-style: italic;"&gt;one-to-one&lt;/span&gt;) in the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;JSP&lt;/span&gt; pages. However I was getting a scenario where if a user performed a certain action I would get the following error:&lt;br /&gt;&lt;blockquote&gt;org.hibernate.LazyInitializationException: could not initialize proxy - no Session&lt;/blockquote&gt;After a lot of debugging and sifting through &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;hibernate's&lt;/span&gt; source I traced it to a bit  of code I had used that someone had posted for having a paged interval collection for hibernate (as oracle doesn't support server side paging). The culprit line of code was:&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;hibernateTemplate&lt;/span&gt;.clear();&lt;br /&gt;&lt;br /&gt;//which is defined in &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;Spring's&lt;/span&gt; wrapper as&lt;br /&gt;public void clear() throws &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;DataAccessException&lt;/span&gt; {&lt;br /&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;executeWithNativeSession&lt;/span&gt;(new &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;HibernateCallback&lt;/span&gt;() {&lt;br /&gt;  public Object &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;doInHibernate&lt;/span&gt;(Session session) {&lt;br /&gt;      session.clear();&lt;br /&gt;      return null;&lt;br /&gt;  }&lt;br /&gt;});&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;This causes all objects that had been loaded previously by that session to be DISCONNECTED from the session. Hence the slightly misleading message. The session is still open, its just longer associated with it.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;many-to-one relationships not being lazy&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;I had a problem with relationships which I had defined as being lazy not being lazily loaded which I only discovered after I turned of the second level cache off. With the cache on, I never saw the requests it made internally to load an entire child-parent-etc hierarchy (which is one bonus of using a cache).&lt;br /&gt;After spending what seemed like hours, sifting through the documentation on lazy loading, fiddling with settings, checking the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_10"&gt;bytecode&lt;/span&gt; libraries, I finally discovered the cause. To get around cases where the 'static' data that these entities were referring to were missing due to some &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_11"&gt;muppet&lt;/span&gt; bodging the data, I had set attribute &lt;code&gt;not-found="ignore"&lt;/code&gt;. This prevents the JSP page blowing up when you try and access the property when all you really want is to display a blank field or maybe a message. However, in order for a relational property to be lazy loaded it must be set to &lt;code&gt;not-found="exception"&lt;/code&gt; (which is the default). Its a trade off between dealing with the exceptions where you don't expect them and the performance hit.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2330120457456880954-1526572369753472659?l=devgrok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devgrok.blogspot.com/feeds/1526572369753472659/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://devgrok.blogspot.com/2008/11/hibernates-lazy-loading-quirks.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/1526572369753472659'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/1526572369753472659'/><link rel='alternate' type='text/html' href='http://devgrok.blogspot.com/2008/11/hibernates-lazy-loading-quirks.html' title='Hibernate&apos;s Lazy Loading Quirks'/><author><name>Christopher Watts</name><uri>http://www.blogger.com/profile/12923587712192007751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://3.bp.blogspot.com/_qoo3n1eKv3E/Swn9NTUeryI/AAAAAAAAC6A/qESuFc9W1CQ/S220/P9260160.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2330120457456880954.post-6120328849010895958</id><published>2008-11-17T20:50:00.032+11:00</published><updated>2011-12-15T12:15:10.483+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Unit Testing'/><category scheme='http://www.blogger.com/atom/ns#' term='Spring'/><title type='text'>EasyMock and Spring Autowiring</title><content type='html'>&lt;a href="http://springframework.org/"&gt;Spring Framework&lt;/a&gt; provides an easy way to unit test components in isolation and &lt;a href="http://www.easymock.org/"&gt;EasyMock&lt;/a&gt; provides a quick way to create mock objects with very little effort. Combining them together, Spring can be used to create the mock objects so that beans that use auto wiring to inject dependencies can be tested without having to modify the classes or create complex context configuration files.&lt;br /&gt;&lt;br /&gt;Creating mock objects using spring is simple, here is a sample &lt;span style="font-style: italic;"&gt;beans.xml&lt;/span&gt;:&lt;br /&gt;&lt;pre class="brush:xml"&gt;&amp;lt;bean class="org.easymock.EasyMock" factory-method="createNiceMock" primary="true" id="someServiceMock"&gt;&lt;br /&gt;   &amp;lt;constructor-arg value="com.example.service.SomeService" /&gt;&lt;br /&gt;&amp;lt;/bean&gt;&lt;br /&gt;&lt;/pre&gt;This creates a mock object from the given interface. The primary is used to indicate that it should be used for autowiring which is useful when component scanning is used together with  @Component tags. When you want to refer to the actual implementation you would use @Qualifier("someService").&lt;br /&gt;&lt;br /&gt;If interfaces aren't used then the following &lt;span style="font-style: italic;"&gt;beans.xml&lt;/span&gt; is used.&lt;br /&gt;&lt;pre class="brush:xml"&gt;&amp;lt;bean class="org.easymock.classextension.EasyMock" factory-method="createNiceMock" primary="true" id="someDAO" &gt;&lt;br /&gt;   &amp;lt;constructor-arg value="com.example.dao.SomeDAO" /&gt;&lt;br /&gt;   &amp;lt;property name="sessionFactory"&gt;&lt;br /&gt;      &amp;lt;null /&gt;&lt;br /&gt;   &amp;lt;/property&gt;&lt;br /&gt;&amp;lt;/bean&gt;&lt;br /&gt;&lt;/pre&gt;Performing the test is relatively simple and with autowiring configuration is minimal. Below I have used the classextension static imports as it can be used for both types of mocks. However the standard expect/replay/etc cannot be used with classextension created mocks.&lt;pre name="code" class="java"&gt;import static org.easymock.EasyMock.expect;&lt;br /&gt;import static org.easymock.EasyMock.replay;&lt;br /&gt;import static org.easymock.EasyMock.reset;&lt;br /&gt;import static org.hamcrest.CoreMatchers.equalTo;&lt;br /&gt;import static org.hamcrest.CoreMatchers.notNullValue;&lt;br /&gt;import static org.hamcrest.CoreMatchers.nullValue;&lt;br /&gt;import org.junit.Before;&lt;br /&gt;import org.junit.Test;&lt;br /&gt;import org.springframework.ui.ModelMap;&lt;br /&gt;&lt;br /&gt;@RunWith(SpringJUnit4ClassRunner.class)&lt;br /&gt;@ContextConfiguration(locations = { "classpath:/controller-beans.xml" })&lt;br /&gt;public class TestSampleController&lt;br /&gt;{&lt;br /&gt;   /** UNIT UNDER TEST */&lt;br /&gt;   @Autowired&lt;br /&gt;   private SampleController controller;&lt;br /&gt;   /** mock object */&lt;br /&gt;   @Autowired&lt;br /&gt;   private SampleService service;&lt;br /&gt;&lt;br /&gt;   /**&lt;br /&gt;   * Called before each test.&lt;br /&gt;   */&lt;br /&gt;   @Before&lt;br /&gt;   public void setUp() throws Exception&lt;br /&gt;   {&lt;br /&gt;      reset(service);&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   @Test&lt;br /&gt;   public void testPage() throws Exception&lt;br /&gt;   {&lt;br /&gt;      //data&lt;br /&gt;      List data = new LinkedList();&lt;br /&gt;&lt;br /&gt;      //prepare&lt;br /&gt;      expect(service.getData()).andReturn(data);&lt;br /&gt;      replay(service);&lt;br /&gt;&lt;br /&gt;      //perform&lt;br /&gt;      ModelMap map = new ModelMap();&lt;br /&gt;      String result = controller.page(map);&lt;br /&gt;&lt;br /&gt;      //verify&lt;br /&gt;      assertThat("result", result, equalTo("expected");&lt;br /&gt;      assertThat((Map&amp;lt;String,Object&gt;) map, Matchers.hasKey("someobj"));&lt;br /&gt;      assertThat("someobj", map.get("someobj"), notNullValue());&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;Finally there are cases where you need the mock object ready to give a response during load up, such as in an &lt;a href="http://static.springframework.org/spring/docs/2.5.x/api/org/springframework/beans/factory/InitializingBean.html"&gt;InitializingBean&lt;/a&gt;. In those cases the following util class can be adapted:&lt;br /&gt;&lt;pre name="code" class="java"&gt;public class MockUtil&lt;br /&gt;{&lt;br /&gt;   public static &amp;lt;T&gt; T createNiceMock(Class&amp;lt;T&gt; toMock, boolean replay)&lt;br /&gt;   {&lt;br /&gt;      IMocksControl control = EasyMock.createNiceControl();&lt;br /&gt;      T mock = control.createMock(toMock);&lt;br /&gt;      if (replay)&lt;br /&gt;      {&lt;br /&gt;         control.replay();&lt;br /&gt;      }&lt;br /&gt;      return mock;&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;pre class="brush:xml"&gt;&amp;lt;bean id="dataServiceMock" class="com.example.test.MockUtil"  factory-method="createNiceMock" primary="true"&gt;&lt;br /&gt;   &amp;lt;constructor-arg value="com.example.service.DataService" /&gt;&lt;br /&gt;   &amp;lt;constructor-arg value="true"/&gt;&lt;br /&gt;&amp;lt;/bean&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2330120457456880954-6120328849010895958?l=devgrok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devgrok.blogspot.com/feeds/6120328849010895958/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://devgrok.blogspot.com/2008/11/easymock-and-spring-autowiring.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/6120328849010895958'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2330120457456880954/posts/default/6120328849010895958'/><link rel='alternate' type='text/html' href='http://devgrok.blogspot.com/2008/11/easymock-and-spring-autowiring.html' title='EasyMock and Spring Autowiring'/><author><name>Christopher Watts</name><uri>http://www.blogger.com/profile/12923587712192007751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://3.bp.blogspot.com/_qoo3n1eKv3E/Swn9NTUeryI/AAAAAAAAC6A/qESuFc9W1CQ/S220/P9260160.JPG'/></author><thr:total>0</thr:total></entry></feed>
