<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule"
>

<channel>
	<title>cum grano salis — nobody likes a clever bastard &#187; Software Development</title>
	<atom:link href="http://datenschwanz.net/category/software-development/feed/" rel="self" type="application/rss+xml" />
	<link>http://datenschwanz.net</link>
	<description>science, technology, politics, and vitriol at the bleeding edge of the crinkum-crankum we call Internet. also, food.</description>
	<lastBuildDate>Tue, 07 Sep 2010 05:15:37 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-nd/3.0/us/</creativeCommons:license>
		<item>
		<title>EGit May Eat Your Project</title>
		<link>http://datenschwanz.net/2010/03/30/egit-may-eat-your-project/</link>
		<comments>http://datenschwanz.net/2010/03/30/egit-may-eat-your-project/#comments</comments>
		<pubDate>Tue, 30 Mar 2010 23:49:24 +0000</pubDate>
		<dc:creator>studmuffin</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Eclipse]]></category>
		<category><![CDATA[EGit]]></category>
		<category><![CDATA[Git]]></category>
		<category><![CDATA[Subversion]]></category>

		<guid isPermaLink="false">http://datenschwanz.net/?p=413</guid>
		<description><![CDATA[




I moved a few client repositories over to Git from Subversion over the weekend and I started using EGit. It works pretty well, other than that it&#8217;s missing the Team Synchronize functionality, which is sorely missed. The most you get is a single file diff. The only thing you have to watch out for is [...]]]></description>
			<content:encoded><![CDATA[<!-- Easy AdSense V2.82 -->
<!-- Post[count: 2] -->
<div class="ezAdsense adsense adsense-leadin" style="text-align:center;margin:12px;"><script type="text/javascript"><!--
google_ad_client = "pub-6651136519429825";
/* DS, top content, 468x60, created 11/25/09 */
google_ad_slot = "2784801780";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></div><p>I moved a few client repositories over to <a href="http://git-scm.com/">Git</a> from <a href="http://subversion.tigris.org/">Subversion</a> over the weekend and I started using <a href="http://www.eclipse.org/egit/">EGit</a>. It works pretty well, other than that it&#8217;s missing the Team Synchronize functionality, which is sorely missed. The most you get is a single file diff. The only thing you have to watch out for is renaming projects. For some reason, and <a href="http://osdir.com/ml/git/2009-03/msg02013.html">this goes back to March 2009</a> I guess, it loses its configuration. None of the decorators will be there anymore and there will be no mention of your respository. If you check the Error Log, you&#8217;ll see an error something like this:</p>
<pre class="brush: plain; light: true; wrap-lines: false;">
Git team provider configuration has gone missing.

java.io.FileNotFoundException: /home/xxx/workspace/.metadata/.plugins/org.eclipse.core.resources/.projects/&lt;projectname&gt;/org.eclipse.egit.core/GitProjectData.properties (No such file or directory)
at java.io.FileInputStream.open(Native Method)
at java.io.FileInputStream.&lt;init&gt;(FileInputStream.java:106)
at org.eclipse.egit.core.project.GitProjectData.load(GitProjectData.java:402)
at org.eclipse.egit.core.project.GitProjectData.get(GitProjectData.java:165)
at org.eclipse.egit.core.GitProvider.getData(GitProvider.java:69)
at org.eclipse.egit.core.project.RepositoryMapping.getMapping(RepositoryMapping.java:244)
at org.eclipse.egit.ui.Activator$RCS.run(Activator.java:322)
at org.eclipse.core.internal.jobs.Worker.run(Worker.java:55)
</pre>
<p>It&#8217;s easily fixed, though. Just recreate that file with contents like this:</p>
<pre class="brush: plain; light: true;">
#GitProjectData
#Mon Mar 29 08:01:28 CDT 2010
.gitdir=.git
</pre>
<p>Voila.</p>
]]></content:encoded>
			<wfw:commentRss>http://datenschwanz.net/2010/03/30/egit-may-eat-your-project/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-nd/3.0/us/</creativeCommons:license>
	</item>
		<item>
		<title>facelets.BUILD_BEFORE_RESTORE brokenness</title>
		<link>http://datenschwanz.net/2010/02/01/facelets-build_before_restore-brokenness/</link>
		<comments>http://datenschwanz.net/2010/02/01/facelets-build_before_restore-brokenness/#comments</comments>
		<pubDate>Mon, 01 Feb 2010 17:01:29 +0000</pubDate>
		<dc:creator>studmuffin</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Facelets]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[JSF]]></category>

		<guid isPermaLink="false">http://datenschwanz.net/?p=390</guid>
		<description><![CDATA[I have finally had some time to sit down and figure out why submitted form data was disappearing when there were form validation errors. I tracked it down to facelets.BUILD_BEFORE_RESTORE, yet another one of Facelets completely undocumented features.
You may be wondering why I had it enabled in the first place, since I didn&#8217;t read the [...]]]></description>
			<content:encoded><![CDATA[<p>I have finally had some time to sit down and figure out why submitted form data was disappearing when there were form validation errors. I tracked it down to facelets.BUILD_BEFORE_RESTORE, yet another one of Facelets completely undocumented features.</p>
<p>You may be wondering why I had it enabled in the first place, since I didn&#8217;t read the documentation that doesn&#8217;t exist. Well, I&#8217;m dealing with a few sizable forms and a pretty small heap, and according to <a href="https://javaserverfaces.dev.java.net/issues/show_bug.cgi?id=1176">this Facelets enhancement</a>, I would get a magical 30-60% memory savings. <strong>Great</strong>, <em>except it breaks everything.</em></p>
<p>BUILD_BEFORE_RESTORE <a href="http://sfjsf.blogspot.com/2006/03/fixing-jsf-state-saving-progress.html">seems to go back to 2006</a>, when it was added to save on saved state size. 10k down to 600 bytes sure sounds like a big deal, <em>except it breaks everything.</em></p>
<p><a href="http://www.jtraining.com/blogs/faceletsbuild-before-restore-will-eat-your-richfaces.html">I&#8217;m not the first to notice this</a>, and people have been having problems with it ever since:</p>
<ul>
<li><a href="http://markmail.org/message/kbrh5roud4lhkx4d">net.java.dev.facelets.users [Facelets] BUILD_BEFORE_RESTORE failure</a></li>
<li><a href="http://markmail.org/message/hhy6ygifjaxcdad5">net.java.dev.facelets.dev CACHE_VEW_ROOT=false and BUILD_BEFORE_RESTORE=true</a></li>
<li><a href="http://seamframework.org/Community/FaceletsBUILDBEFORERESTOREBreaksHcommandButtonInSeam">facelets.BUILD_BEFORE_RESTORE breaks h:commandButton in seam</a></li>
<li><a href="http://www.logikdev.com/2009/11/25/no-saved-view-state/">No saved view state</a></li>
</ul>
<p>Similar behavior was noted and fixed in MyFaces, but it was related to UIInput. Maybe the mechanism is similar.</p>
<p>So, I went back and took out the web.xml mods. Mojarra didn&#8217;t like this. It didn&#8217;t break, but it felt it necessary to recommend that I break it back to where it was:</p>
<style>
div.plainred td.content code.plain { color: red !important; }
</style>
<pre class="brush: plain; class-name: plainred; light: true;">
WARNING: facelets.RECREATE_VALUE_EXPRESSION_ON_BUILD_BEFORE_RESTORE is set to 'true' but facelets.BUILD_BEFORE_RESTORE is set to 'false' or unset. To use facelets.RECREATE_VALUE_EXPRESSION_ON_BUILD_BEFORE_RESTORE you must also set facelets.BUILD_BEFORE_RESTORE to 'true'!
</pre>
<p>Sweet. facelets.RECREATE_VALUE_EXPRESSION_ON_BUILD_BEFORE_RESTORE is true by default, so you need to go back into your web.xml and disable it if you don&#8217;t want to see this nagging message all of the time. If you work in a team, you almost certainly want to squelch this message so someone who isn&#8217;t <em>in the know</em> doesn&#8217;t go in and break everything because the machine told them to.</p>
]]></content:encoded>
			<wfw:commentRss>http://datenschwanz.net/2010/02/01/facelets-build_before_restore-brokenness/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-nd/3.0/us/</creativeCommons:license>
	</item>
		<item>
		<title>EclipseLink Hates MySQL&#8230; Probably</title>
		<link>http://datenschwanz.net/2010/01/22/eclipselink-hates-mysql-probably/</link>
		<comments>http://datenschwanz.net/2010/01/22/eclipselink-hates-mysql-probably/#comments</comments>
		<pubDate>Fri, 22 Jan 2010 11:00:41 +0000</pubDate>
		<dc:creator>studmuffin</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[EclipseLink]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[JPA]]></category>
		<category><![CDATA[MySQL]]></category>

		<guid isPermaLink="false">http://datenschwanz.net/?p=383</guid>
		<description><![CDATA[Being TopLink&#8217;s mutant flipper baby, it&#8217;s no surprise that EclipseLink&#8217;s (2.0.0) support of MySQL is substandard. If you have been using the two of them together, you may have noticed that LOBs don&#8217;t really work quite right. Some of the blame is probably for MySQL, with its multiple length-specific LOB column types, but it at [...]]]></description>
			<content:encoded><![CDATA[<p>Being TopLink&#8217;s mutant flipper baby, it&#8217;s no surprise that EclipseLink&#8217;s (2.0.0) support of MySQL is substandard. If you have been using the two of them together, you may have noticed that LOBs don&#8217;t really work quite right. Some of the blame is probably for MySQL, with its multiple length-specific LOB column types, but it at least handles specified lengths and does the work for you. So, if you have been getting exceptions when you&#8217;re trying to insert a bunch of data, you&#8217;re using EL&#8217;s DDL generation, and you have been lazy about fixing it yourself, read on&#8230;</p>
<p><span id="more-383"></span><br />
64000. Yep, that&#8217;s it. (Insert &#8220;64k ought to be enough&#8221; joke.) That&#8217;s all you get if you use a LOB type with EL and MySQL. It&#8217;s hard coded and it ignores the @Column length. I don&#8217;t know how important it is to abide by the JPA spec here. It doesn&#8217;t seem to be specified anywhere obvious that @Lob should obey @Column&#8217;s length, but Hibernate does that and it&#8217;s kind of useless on MySQL without it. Being that MySQL is basically a de facto standard in the OSS world, you would expect it to be usable on MySQL. (Yeah, I know that there are others. Big deal. I have never felt the need to reach for an alternative RDBMS, more often opting for distributed object stores or whatever.) Regardless, the JPA spec seems optional for EL, since it <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=243301">doesn&#8217;t really</a> <a href="http://www.eclipse.org/forums/index.php?t=msg&#038;goto=499756&#038;S=3bcc64b0e0822e7707f2ce0b616d92df">seem to</a> <a href="http://stackoverflow.com/questions/1877499/eclipselink-jpa-preupdate-call-not-persisting">follow it</a>. (Hey, why should it work as expected when it can be <em>faster</em>!) Anyway, 64000&#8230;</p>
<p>The first suspect that&#8217;s broken in EclipseLink is o.e.p.platform.database.MySQLPlatform, which essentially blows at describing the underlying database&#8217;s capabilities and SQL quirks. It basically locks the column types for CLOB and BLOB to TEXT and BLOB, all with a fixed 64000 length. MySQL basically ignores that length and turns them into plain BLOB and TEXT columns. This doesn&#8217;t do us any good if we need MEDIUMBLOB, LONGTEXT, etc. This enables setting of the size on these field definitions so @Column&#8217;s length actually ends up somewhere.</p>
<pre class="brush: diff; wrap-lines: false;">
diff -ur f/org/eclipse/persistence/platform/database/MySQLPlatform.java src/org/eclipse/persistence/platform/database/MySQLPlatform.java
--- f/org/eclipse/persistence/platform/database/MySQLPlatform.java	2009-11-04 16:00:56.000000000 -0600
+++ src/org/eclipse/persistence/platform/database/MySQLPlatform.java	2010-01-22 03:19:41.000000000 -0600
@@ -129,12 +129,18 @@
         fieldTypeMapping.put(String.class, new FieldTypeDefinition(&quot;VARCHAR&quot;, 255));
         fieldTypeMapping.put(Character.class, new FieldTypeDefinition(&quot;CHAR&quot;, 1));

-        fieldTypeMapping.put(Byte[].class, new FieldTypeDefinition(&quot;BLOB&quot;, 64000));
-        fieldTypeMapping.put(Character[].class, new FieldTypeDefinition(&quot;TEXT&quot;, 64000));
-        fieldTypeMapping.put(byte[].class, new FieldTypeDefinition(&quot;BLOB&quot;, 64000));
-        fieldTypeMapping.put(char[].class, new FieldTypeDefinition(&quot;TEXT&quot;, 64000));
-        fieldTypeMapping.put(java.sql.Blob.class, new FieldTypeDefinition(&quot;BLOB&quot;, 64000));
-        fieldTypeMapping.put(java.sql.Clob.class, new FieldTypeDefinition(&quot;TEXT&quot;, 64000));
+        final FieldTypeDefinition blobFieldTypeDefinition = new FieldTypeDefinition(&quot;BLOB&quot;, 64000);
+        blobFieldTypeDefinition.setIsSizeAllowed(true);
+
+        final FieldTypeDefinition clobFieldTypeDefinition = new FieldTypeDefinition(&quot;TEXT&quot;, 64000);
+        clobFieldTypeDefinition.setIsSizeAllowed(true);
+
+        fieldTypeMapping.put(Byte[].class, blobFieldTypeDefinition);
+        fieldTypeMapping.put(Character[].class, clobFieldTypeDefinition);
+        fieldTypeMapping.put(byte[].class, blobFieldTypeDefinition);
+        fieldTypeMapping.put(char[].class, clobFieldTypeDefinition);
+        fieldTypeMapping.put(java.sql.Blob.class, blobFieldTypeDefinition);
+        fieldTypeMapping.put(java.sql.Clob.class, clobFieldTypeDefinition);

         fieldTypeMapping.put(java.sql.Date.class, new FieldTypeDefinition(&quot;DATE&quot;, false));
         fieldTypeMapping.put(java.sql.Time.class, new FieldTypeDefinition(&quot;TIME&quot;, false));
</pre>
<div class="boxnote">
EclipseLink defines two types for MySQL: TargetDatabase.MySQL and TargetDatabase.MySQL4. Spring 3.0.0 actually only ever uses MySQL4. It doesn&#8217;t matter, because EL uses the same MySQLPlatform for both. One day it may matter, though&#8230;
</div>
<p>The second is the pukerrific(!) o.e.p.tools.schemaframework.DefaultTableGenerator, which generates the DDL. Originally, it only obeyed the @Column length for, essentially, basic String values. Even if you set a length, it would silently ignore it. You would never know without running into it after deployment or verifying the schema by hand. If you&#8217;re going to have to do that, you may as well throw out your computers and use pencil and paper. Someone must not know what fail-fast means.</p>
<pre class="brush: diff; wrap-lines: false;">
diff -ur f/org/eclipse/persistence/tools/schemaframework/DefaultTableGenerator.java src/org/eclipse/persistence/tools/schemaframework/DefaultTableGenerator.java
--- f/org/eclipse/persistence/tools/schemaframework/DefaultTableGenerator.java	2009-11-24 18:02:34.000000000 -0600
+++ src/org/eclipse/persistence/tools/schemaframework/DefaultTableGenerator.java	2010-01-22 03:48:10.000000000 -0600
@@ -683,7 +683,9 @@
                 if ((fieldType != null)) {
                     if (fieldType.equals(ClassConstants.STRING) ||
                        fieldType.equals(ClassConstants.APCHAR)  ||
-                       fieldType.equals(ClassConstants.ACHAR)) {
+                       fieldType.equals(ClassConstants.ACHAR) ||
+                       fieldType.equals(ClassConstants.BLOB) ||
+                       fieldType.equals(ClassConstants.CLOB)) {
                         // The field size is defaulted to &quot;255&quot; or use the user supplied length
                         fieldDef.setSize(dbField.getLength());
                     } else {
</pre>
<p>After these minor changes, maybe everything explodes for other database systems. I don&#8217;t really care. It works for me. Countdown to infinity, as we wait for EclipseLink developers to find this sitting here and then include it in EclipseLink, starts now!</p>
]]></content:encoded>
			<wfw:commentRss>http://datenschwanz.net/2010/01/22/eclipselink-hates-mysql-probably/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-nd/3.0/us/</creativeCommons:license>
	</item>
		<item>
		<title>They Should Have Called Java &#8220;Molasses&#8221;</title>
		<link>http://datenschwanz.net/2010/01/15/they-should-have-called-java-molasses/</link>
		<comments>http://datenschwanz.net/2010/01/15/they-should-have-called-java-molasses/#comments</comments>
		<pubDate>Sat, 16 Jan 2010 01:57:34 +0000</pubDate>
		<dc:creator>studmuffin</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[AOP]]></category>
		<category><![CDATA[AspectJ]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[JSF]]></category>

		<guid isPermaLink="false">http://datenschwanz.net/?p=376</guid>
		<description><![CDATA[Possibly a testament to why people hate the JCP, that style of bureaucracy, and why almost everything that isn&#8217;t touched by it actually gets things done, I ran into what I would consider a blocker when it was requested that I have the currency symbol and percent signs optional for form inputs using f:convertNumber and [...]]]></description>
			<content:encoded><![CDATA[<p>Possibly a testament to why people hate the JCP, that style of bureaucracy, and why almost everything that isn&#8217;t touched by it actually gets things done, I ran into what I would consider a blocker when it was requested that I have the currency symbol and percent signs optional for form inputs using f:convertNumber and found that it was impossible with Mojarra. I can&#8217;t see any reason why they would be absolutely required. There isn&#8217;t even an option to make them optional with some listed caveats or &#8220;we don&#8217;t think you should do this, but here&#8217;s the gun.&#8221;</p>
<p>After about ten seconds of research, I found this enhancement request:</p>
<p><a href="https://javaserverfaces.dev.java.net/issues/show_bug.cgi?id=811">Have f:convertNumber add currency symbol if not present for type=currency</a></p>
<p>This issue has been rotting there <strong><em>since 2008</em></strong>? It was marked for <em>consideration</em>, its priority reduced, and then rescheduled four times, not even for JSF 1.2? Who puts these retards at the helm?</p>
<p>So, in typical fashion, we have to shoehorn business processes into the framework. Well, not this time. I have decided to abuse AOP <em>once again</em> and patch around it.</p>
<p><span id="more-376"></span><br />
I initially considered writing a simple converter that subclassed the broken one. I actually did it. Here, you can use it if you want to go down that route or you can&#8217;t/don&#8217;t use AspectJ.</p>
<p><em>Note: There is a tiny hack in there that will format a string with the same formatter to extract a missing currency symbol. If you don&#8217;t like it that much, just set currencySymbol on the convert tag.</em></p>
<pre class="brush: java; wrap-lines: false;">
/**
 * LDSYS Java Library
 *
 * Copyright (C) 1997-2010 Christopher G. Stach II
 *
 * This file is part of LDSYS Java Library.
 *
 * LDSYS Java Library is free software: you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * LDSYS Java Library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with LDSYS Java Library.  If not, see
 * &lt;http://www.gnu.org/licenses/&gt;.
 *
 **/

package net.ldsys.view.jsf.converter;

import java.math.BigDecimal;

import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;

/**
 * Description: Description goes here.
 *
 * @author cgs
 */
public class NumberConverter
	extends javax.faces.convert.NumberConverter
{

	private static final char PERCENT_SYMBOL = '%';

	/**
	 *
	 */
	public NumberConverter() {
		super();
	}

	/**
	 * @see javax.faces.convert.NumberConverter#getAsObject(javax.faces.context.FacesContext,
	 *      javax.faces.component.UIComponent, java.lang.String)
	 */
	@Override
	public Object getAsObject(FacesContext facesContext, UIComponent component, String str) {
		final String trimmed = str == null ? &quot;&quot; : str.trim();

		final String maybeModifiedStr;

		if (&quot;currency&quot;.equals(getType()) &amp;&amp; !trimmed.isEmpty() &amp;&amp; !hasCurrencySymbol(trimmed, getCurrencySymbol(facesContext, component))) {
			maybeModifiedStr = getCurrencySymbol(facesContext, component) + trimmed;
		} else if (&quot;percent&quot;.equals(getType()) &amp;&amp; !trimmed.isEmpty() &amp;&amp; !hasPercentSymbol(trimmed)) {
			maybeModifiedStr = trimmed + PERCENT_SYMBOL;
		} else {
			maybeModifiedStr = str;
		}

		return super.getAsObject(facesContext, component, maybeModifiedStr);
	}

	private String getCurrencySymbol(FacesContext facesContext, UIComponent component) {
		String currencySymbol = getCurrencySymbol();

		if (currencySymbol == null) {
			currencySymbol = getAsString(facesContext, component, BigDecimal.ZERO).substring(0, 1);
		}

		return currencySymbol;
	}

	private boolean hasCurrencySymbol(String str, String currencySymbol) {
		return str.substring(0, 1).equals(currencySymbol);
	}

	private boolean hasPercentSymbol(String str) {
		return str.charAt(str.length() - 1) == PERCENT_SYMBOL;
	}

}
</pre>
<p>Then realized I would probably need to go and change all of the tags in a plethora of files. It&#8217;s basically the same thing, but an aspect.</p>
<pre class="brush: java; wrap-lines: false;">
/**
 * LDSYS Java Library
 *
 * Copyright (C) 1997-2010 Christopher G. Stach II
 *
 * This file is part of LDSYS Java Library.
 *
 * LDSYS Java Library is free software: you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * LDSYS Java Library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with LDSYS Java Library.  If not, see
 * &lt;http://www.gnu.org/licenses/&gt;.
 *
 **/

package net.ldsys.view.jsf.converter;

import java.math.BigDecimal;

import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;

/**
 * Description: Description goes here.
 *
 * @author cgs
 */
@Aspect
public class NumberConverterAspect {

	private static final char PERCENT_SYMBOL = '%';

	/**
	 *
	 */
	public NumberConverterAspect() {
		super();
	}

	/**
	 * @param proceedingJoinPoint
	 * @param facesContext
	 * @param component
	 * @param str
	 * @return Object version of &lt;code&gt;str&lt;/code&gt;
	 * @throws Throwable
	 * @see javax.faces.convert.NumberConverter#getAsObject(javax.faces.context.FacesContext,
	 *      javax.faces.component.UIComponent, java.lang.String)
	 */
	@Around(argNames = &quot;facesContext, component, str&quot;, value = &quot;execution(public Object javax.faces.convert.NumberConverter.getAsObject(..)) &amp;&amp; args(facesContext, component, str)&quot;)
	public Object addMissingCurrencyPercentSymbols(ProceedingJoinPoint proceedingJoinPoint, FacesContext facesContext, UIComponent component, String str)
		throws Throwable
	{
		final javax.faces.convert.NumberConverter numberConverter = (javax.faces.convert.NumberConverter) proceedingJoinPoint.getThis();

		final String trimmed = str == null ? &quot;&quot; : str.trim();

		final String maybeModifiedStr;

		if (&quot;currency&quot;.equals(numberConverter.getType()) &amp;&amp; !trimmed.isEmpty() &amp;&amp; !hasCurrencySymbol(trimmed, getCurrencySymbol(numberConverter, facesContext, component))) {
			maybeModifiedStr = getCurrencySymbol(numberConverter, facesContext, component) + trimmed;
		} else if (&quot;percent&quot;.equals(numberConverter.getType()) &amp;&amp; !trimmed.isEmpty() &amp;&amp; !hasPercentSymbol(trimmed)) {
			maybeModifiedStr = trimmed + PERCENT_SYMBOL;
		} else {
			maybeModifiedStr = str;
		}

		return proceedingJoinPoint.proceed(new Object[] {
			facesContext,
			component,
			maybeModifiedStr
		});
	}

	private String getCurrencySymbol(javax.faces.convert.NumberConverter numberConverter, FacesContext facesContext, UIComponent component) {
		String currencySymbol = numberConverter.getCurrencySymbol();

		if (currencySymbol == null) {
			currencySymbol = numberConverter.getAsString(facesContext, component, BigDecimal.ZERO).substring(0, 1);
		}

		return currencySymbol;
	}

	private boolean hasCurrencySymbol(String str, String currencySymbol) {
		return str.substring(0, 1).equals(currencySymbol);
	}

	private boolean hasPercentSymbol(String str) {
		return str.charAt(str.length() - 1) == PERCENT_SYMBOL;
	}

}
</pre>
<p>Just add -Xset:weaveJavaxPackages=true to your weaver options and the net.ldsys.view.jsf.converter.NumberConverterAspect aspect to your aspects in aop.xml and you&#8217;re done. All of the tags will work as you probably always expected. The damn thing adds commas, but not dollar signs?</p>
]]></content:encoded>
			<wfw:commentRss>http://datenschwanz.net/2010/01/15/they-should-have-called-java-molasses/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-nd/3.0/us/</creativeCommons:license>
	</item>
		<item>
		<title>How To Easily Get Row Selection Working With ICEfaces and AspectJ</title>
		<link>http://datenschwanz.net/2010/01/05/how-to-easily-get-row-selection-working-with-icefaces-and-aspectj/</link>
		<comments>http://datenschwanz.net/2010/01/05/how-to-easily-get-row-selection-working-with-icefaces-and-aspectj/#comments</comments>
		<pubDate>Tue, 05 Jan 2010 21:32:27 +0000</pubDate>
		<dc:creator>studmuffin</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[AOP]]></category>
		<category><![CDATA[AspectJ]]></category>
		<category><![CDATA[ICEfaces]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://datenschwanz.net/?p=354</guid>
		<description><![CDATA[If you&#8217;ve succumbed to not being able to get Spring Web Flow to work with your other framework of choice (I am only using ICEfaces as an example because its fresh in my head) and have to figure out how to reimplement row selection for tables and such, since you can&#8217;t readily use SWF&#8217;s OneSelectionTrackingListDataModel [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;ve succumbed to not being able to get Spring Web Flow to work with your other framework of choice (I am only using ICEfaces as an example because its fresh in my head) and have to figure out how to reimplement row selection for tables and such, since you can&#8217;t readily use SWF&#8217;s OneSelectionTrackingListDataModel et al (i.e. result-type=&#8221;dataModel&#8221; in a flow configuration), there is of course an AOP solution. <em>What can&#8217;t it do?!</em></p>
<p>I have an aspect skeleton sitting around for this, and of course you can use it if you want. (Fuck, you can use the whole library. I just have to get my SCM back online.) You just have to have everything else in place to make it go, like load-time weaving or whatever. Anyway, it&#8217;s basically the <a href="http://en.wikipedia.org/wiki/Decorator_pattern">Decorator pattern</a>, something AOP introductions&#8230; <em>are</em>. Here it is&#8230;</p>
<p><span id="more-354"></span></p>
<pre class="brush: java; wrap-lines: false;">
/**
 * LDSYS Java Library
 *
 * Copyright (C) 1997-2010 Christopher G. Stach II
 *
 * This file is part of LDSYS Java Library.
 *
 * LDSYS Java Library is free software: you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * LDSYS Java Library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with LDSYS Java Library.  If not, see
 * &lt;http://www.gnu.org/licenses/&gt;.
 *
 **/

package net.ldsys.view.jsf;

import java.io.Serializable;

import javax.faces.event.ActionEvent;

/**
 * Description: This should be subclassed and used like this: &lt;code&gt;
 * &amp;#064;Aspect
 * public class SelectableRowAspect {
 *     &amp;#064;DeclareMixin(&amp;quot;@javax.persistence.Entity your.package.model..*&amp;quot;)
 *     public static SelectableRow createDelegate(Object row) {
 *         return net.ldsys.view.jsf.SelectableRowAspect.createDelegate(row);
 *     }
 * }
 * &lt;/code&gt;
 *
 * @author cgs
 */
// @Aspect
public class SelectableRowAspect {

	/**
	 * Description: What do you think it is?
	 *
	 * @author cgs
	 */
	public interface SelectableRow
		extends Serializable
	{

		/**
		 * @return the selected
		 */
		boolean isSelected();

		/**
		 * @param selected
		 */
		void setSelected(boolean selected);

		/**
		 * @param actionEvent
		 */
		void toggleSelected(ActionEvent actionEvent);

	}

	/**
	 * Description: What do you think it is?
	 *
	 * @author cgs
	 */
	public static class SelectableRowImpl
		implements SelectableRow
	{

		private static final long serialVersionUID = 1L;

		private boolean _selected;

		/**
		 *
		 */
		public SelectableRowImpl() {
			super();
		}

		/**
		 * @see net.ldsys.view.jsf.SelectableRowAspect.SelectableRow#isSelected()
		 */
		public boolean isSelected() {
			return _selected;
		}

		/**
		 * @see net.ldsys.view.jsf.SelectableRowAspect.SelectableRow#setSelected(boolean)
		 */
		public void setSelected(boolean selected) {
			_selected = selected;
		}

		/**
		 * @see net.ldsys.view.jsf.SelectableRowAspect.SelectableRow#toggleSelected(javax.faces.event.ActionEvent)
		 */
		public void toggleSelected(ActionEvent actionEvent) {
			_selected = !_selected;
		}

	}

	/**
	 * @param row
	 * @return the SelectableRow implementation
	 */
	// @DeclareMixin(&amp;quot;@javax.persistence.Entity
	// your.package.model..*&amp;quot;)
	public static SelectableRow createDelegate(Object row) {
		return new SelectableRowImpl();
	}

}
</pre>
<p>Using it is basically what the Javadoc says. One would look like this:</p>
<pre class="brush: java; wrap-lines: false;">
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.DeclareMixin;

@Aspect
public class SelectableRowAspect
	extends net.ldsys.view.jsf.SelectableRowAspect
{

	@DeclareMixin(&quot;@javax.persistence.Entity tld.domain.some.package.model..*&quot;)
	public static SelectableRow createDelegate(Object row) {
		return net.ldsys.view.jsf.SelectableRowAspect.createDelegate(row);
	}

	/**
	 *
	 */
	public SelectableRowAspect() {
		super();
	}

}
</pre>
<p>That applies your row selection aspect on all of your entities. You just stuff them into a list and you can use the selection mechanism in things, kind of like this (this is a fucked up example, so don&#8217;t copy and paste thinking that it will work):</p>
<pre class="brush: xml; wrap-lines: false;">
&lt;ice:dataTable id=&quot;someTableData&quot;
    value=&quot;#{someTableModel.rows}&quot;
    var=&quot;user&quot;
    varStatus=&quot;status&quot;&gt;

    &lt;ice:rowSelector id=&quot;someTableRowSelector&quot;
        immediate=&quot;true&quot;
        toggleOnClick=&quot;false&quot;
        toggleOnInput=&quot;false&quot;
        value=&quot;#{something.selected}&quot; /&gt;

    &lt;columnblahblah&gt;

        &lt;ice:commandLink action=&quot;#{somePopup.open}&quot;
            actionListener=&quot;#{something.toggleSelected}&quot;&gt;

            &lt;ice:outputText value=&quot;#{status.index + 1}&quot; /&gt;

        &lt;/ice:commandLink&gt;

    &lt;/columnblahblah&gt;

    [...]

&lt;/ice:dataTable&gt;
</pre>
<p>There. Now you can click on a row and it will be selected for your popup.</p>
]]></content:encoded>
			<wfw:commentRss>http://datenschwanz.net/2010/01/05/how-to-easily-get-row-selection-working-with-icefaces-and-aspectj/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-nd/3.0/us/</creativeCommons:license>
	</item>
		<item>
		<title>RichFaces AJAX Doesn&#8217;t Even Work</title>
		<link>http://datenschwanz.net/2010/01/01/richfaces-ajax-doesnt-even-work/</link>
		<comments>http://datenschwanz.net/2010/01/01/richfaces-ajax-doesnt-even-work/#comments</comments>
		<pubDate>Fri, 01 Jan 2010 16:37:14 +0000</pubDate>
		<dc:creator>studmuffin</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[RichFaces]]></category>
		<category><![CDATA[Spring]]></category>

		<guid isPermaLink="false">http://datenschwanz.net/?p=346</guid>
		<description><![CDATA[After a few days of wasting my time with ICEfaces, I switched to RichFaces because at least it tries to integrate with other frameworks without having complete diarrhea for a code base. Seriously, it looks like ICEfaces was written by a bunch of fucking monkeys drunk on gin. Have some pride in your work, assholes. [...]]]></description>
			<content:encoded><![CDATA[<p>After a few days of wasting my time with ICEfaces, I switched to RichFaces because at least it tries to integrate with other frameworks without having complete diarrhea for a code base. Seriously, it looks like ICEfaces was written by a bunch of fucking monkeys drunk on gin. Have some pride in your work, assholes. Try formatting your code and not using copy and paste from Spring to make things kind of work&#8230; I mean not work at all you fucks. Great look and feel, but total shit on the inside, like an American girl. Nice components, but unusable. You suck. Sun/Oracle is going to have a great time gutting you. Sorry, Ted.</p>
<p>Anyway, RichFaces doesn&#8217;t even fucking work, either. They do, however, have a great debugging component called a4j:log, which is really nothing to do with the JBoss infection, or the Exadel infection, but probably someone else in the real world. I don&#8217;t know for sure, but it&#8217;s probably from a good source. Anyway, this component will spit out your AJAX transaction and save the day. In particular, it will help to solve issues like RICHFACES DOESN&#8217;T FUCKING WORK. I don&#8217;t give a shit what a certified asshole with the most annoying British stick-up-the-ass name like Gavin says. &#8220;Oy, it works with Seam. Guffaw, ol&#8217; chap!&#8221; Celebrity developers can suck it. The feel that they generate among other developers is sick. &#8220;Oh, so-and-so uses it, so I must waste my time using it in a different, unproven, way that is outside of the Hibernate recipe, ultimately fail, and feel bad about myself.&#8221; Not everyone on every project wants to fuck around with these broken frameworks with retarded paradigms and disgusting code that is nearly impossible to debug, unless they <em>really</em> know how to debug and have the time and inclination to do so. I do, so I end up patching a lot of fucked up shit that I shouldn&#8217;t have to.</p>
<p>Anyway, the excitement can be found in many places, including <a href="http://forum.springsource.org/showthread.php?t=51127">here</a>, where Spring announces a brokeass doesn&#8217;t fucking work integration with RichFaces. But, I at least found a way to work around it&#8230;</p>
<p><span id="more-346"></span><br />
So, the a4j:log output, it looks something like this:</p>
<pre class="brush: plain; wrap-lines: false;">
debug[18:46:02,025]: Have Event [object Object] with properties: target: http://localhost:8080/xxx/app/admin/sales?execution=e1s1#, srcElement: undefined, type: click
debug[18:46:02,026]: Query preparation for form 'dataTableForm' requested
debug[18:46:02,027]: Append hidden control dataTableForm with value [dataTableForm] and value attribute [dataTableForm]
debug[18:46:02,028]: Append text control dataTableForm:displayRows with value [2] and value attribute [2]
debug[18:46:02,029]: Append hidden control javax.faces.ViewState with value [e1s1] and value attribute [e1s1]
debug[18:46:02,029]: parameter dataTableForm:previousPageLink with value dataTableForm:previousPageLink
debug[18:46:02,029]: Look up queue with default name
debug[18:46:02,030]: NEW AJAX REQUEST !!! with form: dataTableForm
debug[18:46:02,030]: Start XmlHttpRequest
debug[18:46:02,034]: Request state : 1
debug[18:46:02,034]: QueryString: AJAXREQUEST=_viewRoot&amp;dataTableForm=dataTableForm&amp;dataTableForm%3AdisplayRows=2&amp;javax.faces.ViewState=e1s1&amp;dataTableForm%3ApreviousPageLink=dataTableForm%3ApreviousPageLink&amp;
debug[18:46:02,052]: Request state : 1
debug[18:46:03,951]: Request state : 2
debug[18:46:03,954]: Request state : 3
debug[18:46:03,955]: Request state : 3
debug[18:46:03,956]: Request state : 4
debug[18:46:03,957]: Request end with state 4
debug[18:46:03,957]: Response with content-type: text/xml;charset=UTF-8
debug[18:46:03,958]: Full response content: &lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot;&gt;&lt;head&gt;&lt;/head&gt;&lt;body xmlns=&quot;http://www.w3.org/1999/xhtml&quot;&gt;&lt;dl id=&quot;dataTableForm:j_id23&quot; class=&quot;rich-messages&quot; style=&quot;display: none; &quot;&gt;&lt;dt&gt;&lt;/dt&gt;&lt;/dl&gt; &lt;center&gt;&lt;div class=&quot;tableControlPanel&quot;&gt;&lt;div class=&quot;fLeft&quot;&gt;&lt;input id=&quot;dataTableForm:displayRows&quot; type=&quot;text&quot; name=&quot;dataTableForm:displayRows&quot; value=&quot;2&quot; maxlength=&quot;2&quot; onchange=&quot;changeDisplayRows&quot; size=&quot;1&quot; /&gt; items per page. 12 found. Showing 2, from 3 to 4. Page 2 / 6.&lt;/div&gt;&lt;div class=&quot;fRight&quot;&gt; &lt;span class=&quot;fLeft&quot;&gt;&lt;a href=&quot;#&quot; id=&quot;dataTableForm:previousPageLink&quot; name=&quot;dataTableForm:previousPageLink&quot; onclick=&quot;A4J.AJAX.Submit('dataTableForm',event,{'similarityGroupingId':'dataTableForm:previousPageLink','parameters':{'dataTableForm:previousPageLink':'dataTableForm:previousPageLink'} } );return false;&quot;&gt;« Previous page&lt;/a&gt;&lt;/span&gt;&lt;span class=&quot;fLeft&quot; style=&quot;margin: 0px 5px&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;fRight&quot;&gt;&lt;a href=&quot;#&quot; id=&quot;dataTableForm:nextPageLink&quot; name=&quot;dataTableForm:nextPageLink&quot; onclick=&quot;A4J.AJAX.Submit('dataTableForm',event,{'similarityGroupingId':'dataTableForm:nextPageLink','parameters':{'dataTableForm:nextPageLink':'dataTableForm:nextPageLink'} } );return false;&quot;&gt;Next page »&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;clearer&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/center&gt; &lt;center&gt;&lt;table class=&quot;rich-table dataTable&quot; id=&quot;dataTableForm:dataTable&quot; border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot;&gt;&lt;colgroup span=&quot;5&quot;&gt;&lt;/colgroup&gt;&lt;thead class=&quot;rich-table-thead&quot;&gt;&lt;tr class=&quot;rich-table-subheader &quot;&gt;&lt;th class=&quot;rich-table-subheadercell &quot; scope=&quot;col&quot; id=&quot;dataTableForm:dataTable:j_id46header&quot;&gt;&lt;div id=&quot;dataTableForm:dataTable:j_id46header:sortDiv&quot;&gt;#&lt;/div&gt;&lt;/th&gt;&lt;th class=&quot;rich-table-subheadercell &quot; scope=&quot;col&quot; id=&quot;dataTableForm:dataTable:j_id49header&quot;&gt;&lt;div id=&quot;dataTableForm:dataTable:j_id49header:sortDiv&quot;&gt;&lt;a href=&quot;#&quot; id=&quot;dataTableForm:dataTable:sortByNameLink&quot; name=&quot;dataTableForm:dataTable:sortByNameLink&quot; onclick=&quot;A4J.AJAX.Submit('dataTableForm',event,{'similarityGroupingId':'dataTableForm:dataTable:sortByNameLink','parameters':{'sortColumn':'firstName','dataTableForm:dataTable:sortByNameLink':'dataTableForm:dataTable:sortByNameLink'} } );return false;&quot;&gt;First Name&lt;/a&gt;&lt;/div&gt;&lt;/th&gt;&lt;th class=&quot;rich-table-subheadercell &quot; scope=&quot;col&quot; id=&quot;dataTableForm:dataTable:j_id52header&quot;&gt;&lt;div id=&quot;dataTableForm:dataTable:j_id52header:sortDiv&quot;&gt;&lt;a href=&quot;#&quot; id=&quot;dataTableForm:dataTable:sortByNameLink&quot; name=&quot;dataTableForm:dataTable:sortByNameLink&quot; onclick=&quot;A4J.AJAX.Submit('dataTableForm',event,{'similarityGroupingId':'dataTableForm:dataTable:sortByNameLink','parameters':{'sortColumn':'lastName','dataTableForm:dataTable:sortByNameLink':'dataTableForm:dataTable:sortByNameLink'} } );return false;&quot;&gt;Last Name&lt;/a&gt;&lt;/div&gt;&lt;/th&gt;&lt;th class=&quot;rich-table-subheadercell &quot; scope=&quot;col&quot; id=&quot;dataTableForm:dataTable:j_id55header&quot;&gt;&lt;div id=&quot;dataTableForm:dataTable:j_id55header:sortDiv&quot;&gt;&lt;a href=&quot;#&quot; id=&quot;dataTableForm:dataTable:sortByNameLink&quot; name=&quot;dataTableForm:dataTable:sortByNameLink&quot; onclick=&quot;A4J.AJAX.Submit('dataTableForm',event,{'similarityGroupingId':'dataTableForm:dataTable:sortByNameLink','parameters':{'sortColumn':'totalSales','dataTableForm:dataTable:sortByNameLink':'dataTableForm:dataTable:sortByNameLink'} } );return false;&quot;&gt;# Sales&lt;/a&gt;&lt;/div&gt;&lt;/th&gt;&lt;th class=&quot;rich-table-subheadercell &quot; scope=&quot;col&quot; id=&quot;dataTableForm:dataTable:j_id58header&quot;&gt;&lt;div id=&quot;dataTableForm:dataTable:j_id58header:sortDiv&quot;&gt;&lt;a href=&quot;#&quot; id=&quot;dataTableForm:dataTable:sortByNameLink&quot; name=&quot;dataTableForm:dataTable:sortByNameLink&quot; onclick=&quot;A4J.AJAX.Submit('dataTableForm',event,{'similarityGroupingId':'dataTableForm:dataTable:sortByNameLink','parameters':{'sortColumn':'totalCommissions','dataTableForm:dataTable:sortByNameLink':'dataTableForm:dataTable:sortByNameLink'} } );return false;&quot;&gt;Total Commissions&lt;/a&gt;&lt;/div&gt;&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody id=&quot;dataTableForm:dataTable:tb&quot;&gt;&lt;tr class=&quot;rich-table-row rich-table-firstrow oddRow&quot;&gt;&lt;td class=&quot;rich-table-cell listNumberColumn&quot; id=&quot;dataTableForm:dataTable:0:j_id46&quot;&gt;3&lt;/td&gt;&lt;td class=&quot;rich-table-cell listFirstNameColumn&quot; id=&quot;dataTableForm:dataTable:0:j_id49&quot;&gt;Knwpwibvgiatv&lt;/td&gt;&lt;td class=&quot;rich-table-cell listLastNameColumn&quot; id=&quot;dataTableForm:dataTable:0:j_id52&quot;&gt;Hplzjtgko&lt;/td&gt;&lt;td class=&quot;rich-table-cell &quot; id=&quot;dataTableForm:dataTable:0:j_id55&quot;&gt;0&lt;/td&gt;&lt;td class=&quot;rich-table-cell &quot; id=&quot;dataTableForm:dataTable:0:j_id58&quot;&gt;$0.00&lt;/td&gt;&lt;/tr&gt;&lt;tr class=&quot;rich-table-row evenRow&quot;&gt;&lt;td class=&quot;rich-table-cell listNumberColumn&quot; id=&quot;dataTableForm:dataTable:1:j_id46&quot;&gt;4&lt;/td&gt;&lt;td class=&quot;rich-table-cell listFirstNameColumn&quot; id=&quot;dataTableForm:dataTable:1:j_id49&quot;&gt;Wttvqqrwsin&lt;/td&gt;&lt;td class=&quot;rich-table-cell listLastNameColumn&quot; id=&quot;dataTableForm:dataTable:1:j_id52&quot;&gt;Hzyiboe&lt;/td&gt;&lt;td class=&quot;rich-table-cell &quot; id=&quot;dataTableForm:dataTable:1:j_id55&quot;&gt;0&lt;/td&gt;&lt;td class=&quot;rich-table-cell &quot; id=&quot;dataTableForm:dataTable:1:j_id58&quot;&gt;$0.00&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/center&gt;&lt;meta name=&quot;Ajax-Update-Ids&quot; content=&quot;dataTableForm:dataTableFragment&quot; xmlns=&quot;http://www.w3.org/1999/xhtml&quot; /&gt;&lt;span xmlns=&quot;http://www.w3.org/1999/xhtml&quot; id=&quot;ajax-view-state&quot;&gt;&lt;input type=&quot;hidden&quot; name=&quot;javax.faces.ViewState&quot; id=&quot;javax.faces.ViewState&quot; value=&quot;e1s1&quot; autocomplete=&quot;off&quot; /&gt;&lt;/span&gt;&lt;meta xmlns=&quot;http://www.w3.org/1999/xhtml&quot; id=&quot;Ajax-Response&quot; name=&quot;Ajax-Response&quot; content=&quot;true&quot; /&gt;&lt;/body&gt;&lt;/html&gt;
debug[18:46:03,958]: Header Ajax-Expired not found, search in &lt;meta&gt;
debug[18:46:03,959]: search for elements by name 'meta' in element #document
debug[18:46:03,961]: Find &lt;meta name='Ajax-Update-Ids' content='dataTableForm:dataTableFragment'&gt;
debug[18:46:03,962]: Find &lt;meta name='Ajax-Response' content='true'&gt;
debug[18:46:03,962]: Header Ajax-Update-Ids not found, search in &lt;meta&gt;
debug[18:46:03,963]: search for elements by name 'meta' in element #document
debug[18:46:03,965]: Find &lt;meta name='Ajax-Update-Ids' content='dataTableForm:dataTableFragment'&gt;
debug[18:46:03,965]: Update page by list of rendered areas from response dataTableForm:dataTableFragment
debug[18:46:03,966]: search for elements by name 'script' in element #document
debug[18:46:03,968]: search for elements by name 'link' in element #document
debug[18:46:03,971]: call getElementById for id= org.ajax4jsf.queue_script
debug[18:46:03,971]: Update page part from call parameter for ID dataTableForm:dataTableFragment
debug[18:46:03,972]: call getElementById for id= dataTableForm:dataTableFragment
error[18:46:03,972]: New node for ID dataTableForm:dataTableFragment is not present in response
debug[18:46:03,972]: call getElementById for id= org.ajax4jsf.oncomplete
debug[18:46:03,973]: Processing updates finished, no oncomplete function to call
debug[18:46:03,973]: call getElementById for id= ajax-view-state
debug[18:46:03,974]: Hidden JSF state fields: [object HTMLSpanElement]
debug[18:46:03,974]: Namespace for hidden view-state input fields is undefined
debug[18:46:03,975]: search for elements by name 'input' in element span
debug[18:46:03,978]: Replace value for inputs: 3 by new values: 1
debug[18:46:03,978]: Input in response: javax.faces.ViewState
debug[18:46:03,979]: Found same input on page with type: hidden
debug[18:46:03,980]: search for elements by name 'INPUT' in element span
debug[18:46:03,982]: Replace value for inputs: 3 by new values: 0
debug[18:46:03,983]: call getElementById for id= _A4J.AJAX.focus
debug[18:46:03,984]: No focus information in response
</pre>
<p>The key line here is this:</p>
<pre class="brush: plain; light: true;">
error[18:46:03,972]: New node for ID dataTableForm:dataTableFragment is not present in response
</pre>
<p>That basically means that the client side can&#8217;t find an id attribute on the body of the response generated by the server side. It doesn&#8217;t know what part of the response it&#8217;s supposed to use to replace the renderable section on the client side. After multiple concoctions of ui:fragment and a4j:outputPanel, I just stuck a div tag with this id (dataTableForm:dataTableFragment) inside of the a4j:outputPanel. The server won&#8217;t touch it and it will always be there.</p>
<p>After a little mucking around, I found that some things were not submitted correctly in AJAX requests, but using h:panelGroup with the same id as the outputPanel worked. So, my file looks like this:</p>
<pre class="brush: xml;">
...
&lt;h:form id=&quot;dataTableForm&quot;&gt;
&lt;h:panelGroup layout=&quot;block&quot; styleClass=&quot;section&quot;&gt;
&lt;a4j:outputPanel id=&quot;dataTableFragment&quot; ajaxRendered=&quot;true&quot;&gt;
&lt;h:panelGroup id=&quot;dataTableFragment&quot; layout=&quot;block&quot;&gt;
...
</pre>
<p>Well, now it works. I don&#8217;t know who is to blame for this fuckup, but get your act together. At least document it. It&#8217;s probably something stupid like the turf battle between Spring and JBoss, but if they don&#8217;t integrate flawlessly, they are going down the same nightmare fudge tunnel that software was before open source development took hold. I&#8217;m sure all of the usability and workarounds are covered in the documentation and consulting for sale.</p>
]]></content:encoded>
			<wfw:commentRss>http://datenschwanz.net/2010/01/01/richfaces-ajax-doesnt-even-work/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-nd/3.0/us/</creativeCommons:license>
	</item>
		<item>
		<title>Facelets ui:debug and Spring Web Flow</title>
		<link>http://datenschwanz.net/2009/12/31/facelets-uidebug-and-spring-web-flow/</link>
		<comments>http://datenschwanz.net/2009/12/31/facelets-uidebug-and-spring-web-flow/#comments</comments>
		<pubDate>Thu, 31 Dec 2009 18:57:01 +0000</pubDate>
		<dc:creator>studmuffin</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Facelets]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Spring Web Flow]]></category>

		<guid isPermaLink="false">http://datenschwanz.net/?p=344</guid>
		<description><![CDATA[Apparently, it&#8217;s too much to ask to get a single line change in an open source project these days. It must be the economy. So, if you want ui:debug to work with SWF, and you happen to be using something approximately around Facelets 1.1.15, here&#8217;s the diff:


--- src/java/com/sun/facelets/tag/ui/UIDebug.java.orig       2009-10-15 [...]]]></description>
			<content:encoded><![CDATA[<p>Apparently, <a href="https://facelets.dev.java.net/issues/show_bug.cgi?id=312">it&#8217;s too much to ask to get a single line change</a> in an open source project these days. It must be the economy. So, if you want ui:debug to work with SWF, and you happen to be using something approximately around Facelets 1.1.15, here&#8217;s the diff:</p>
<p><span id="more-344"></span></p>
<pre class="brush: diff; wrap-lines: false;">
--- src/java/com/sun/facelets/tag/ui/UIDebug.java.orig       2009-10-15 10:03:16.000000000 -0500
+++ src/com/sun/facelets/tag/ui/UIDebug.java     2009-12-31 12:45:57.000000000 -0600
@@ -75,7 +75,7 @@
         sb.append(&quot;function faceletsDebug(URL) { day = new Date(); id = day.getTime(); eval(\&quot;page\&quot; + id + \&quot; = window.open(URL, '\&quot; + id + \&quot;', 'toolbar=0,scrollbars=1,location=0,statusbar=0,menubar=0,resizable=1,width=800,height=600,left = 240,top = 212');\&quot;); };&quot;);
         sb.append(&quot;var faceletsOrigKeyup = document.onkeyup; document.onkeyup = function(e) { if (window.event) e = window.event; if (String.fromCharCode(e.keyCode) == '&quot; + this.getHotkey() + &quot;' &amp; e.shiftKey &amp; e.ctrlKey) faceletsDebug('&quot;);
         sb.append(actionId);
-        sb.append('?');
+        sb.append(actionId.contains(&quot;?&quot;) ? '&amp;' : '?');
         sb.append(KEY);
         sb.append('=');
         sb.append(writeDebugOutput(faces));
</pre>
<p>Wow.</p>
]]></content:encoded>
			<wfw:commentRss>http://datenschwanz.net/2009/12/31/facelets-uidebug-and-spring-web-flow/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-nd/3.0/us/</creativeCommons:license>
	</item>
		<item>
		<title>ICEfaces and Spring Web Flow</title>
		<link>http://datenschwanz.net/2009/12/29/icefaces-and-spring-web-flow/</link>
		<comments>http://datenschwanz.net/2009/12/29/icefaces-and-spring-web-flow/#comments</comments>
		<pubDate>Tue, 29 Dec 2009 19:15:13 +0000</pubDate>
		<dc:creator>studmuffin</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[ICEfaces]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[JSF]]></category>
		<category><![CDATA[Spring Security]]></category>
		<category><![CDATA[Spring Web Flow]]></category>

		<guid isPermaLink="false">http://datenschwanz.net/?p=337</guid>
		<description><![CDATA[I have been banging on this project&#8217;s view with a few different technologies. I prototyped the thing in ZK, which turned out to be a complete piece of shit after trying to get it to work in a real world scenario. (More on that later.) Now it&#8217;s all about JSF. ICEfaces has some pretty neat [...]]]></description>
			<content:encoded><![CDATA[<p>I have been banging on this project&#8217;s view with a few different technologies. I prototyped the thing in ZK, which turned out to be a complete piece of shit after trying to get it to work in a real world scenario. (More on that later.) Now it&#8217;s all about JSF. ICEfaces has some pretty neat components and I have almost everything mocked up. Getting the flows and conversations to work with JPA is no problem with Spring Web Flow, either. The issue is getting ICEfaces into the mix.</p>
<p><span id="more-337"></span><br />
One particular pain is this hack done in ICEfaces 1.8.2 (I don&#8217;t know when it originally went in to the code) to grab the SWF FlowExecutor, the SpringWebFlowInstantiationServlet. I was wondering why my application context was being loaded twice, populating the MXJ database with a shitload of fake data for testing AGAIN, and then getting unique key exception. Well, this little bitch completely loads your application context a second time, side-effects and all. This new version of it should handle everything that needs to handled, without the retardation:</p>
<pre class="brush: java; wrap-lines: false;">
package com.icesoft.faces.env;

import java.io.IOException;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import org.springframework.webflow.executor.FlowExecutor;

public class SpringWebFlowInstantiationServlet
	extends HttpServlet
{

	private static FlowExecutor flowExecutor;

	public static FlowExecutor getFlowExecutor() {
		return flowExecutor;
	}

	private static void setFlowExecutor(FlowExecutor flowExecutor) {
		SpringWebFlowInstantiationServlet.flowExecutor = flowExecutor;
	}

	@Override
	public void init(ServletConfig servletConfig)
		throws ServletException
	{
		super.init(servletConfig);

		final WebApplicationContext webApplicationContext = WebApplicationContextUtils.getWebApplicationContext(servletConfig.getServletContext());

		final String[] beanNames = webApplicationContext.getBeanNamesForType(FlowExecutor.class);

		if (beanNames.length == 0) {
			throw new IllegalStateException(&quot;No bean of type FlowExecutor defined in context&quot;);
		} else if (beanNames.length &gt; 1) {
			throw new IllegalStateException(&quot;More than one bean of type FlowExecutor defined in context.&quot;);
		} else {
			setFlowExecutor(webApplicationContext.getBean(beanNames[0], FlowExecutor.class));
		}
	}

	@Override
	public void service(HttpServletRequest request, HttpServletResponse response)
		throws ServletException, IOException
	{
		// this servlet is for instantiation SpringWebFlow but does not handle
		// requests
	}

}
</pre>
<p>I don&#8217;t know why that was so difficult the first time around. Maybe I&#8217;m missing something, but didn&#8217;t anyone think, &#8220;Wow, there must be a better way.&#8221; Not loading the Spring ContextLoaderListener isn&#8217;t optional for a lot of things, so why load it what would be a second time to fetch a single bean? It makes no sense.</p>
<p>While we&#8217;re at it with the patching of ICEfaces, there are some patches that needs to be made to ICEfaces to get it to work with Spring Security 3.0.0.</p>
<pre class="brush: diff; wrap-lines: false;">
diff -ur core/src/com/icesoft/faces/context/BridgeExternalContext.java src/com/icesoft/faces/context/BridgeExternalContext.java
--- core/src/com/icesoft/faces/context/BridgeExternalContext.java       2009-09-03 15:58:18.000000000 -0500
+++ src/com/icesoft/faces/context/BridgeExternalContext.java     2009-12-29 13:01:35.000000000 -0600
@@ -95,6 +95,13 @@
         } catch (Throwable t) {
             Log.debug(&quot;Spring Security not detected.&quot;);
         }
+        try {
+            SpringAuthenticationClass = Class.forName(&quot;org.springframework.security.core.Authentication&quot;);
+            AuthenticationClass = SpringAuthenticationClass;
+            Log.debug(&quot;Spring Security 3 detected.&quot;);
+        } catch (Throwable t) {
+            Log.debug(&quot;Spring Security 3 not detected.&quot;);
+        }
     }

     protected static final RequestAttributes NOOPRequestAttributes = new RequestAttributes() {
diff -ur core/src/com/icesoft/faces/env/SpringAuthWrapper.java src/com/icesoft/faces/env/SpringAuthWrapper.java
--- core/src/com/icesoft/faces/env/SpringAuthWrapper.java       2008-11-13 04:11:26.000000000 -0600
+++ src/com/icesoft/faces/env/SpringAuthWrapper.java     2009-12-29 13:02:37.000000000 -0600
@@ -33,16 +33,17 @@

 package com.icesoft.faces.env;

-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.springframework.security.Authentication;
-import org.springframework.security.GrantedAuthority;
-import org.springframework.security.context.HttpSessionContextIntegrationFilter;
-import org.springframework.security.context.SecurityContext;
-
 import java.security.Principal;
+import java.util.Collection;
 import java.util.Map;

+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.context.SecurityContext;
+import org.springframework.security.web.context.HttpSessionContextIntegrationFilter;
+
 public class SpringAuthWrapper implements Authorization {
     private final static Log Log = LogFactory.getLog(SpringAuthWrapper.class);
     private final Authentication authentication;
@@ -57,13 +58,13 @@
         }
         Log.trace(&quot;isUserInRole ROLE: &quot; + role);

-        GrantedAuthority[] authorities = authentication.getAuthorities();
+        Collection&lt;GrantedAuthority&gt; authorities = authentication.getAuthorities();
         if (authentication.getPrincipal() == null || authorities == null) {
             return false;
         }

-        for (int i = 0; i &lt; authorities.length; i++) {
-            if (role.equals(authorities[i].getAuthority())) {
+        for (GrantedAuthority authority : authorities) {
+            if (role.equals(authority.getAuthority())) {
                 return true;
             }
         }
diff -ur core/src/com/icesoft/util/SeamUtilities.java src/com/icesoft/util/SeamUtilities.java
--- core/src/com/icesoft/util/SeamUtilities.java        2009-06-24 09:25:58.000000000 -0500
+++ src/com/icesoft/util/SeamUtilities.java      2009-12-28 21:51:29.000000000 -0600
@@ -67,7 +67,7 @@
     private static int springLoaded = 0;

     private static String SPRING_SECURITY_CONTEXT_HOLDER =
-            &quot;org.springframework.security.context.SecurityContextHolder&quot;;
+            &quot;org.springframework.security.core.context.SecurityContextHolder&quot;;
     private static int springSecurityLoaded = 0;

     static {
</pre>
<p>Yeah, really just a package name changes and that authorities return value again. It should probably check for both versions in SeamUtilities, but I only use one.</p>
]]></content:encoded>
			<wfw:commentRss>http://datenschwanz.net/2009/12/29/icefaces-and-spring-web-flow/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-nd/3.0/us/</creativeCommons:license>
	</item>
		<item>
		<title>Spring Security 3 and JSF</title>
		<link>http://datenschwanz.net/2009/12/23/spring-security-3-and-jsf/</link>
		<comments>http://datenschwanz.net/2009/12/23/spring-security-3-and-jsf/#comments</comments>
		<pubDate>Wed, 23 Dec 2009 14:59:37 +0000</pubDate>
		<dc:creator>studmuffin</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Facelets]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[JSF]]></category>
		<category><![CDATA[Spring Security]]></category>

		<guid isPermaLink="false">http://datenschwanz.net/?p=333</guid>
		<description><![CDATA[I&#8217;ve been hunting down bugs all day and getting next to nothing done. After finding that Spring would rather convert a String into a bunch of smaller Strings than let me do my work, I find even more. Fortunately, this one was a cinch.
Needing something to do role-based conditional processing in my JSF pages, I [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been hunting down bugs all day and getting next to nothing done. After finding that <a href="https://jira.springsource.org/browse/SEC-1342">Spring would rather convert a String into a bunch of smaller Strings</a> than let me do my work, I find even more. Fortunately, this one was a cinch.</p>
<p>Needing something to do role-based conditional processing in my JSF pages, I ended up with what looks like what may be possibly <a href="http://dominikdorn.com/?p=45">the only open source solution</a>. (If there are more, please let me know.) It&#8217;s unfortunate that <a href="http://jira.springframework.org/browse/FACES-34">Spring decided not to support JSF for Spring Security</a> when they support a JSP/JSTL taglib. Supposedly, <a href="https://jira.springsource.org/browse/SEC-1218">Spring Security isn&#8217;t tied to any web tier</a> technology. That doesn&#8217;t make sense. Drop the taglib, then, assholes. Move it into another package or something. It&#8217;s not like JSF tags are a difficult problem, either. Standard framework support probably belongs under Spring Security. If it&#8217;s all in one place, cohesive, and it works, people won&#8217;t be annoyed.</p>
<p>That being said, it&#8217;s also unfortunate that Dominik decided to go with <a href="http://dominikdorn.com/facelets/">a google code project</a>. I don&#8217;t want to log into google for every god damned thing. There are other alternatives that aren&#8217;t complete shit. So, just out of spite, I&#8217;m not using that shitheaded issue tracker and I&#8217;m posting about it here. I&#8217;m not even going to link to it. Just set up Trac or something. You already run a site.</p>
<p>Anyway, the taglib is broken, so here&#8217;s the fix&#8230;</p>
<p><span id="more-333"></span><br />
I guess Spring Security updated an interface in 3.0.0. You just need to pull out org.springframework.security.taglibs.facelets.SpringSecurityELLibrary from the taglib&#8217;s source jar, update line 58 to use a Collection instead of a List, and stick the source on your classpath (or repackage the jar).</p>
<p>I sent this email to <a href="http://www.dominikdorn.com/">Dominik Dorn</a>, the author, but it has probably fallen into a contact form black hole by now:</p>
<blockquote><p>SpringSecurityELLibrary is attempting to get the user&#8217;s authorities on line 58 and it&#8217;s expecting a List:</p>
<p>List<GrantedAuthority> authorities = currentUser.getAuthorities();</p>
<p>However, that isn&#8217;t the case. We get an exception like this:</p>
<p>java.lang.NoSuchMethodError: org.springframework.security.core.Authentication.getAuthorities()Ljava/util/List;</p>
<p>The current method signature in Authentication is:</p>
<p>Collection<GrantedAuthority> getAuthorities();
</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://datenschwanz.net/2009/12/23/spring-security-3-and-jsf/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-nd/3.0/us/</creativeCommons:license>
	</item>
		<item>
		<title>Load Time Weaving with Spring, AspectJ, and Tomcat</title>
		<link>http://datenschwanz.net/2009/12/21/load-time-weaving-with-spring-aspectj-and-tomcat/</link>
		<comments>http://datenschwanz.net/2009/12/21/load-time-weaving-with-spring-aspectj-and-tomcat/#comments</comments>
		<pubDate>Mon, 21 Dec 2009 17:10:38 +0000</pubDate>
		<dc:creator>studmuffin</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[AOP]]></category>
		<category><![CDATA[AspectJ]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Spring Framework]]></category>
		<category><![CDATA[Spring Security]]></category>
		<category><![CDATA[Tomcat]]></category>

		<guid isPermaLink="false">http://datenschwanz.net/?p=313</guid>
		<description><![CDATA[I&#8217;m currently working on a project that has given me the lovely opportunity to revisit the holy hell that is Tomcat. It&#8217;s fine and all, but it can be a real bitch to you. So I have a fine mix of JPA 2 (via EclipseLink 2.0.0), Spring 3.0.0, and AspectJ 1.6.6 running on Tomcat 6.0.20. [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m currently working on a project that has given me the lovely opportunity to revisit the holy hell that is Tomcat. It&#8217;s fine and all, but it can be a real bitch to you. So I have a fine mix of JPA 2 (via EclipseLink 2.0.0), Spring 3.0.0, and AspectJ 1.6.6 running on Tomcat 6.0.20. I have been trying to get persisted HttpSessions to autowire with AspectJ injecting Spring beans back into the JSF beans (also managed by Spring) when the sessions were deserialized. Things look kind of like this&#8230;</p>
<p><span id="more-313"></span><br />
We have our load time weaving configured via the Tomcat class loader instrumentation, courtesy of Spring. Since we are using Tomcat, -javaagent: is not required on the command line.</p>
<p>WebContent/META-INF/context.xml:</p>
<pre class="brush: xml; wrap-lines: false;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;Context&gt;
	&lt;Loader loaderClass=&quot;org.springframework.instrument.classloading.tomcat.TomcatInstrumentableClassLoader&quot; /&gt;
&lt;/Context&gt;
</pre>
<p>Next, we have our AspectJ configuration to handle our application classes (xxx stands for our package base), skipping what is already instrumented (lest we run into stack brokenness), and injecting things during deserialization.</p>
<p>WebContent/WEB-INF/classes/META-INF/aop.xml:</p>
<pre class="brush: xml; wrap-lines: false;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;!DOCTYPE aspectj PUBLIC &quot;-//AspectJ//DTD//EN&quot; &quot;http://www.eclipse.org/aspectj/dtd/aspectj.dtd&quot;&gt;
&lt;aspectj&gt;
	&lt;weaver options=&quot;-verbose -showWeaveInfo -XmessageHandlerClass:org.springframework.aop.aspectj.AspectJWeaverMessageHandler&quot;&gt;
		&lt;include within=&quot;xxx..*&quot; /&gt;
		&lt;exclude within=&quot;xxx..*CGLIB*&quot; /&gt;
		&lt;exclude within=&quot;xxx..*javassist*&quot; /&gt;
	&lt;/weaver&gt;
	&lt;aspects&gt;
		&lt;aspect name=&quot;org.springframework.beans.factory.aspectj.AbstractInterfaceDrivenDependencyInjectionAspect&quot; /&gt;
	&lt;/aspects&gt;
&lt;/aspectj&gt;
</pre>
<p>Spring is configured with the standard bunch of annotation processing and AOP tags.</p>
<p>WebContent/WEB-INF/applicationContext.xml:</p>
<pre class="brush: xml;">
	&lt;context:load-time-weaver /&gt;
	&lt;context:annotation-config /&gt;
	&lt;context:component-scan annotation-config=&quot;false&quot; base-package=&quot;xxx&quot; /&gt;
	&lt;context:spring-configured /&gt;
	&lt;tx:annotation-driven mode=&quot;aspectj&quot; proxy-target-class=&quot;true&quot; /&gt;
</pre>
<p>Finally, we have some service classes, DAOs, etc. annotated thusly&#8230; <em>Note: None of these annotated component/configurable beans are configured in applicationContext.xml, although you can use prototypes in the XML.</em></p>
<pre class="brush: java;">
@Configurable(autowire = Autowire.BY_TYPE, dependencyCheck = true)
@Controller(&quot;thingTableModel&quot;)
@Scope(&quot;session&quot;)
public class ThingTableModel
	extends AbstractTableModel&lt;Thing&gt;
{

	private static final long serialVersionUID = 1L;

	@Autowired(required = true)
	private transient ThingController _thingController;

	...
}
</pre>
<div class="boxnote">
This <em>thingTableModel</em> is accessible as a JSF bean thanks to a bit like this:</p>
<p>faces-config.xml:</p>
<pre class="brush: xml; wrap-lines: false;">
	&lt;application&gt;
		...
		&lt;el-resolver&gt;org.springframework.web.jsf.el.SpringBeanFacesELResolver&lt;/el-resolver&gt;
	&lt;/application&gt;
</pre>
</div>
<pre class="brush: java;">
@Service(&quot;thingController&quot;)
@Transactional
public class ThingController {

	@PersistenceContext
	private EntityManager _entityManager;

	@Autowired(required = true)
	private ThingDAO _thingDAO;

	@Secured(&quot;ROLE_ADMINISTRATOR&quot;)
	@Transactional
	public void createThing(Thing thing) {
		_thingDAO.persistRefresh(thing);
	}

	@Secured(&quot;ROLE_ADMINISTRATOR&quot;)
	@SuppressWarnings(&quot;unchecked&quot;)
	@Transactional(readOnly = true)
	public List&lt;Thing&gt; getThings() {
		return _entityManager.createQuery(&quot;SELECT x FROM Thing x ORDER BY x.shape&quot;).getResultList();
	}

	...
}
</pre>
<p>You can imagine the typical generics DAO hierarchy here with the interfaces and JPA-specific implementation yadda yadda, but the annotation here is on the final concrete class (although there is an @PersistenceContext stuck on an EntityManager field in the abstract DAO implementation.)</p>
<pre class="brush: java;">
@Repository
public class ThingDAOImpl
	extends AbstractDAOImpl&lt;Thing, Integer&gt;
	implements ThingDAO
{
	...
}
</pre>
<p>Everything was working great, until NPEs showed up after sessions were restored after Tomcat restarts. The controllers were all null in the JSF beans. This was obviously broken injection. After poring over (no, not &#8220;pouring over&#8221;, numbskull) about 20MiB of logs, I had proof:</p>
<pre class="brush: plain; light: true;">
+main DEBUG wiring.BeanConfigurerSupport - BeanFactory has not been set on BeanConfigurerSupport: Make sure this configurer runs in a Spring container. Unable to configure bean of type [xxx.view.ThingTableModel]. Proceeding without injection.
</pre>
<p>Based on the location of this line, which was before the application context started up and right after sessions were being loaded from disk, it all made sense. But, how to fix&#8230;</p>
<p>This is all it was! One fucking line (or three if you like it that way):</p>
<pre class="brush: xml; wrap-lines: false;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;Context&gt;
	&lt;Loader loaderClass=&quot;org.springframework.instrument.classloading.tomcat.TomcatInstrumentableClassLoader&quot; /&gt;
	&lt;Manager className=&quot;org.apache.catalina.session.StandardManager&quot; algorithm=&quot;SHA&quot; maxInactiveInterval=&quot;600&quot; /&gt;
	&lt;!--
	 - Also a possibility...
	&lt;Manager className=&quot;org.apache.catalina.session.PersistentManager&quot; algorithm=&quot;SHA&quot; maxInactiveInterval=&quot;600&quot;&gt;
		&lt;Store className=&quot;org.apache.catalina.session.FileStore&quot; /&gt;
	&lt;/Manager&gt;
	 --&gt;
&lt;/Context&gt;
</pre>
<p>The issue at hand was that the sessions were being loaded by the main Tomcat StandardManager before the Spring application context was even a glimmer in Tomcat&#8217;s eye. Now that this web app had its own session manager configured, everything was fixed, just in time for the winter solstice!</p>
<p>Keep in mind that if you use Spring Security and you do anything extra during injection with a setter method, there will be no authorization context at that time and the injection will fail. So, make sure that there are no @Secured methods in your call path.</p>
<p>Also, keep an eye on your jars. org.springframework.instrument.tomcat-<ver>.jar goes in ${catalina.home}/lib (no more common/lib in Tomcat 6) and org.springframework.instrument-<ver>.jar goes nowhere. You don&#8217;t need it in your app&#8217;s WEB-INF/lib.</p>
]]></content:encoded>
			<wfw:commentRss>http://datenschwanz.net/2009/12/21/load-time-weaving-with-spring-aspectj-and-tomcat/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-nd/3.0/us/</creativeCommons:license>
	</item>
	</channel>
</rss>
