title

fire chief's random developer tidbits

Thursday, November 29, 2012

Hibernate SQLQuery and Oracle CLOB (long text)

This is possibly very obvious but it took me a while to find the answer.  Using existing native queries (SQLQuery) in hibernate I have a CLOB column I needed to map using a result set transformer.  Note when you use one addScalar() you must map every column with addScalar() that you want returned.  Use the org.hibernate.type.TextType (hibernate 3.5, it looks like hibernate 4 would be TextType.TEXTTYPE).

String sql = "SELECT BLAH_ID as id, FOO_DETAIL as detailText FROM blah";

Query query =
            session.createSQLQuery(sql)
            .addScalar("id")
            .addScalar("detailText", new TextType())
            .setResultTransformer(Transformers.aliasToBean(SomePojo.class));

class SomePojo {
    private Long id;
    private String detailText;

    ...getters and setters...
}
Now the real question is why did they do this native hibernate inside a Spring JpaRepository and not use NamedParameterJDBCTemplate with BeanPropertyRowMapper? It's very similar but I find the Spring style cleaner. Time to refactor.

Monday, November 19, 2012

Grizzly slashes

Glassfish uses Grizzly internally to serve up web apps and grizzly by default doesn't allow encoded slashes in URLs, returning a 400 error.  Here's how to change that setting:


asadmin set
 configs.config.server-config.network-config.protocols.protocol.http-listener-1.http.encoded-slash-enabled=true

This came up when receiving an encrypted URL encoded string in as a path parameter to a restful JAX-RS service in Spring MVC.

http://java.net/jira/browse/JERSEY-1456

Thursday, October 4, 2012

Another reason to dislike Internet Explorer


Internet explorer caches GET requests, but other browsers do not, so you end up having to work around that by adding a current timestamp to the request URL to fool IE into thinking it's a new URL and so not read the result from the cache.

In JQuery that looks like ("global"):

$.ajaxSetup({ cache: false });

or single-call:

$.ajax({url: "myurl", success: myCallback, cache: false});

Thursday, July 12, 2012

When a Date is not a Date

Just because something like Oracle SQL Developer shows a date column and does not show the time, don't assume that's the type of the column.  For whatever stupid reason it defaults the format of a Date column to not include the time, even though by default an Oracle Date type has a time included.  This bad assumption on my part and bad default on their part led to an hour or so of wondering how a query in existing code could possibly work because I kept using a date with no time as my test data.  Yes it can work as long as the hh:mm:ss is included in the query.  Grr.

Anyway, here's how to configure it for the next time I need it:
Tools -> Preferences -> Database -> NLS
Change Date format to: DD-MON-RR HH:MI:SS

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.