title

fire chief's random developer tidbits

Thursday, June 7, 2012

Chicks dig ninja loop debugging skills

Let's say you have a long running process that is misbehaving and there are other more important processes in the same JVM.  You want to kill the misbehaving process because it is leaking memory (or whatever).  You can attach a debugger and see it looping through its job and find that it has a ton of work to do.  You want to stop it so other more important processes can get some processing time and some memory.  If the loop is a for each on a hashmap you can cause it to early exit by doing a couple things.  Here's how:

  1. find the hashmap's internal table object count: table.count
  2. in the i$ iterator object representing the for each, set the index to just below the table.count
  3. iterator will exit without ConcurrentModification or other errors
WARNING: don't do this unless you understand the process you are interrupting in a deep way and know that there are no side effects.

Wednesday, April 11, 2012

List all users crontabs in Linux

Listing all users crontabs:
cut -d: -f1 /etc/passwd | xargs -I {} sudo crontab -u {} -l | less

This worked on gentoo.

Monday, April 2, 2012

Two declarations cause a collision in the ObjectFactory class.

Given a wsdl generated by .net(c#) with inline object specifications, JAX-WS will have trouble with the naming of some of the objects and give the error "Two declarations cause a collision in the ObjectFactory class.".  This seems to be the most common problem with JAX-WS and finding the right recipe was problematic.  Netbeans (7.1.1) didn't help things because the maven plugin code it generated is a very outdated version (1.10 from codehaus).  Upgrading that (not absolutely sure if it was required) using this guide seemed to help: http://jax-ws-commons.java.net/jaxws-maven-plugin/ (and specifically http://jax-ws-commons.java.net/jaxws-maven-plugin/examples/using-jaxb-plugins.html). A co-worker and I tried a lot of combinations to get autoNameResolution working, because that seems to be the answer that works for a lot of other people.  We never did get that to work.  What did work was getting a correctly formatted binding file with references to all the right namespaces so the xpath would work and the problematic object could be renamed.  This page provided an important clue on the format:  http://docs.oracle.com/javaee/5/tutorial/doc/bnbbf.html under the heading: External Binding Customization Files.

Correct structure for binding xml:

<jxb:bindings schemaLocation = "xs:anyURI">
   <jxb:bindings node = "xs:string">
      <binding declaration>
   <jxb:bindings>
</jxb:bindings>

Thursday, March 8, 2012

IllegalAccessError when accessing an enum type in a switch statement

We got this error:  java.lang.IllegalAccessError: com/mycompany/MySessionBean$1 when using a switch statement on an Enum inside a stateless session bean.  It took some puzzling, but the answer ended up being that Java builds an anonymous class internally to handle the switch on enum.  We were accidentally deploying two copies of the $1 class file due to Maven's default excludes on ejb-client not excluding these.  Our ear has an application client which needs an ejb-client jar version of the main ejb jar.  The client jar had a copy of the $1 class when it should not have.  The fix was to include <clientExclude>**/*Bean$*.class</clientExclude> in the ejb-jar plugin config, along with all the maven default configs.

The root cause of this may be that there were different classloaders in Glassfish loading separate copies of the class.

Monday, January 23, 2012

Netbeans code templates

Apparently since Netbeans 6.9, code templates can insert the current class name, and I just found out now that 7.1 is out.  So one template I use all the time I named "logger" and now that I found this feature, I can make the template be:
private static final ${loggerType type="org.slf4j.Logger" default="Logger" editable="false"} logger = ${loggerFactory type="org.slf4j.LoggerFactory" default="LoggerFactory" editable="false"}.getLogger(${classVar editable="false" currClassName default="getClass()"}.class);

Then just by typing "logger[tab]" in inserts:
private static final Logger logger = LoggerFactory.getLogger(CurrentClassName.class);

and it even adds the imports for org.slf4j.  Nice!

This is a great little timesaver.  They have a couple in there for java.util.Logging already (logr and logr).  I need to go through the templates again.

Thursday, January 19, 2012

Glassfish directory deploy

Netbeans has an integration with Glassfish where it can deploy an ear as a directory.  This does not currently work with the "skinny war recipe" in maven.  Bug 199096 is the source of the trouble.  Since the skinny war renames jars and depends on those names and the bug causes the naming to not work, the deploy fails because it can't see the various components of the ear.  In our case we've got an ear containing two wars, an ejb jar, and many libraries with a (typical for JEE) ugly interdependency graph.

Found this while trying out JRebel, which is an awesome product.  We are buying it today at my work.

Tuesday, October 4, 2011

java.util.logging is a joke

pointing the logging system to a properties file works with -Djava.util.logging.config.file=logging.properties
HOWEVER
if you have this contents for example:

handlers=java.util.logging.ConsoleHandler
java.util.logging.ConsoleHandler.level=FINE
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter

it will give the error:
"Can't set level for java.util.logging.ConsoleHandler"

This is simply because there is a SPACE after "level=FINE ".  Really!?  That's terrible.  Back to log4j or maybe logback.