Tomcat 6 vs Tomcat 7 ThreadsPosted by Roger Keays, 8 April 2012, 11:04 AM
The blue line is max threads, the green area is used threads. The same code is run on Tomcat 6 and Tomcat 7. | ||||||||||||||||||||||||||||||||||||||||||
ServletRequest.setCharacterCoding() IgnoredPosted by Roger Keays, 2 April 2012, 3:57 PM Take a look at this block of servlet code and see if you can tell me what the output should be when I send x=éééé
Log.warning(Charset.defaultCharset().toString());
Log.warning(request.getCharacterEncoding());
Log.warning(request.getParameter("x"));
request.setCharacterEncoding("UTF-8");
Log.warning(request.getCharacterEncoding());
Log.warning(request.getParameter("x"));
Well, here is the output UTF-8 null éééé UTF-8 éééé Compare this code
Log.warning(Charset.defaultCharset());
Log.warning(request.getCharacterEncoding());
request.setCharacterEncoding("UTF-8");
Log.warning(request.getCharacterEncoding());
Log.warning(request.getParameter("x"));
Which gives us something more sensible: UTF-8 null UTF-8 éééé Lesson of the day? You can't change the request encoding after request.getParameter() has been called. In my case a third-party filter was causing the damage, so I made a new filter at the top of the chain just to call request.setCharacterEncoding(). Note also that the default character encoding which I set with -Dfile.encoding=UTF-8 had no effect on the decoding of request parameters. Also, the form is POSTed with multipart/form-data and I added accept-charset to force the browser to send UTF-8: <form method="post" enctype="multipart/form-data" accept-charset="UTF-8" > <input type="text" name="x"/> <input type="submit"/> </form> | ||||||||||||||||||||||||||||||||||||||||||
Upgrading To The Java EE 6 Web ProfilePosted by Roger Keays, 21 March 2012, 1:21 PM Here are my notes from our upgrade of the Sunburnt SEO software to the Java EE 6 Web Profile. Previously our stack was pretty similar to Java Web Profile, just with a lot more dependencies than is now necessary with EE 6. We can now deploy to Glassfish 3.1 or a modified Tomcat 7.0, since we aren't using the EJB features of Java EE 6. Code Changespersistence.xml is now version 2.0
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
web.xml is now version 3.0
<web-app xmlns="http://java.sun.com/xml/ns/javaee" version="3.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
Remove vendor-specific JPA annotations.
| ||||||||||||||||||||||||||||||||||||||||||
java.lang.ClassFormatError Exception With EclipseLink Static Weaving [SOLVED]Posted by Roger Keays, 19 March 2012, 4:48 AM Here's an interesting exception that slapped me when I tried out using the EclipseLink static weaver on against a fresh Maven pom.xml for Java EE Web projects. The same exception occurs with the OpenJPA enhancer.
Executing tasks
[java] Exception in thread "main" java.lang.ClassFormatError: Absent Code attribute in method that is not native or abstract in class file javax/persistence/ValidationMode
[java] at java.lang.ClassLoader.defineClass1(Native Method)
[java] at java.lang.ClassLoader.defineClassCond(ClassLoader.java:631)
[java] at java.lang.ClassLoader.defineClass(ClassLoader.java:615)
[java] at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
[java] at java.net.URLClassLoader.defineClass(URLClassLoader.java:283)
[java] at java.net.URLClassLoader.access$000(URLClassLoader.java:58)
[java] at java.net.URLClassLoader$1.run(URLClassLoader.java:197)
[java] at java.security.AccessController.doPrivileged(Native Method)
[java] at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
[java] at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
[java] at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
[java] at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
[java] at org.apache.openjpa.persistence.PersistenceProductDerivation.configureBeanValidation(PersistenceProductDerivation.java:241)
[java] at org.apache.openjpa.persistence.PersistenceProductDerivation.beforeConfigurationLoad(PersistenceProductDerivation.java:214)
It turns out this obscure error is because the default Java EE jars do not contain any actual code. To fix it, change your Java EE dependencies from
<!-- Java EE libraries -->
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-web-api</artifactId>
<version>6.0</version>
<scope>provided</scope>
</dependency>
to
<!-- default Jave EE jars don't include code necessary fo
bytecode enhancement so we use these instead -->
<dependency>
<groupId>org.jboss.spec</groupId>
<artifactId>jboss-javaee-6.0</artifactId>
<version>1.0.0.Final</version>
<type>pom</type>
<scope>provided</scope>
</dependency>
You will also need to add the JBoss repository to your pom.xml if you aren't already using it:
<repositories>
<repository>
<id>repository.jboss.org-public</id>
<name>JBoss repository</name>
<url>https://repository.jboss.org/nexus/content/groups/public</url>
</repository>
</repositories>
| ||||||||||||||||||||||||||||||||||||||||||
java.lang.ClassNotFoundException: com.sun.el.lang.VariableMapperImpl [Fixed] for Glassfish JSFPosted by Roger Keays, 18 March 2012, 5:34 PM Using Glassfish 3.1.2, JSF 2.1.x and Facelets with client side state saving, if you pass a bean reference by EL and try to dereference that expression you will get the following error: Servlet.service() for servlet Faces Servlet threw exception java.lang.ClassNotFoundException: com.sun.el.lang.VariableMapperImpl at org.glassfish.web.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1509) at org.glassfish.web.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1359) at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Class.java:247) at com.sun.faces.renderkit.ApplicationObjectInputStream.resolveClass(ApplicationObjectInputStream.java:95) at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1574) at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1495) at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1731) at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328) at java.io.ObjectInputStream.readObject(ObjectInputStream.java:350) at com.sun.el.MethodExpressionImpl.readExternal(MethodExpressionImpl.java:320) at java.io.ObjectInputStream.readExternalData(ObjectInputStream.java:1791) at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1750) at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328) at java.io.ObjectInputStream.readObject(ObjectInputStream.java:350) at com.sun.faces.facelets.el.TagMethodExpression.readExternal(TagMethodExpression.java:158) at java.io.ObjectInputStream.readExternalData(ObjectInputStream.java:1791) at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1750) at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328) at java.io.ObjectInputStream.readArray(ObjectInputStream.java:1666) at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1322) at java.io.ObjectInputStream.readArray(ObjectInputStream.java:1666) at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1322) at java.io.ObjectInputStream.readArray(ObjectInputStream.java:1666) at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1322) at java.io.ObjectInputStream.readObject(ObjectInputStream.java:350) at java.util.HashMap.readObject(HashMap.java:1030) at sun.reflect.GeneratedMethodAccessor264.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:974) at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1848) at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1752) at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328) at java.io.ObjectInputStream.readObject(ObjectInputStream.java:350) at com.sun.faces.renderkit.ClientSideStateHelper.doGetState(ClientSideStateHelper.java:255) at com.sun.faces.renderkit.ClientSideStateHelper.getState(ClientSideStateHelper.java:198) at com.sun.faces.renderkit.ResponseStateManagerImpl.getState(ResponseStateManagerImpl.java:100) at com.sun.faces.application.view.StateManagementStrategyImpl.restoreView(StateManagementStrategyImpl.java:227) at com.sun.faces.application.StateManagerImpl.restoreView(StateManagerImpl.java:188) at com.sun.faces.application.view.ViewHandlingStrategy.restoreView(ViewHandlingStrategy.java:123) at com.sun.faces.application.view.FaceletViewHandlingStrategy.restoreView(FaceletViewHandlingStrategy.java:453) at com.sun.faces.application.view.MultiViewHandler.restoreView(MultiViewHandler.java:148) at javax.faces.application.ViewHandlerWrapper.restoreView(ViewHandlerWrapper.java:303) at javax.faces.application.ViewHandlerWrapper.restoreView(ViewHandlerWrapper.java:303) at com.sun.faces.lifecycle.RestoreViewPhase.execute(RestoreViewPhase.java:192) at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101) at com.sun.faces.lifecycle.RestoreViewPhase.doPhase(RestoreViewPhase.java:116) at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118) at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593) The workaround is to add el-ri.jar to your project. You can do it in maven like this:
<dependency>
<groupId>com.sun.el</groupId>
<artifactId>el-ri</artifactId>
<version>1.0</version>
<scope>compile</scope>
</dependency>
The problem is tracked by the JAVASERVERFACES-1828 bug. | ||||||||||||||||||||||||||||||||||||||||||
Change J2EE Version Of Netbeans Maven ProjectPosted by Roger Keays, 16 March 2012, 6:07 PM For Maven projects, Netbeans determines the J2EE version shown in the project properties by looking at the version of web.xml:
You have to restart Netbeans to see the changes. | ||||||||||||||||||||||||||||||||||||||||||
WTF Triple Negative!Posted by Roger Keays, 16 March 2012, 4:44 PM Check out this JPA parameter: <exclude-unlisted-classes>false</exclude-unlisted-classes> Now see if you can tell me if it includes my listed classes. | ||||||||||||||||||||||||||||||||||||||||||
How To Show Negative Numbers Using Brackets With NumberFormatter In JavaPosted by Roger Keays, 15 March 2012, 8:46 AM If you want to use parentheses around your negative numbers, you can do it in Java like this:
NumberFormat formatter = NumberFormat.getCurrencyInstance(locale);
if (formatter instanceof DecimalFormat) {
DecimalFormat f = (DecimalFormat) formatter;
f.setNegativePrefix("(" + f.getPositivePrefix());
f.setNegativeSuffix(")");
}
String output = formatter.format(value);
This snippet will retain the localised currency formatting set by NumberFormat. | ||||||||||||||||||||||||||||||||||||||||||
How To Check If The Software Keyboard Is Shown In AndroidPosted by Roger Keays, 21 February 2012, 10:11 AM Here is a method to detect if the soft keyboard is visible on the screen in Android. All the other methods I have seen test the height of screen elements to guess whether it is displayed. This doesn't work for keyboards like WifiKeyboard which is an invisible keyboard. This method uses the callback result of InputMethodManager.showSoftInput() to determine if the keyboard status changed. This is suitable for me because I need to call showSoftInput() anyway if the keyboard is not shown. The result from the operation needs to be polled because it is asynchronous. This example only polls 500 milliseconds and assumes that anything longer than that is caused by the keyboard being loaded and rendered. Here is how the code is used:
// try to show the keyboard and capture the result
InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
IMMResult result = new IMMResult();
imm.showSoftInput(editText, 0, result);
// if keyboard doesn't change, handle the keypress
int res = result.getResult();
if (res == InputMethodManager.RESULT_UNCHANGED_SHOWN ||
res == InputMethodManager.RESULT_UNCHANGED_HIDDEN) {
showTags();
}
| ||||||||||||||||||||||||||||||||||||||||||
How To Move A Node In Nested Sets With SQLPosted by Roger Keays, 8 January 2012, 3:35 PM Moving nodes in nested sets is a complex operation. There were a few solutions on Stack Overflow for moving a node under a given parent, however this doesn't let you select the position of the node amongst it's siblings. This solution lets you move a node to any position in the tree, with just a single input parameter - the new left position (newpos) of the node. Fundamentally there are three steps:
In psuedo-sql, it looks like this:
/**
* -- create new space for subtree
* UPDATE tags SET lpos = lpos + :width WHERE lpos >= :newpos
* UPDATE tags SET rpos = rpos + :width WHERE rpos >= :newpos
*
* -- move subtree into new space
* UPDATE tags SET lpos = lpos + :distance, rpos = rpos + :distance
* WHERE lpos >= :tmppos AND rpos < :tmppos + :width
*
* -- remove old space vacated by subtree
* UPDATE tags SET lpos = lpos - :width WHERE lpos > :oldrpos
* UPDATE tags SET rpos = rpos - :width WHERE rpos > :oldrpos
*/
| ||||||||||||||||||||||||||||||||||||||||||
Android ORM / JPAPosted by Roger Keays, 19 December 2011, 6:01 AM Coming from the server-side, I find it hard to live without ORM (Object-Relational Mapping) such as JPA. Now that I've started writing Android Apps, I set about finding a JPA ORM tool for Android. Here is a comparison of the tools I found that do ORM and are lightweight enough for use with Android.
"DB Ops" refers to how database operations such as persist() and update() are handled. Normally either by a DAO (data access object) or by the entity themselves. Handling Large Data SetsPerformance counts - especially since I need to handle large data sets. I don't want to load 3000 records into memory at once when the device only has room to display 10 at a time. Native Android supplies a Cursor to interate large data sets, and some ORM tools provide their own method too. greenDAO has Query.lazyList() and OrmLite has DAO.iterator(Query) to do this, however Android adapters do not bind to an iterator so a custom adapter would need to be written in any case. There is a thread online that discusses this, however I think I can rig up a something similar to my LazyList for JPA to make this happen. VerdictI've started my project with OrmLite because it is the most mature. Lazy loading query results will need some custom code, but in the long run I think it will be better than polluting my code with column names and SQL hacks. greenDAO was a good candidate from the performance perspective, but really I want to write my Entities myself so I can add the methods that I need. | ||||||||||||||||||||||||||||||||||||||||||
Alt-Tab Shortcuts Broken In Ubuntu Lucid With XModMapPosted by Roger Keays, 15 December 2011, 6:52 AM I use xmodmap to turn caps-lock into an extra modifier for special keys and shortcuts. Since upgrading finally to Ubuntu Lucid 10.04 LTS, I've had a problem with the Caps-Lock modifier key (Mode_switch) getting stuck when I accidentally press the Shift key. When I get it unstuck by pressing the same combination of Caps, Shift and one of my special keys, all my X-Windows shortcuts like Alt-Tab and Function keys stop working. It's freaking annoying, however I finally found a workaround in Red Hat Bug 513815 and Bug 508434... $ setxkbmap -layout jp This resets your keyboard to it's original state. In my case the layout is japanese. You will probably want 'us' for US keyboards. Now you can reapply your xmodmap settings: $ xmodmap ~/.xmodmaprc It's still flaky, but it gets me back on the road. |
