BibleGateway.com Verse Of The Day

Wednesday, October 21, 2009

Running Multiple Versions of Oracle JDBC Driver on same JBoss server

We ran into an issue recently where we need 2 different versions of the Oracle JDBC driver on the same app server, because one application needs to talk to Oracle 8.0.6 (pre-8i even) and everything else talks to newer (9i and 10g) databases.

With the newer JDBC driver out in the Jboss server's lib/ directory, the legacy application fails to connect because of the dreaded ORA-604 that you get when trying to connect to a really early DB with a driver that doesn't go back that far. See the links below for Oracle's list of what drivers support what versions of Oracle. The exception is shown below in case you haven't seen it before.

Throwable while attempting to get a new connection: null
org.jboss.resource.JBossResourceException: Could not create connection; - nested throwable: (java.sql.SQLException: ORA-00604: error occurred at recursive SQL level 1
ORA-02248: invalid option for ALTER SESSION

Putting the old driver out in lib/ means that the newer datasources won't deploy properly.

After a few hours of Google searches and pouring through the Jboss.org wiki and forums, we just couldn't find the answer. We finally made this post to the Jboss forums:
We are using Jboss AS 4.2.2-GA and have hit a snag. One application needs to connect to an older Oracle 8 database, so we need to use the older Oracle JDBC driver. For all of our other applications, we need to use the newer Oracle JDBC driver.

But the classnames for the drivers are the same, so we can't figure a way to tell one *-ds.xml file to deploy under the early driver and everything else to use the newer driver.

We tried adding the older driver JAR file and the *-ds.xml file right in our application EAR file, but when deploying it picked up the newer Oracle driver from the server's lib directory anyways. This puzzled me as we are using ear-scoped classloaders.

Both applications are SEAM applications using EJB3/Hibernate. We can get one or the other to work depending on which Oracle driver we put in lib/ but can't get both to work at once.

I've been searching Google and the Jboss forums and wiki for the past 2 hours, and find lots of newbie "this is how to deploy a datasource" stuff, but nothing on 2 conflicting versions of a vendor's driver. HELP!
We got the response the next morning, and it turns out we were on the right path by putting the datasource file and classes12.zip in the application EAR file, but because of JDBC classloader issues, we had to also include a few other files and some extra application.xml config. Here is the complete article.



Links:

Tuesday, August 18, 2009

Multiple Column Subqueries (Oracle)

I recently had to do something like this in an application, and I had to look it up to see if it was even possible. I knew you could do this with a single value, but was skeptical if multiple columns could be done this easily.

For my own benefit, I am posting the basic syntax for next time I need to do it. Replace your table names where t1 and t2 are, column names for c1, c2, c3, etc. I did this in Oracle, but it may work the same or very similar in other databases.

SELECT *
FROM t1
WHERE (c1,c2,c3)
IN (
SELECT t2.c1,t2.c2,t2.c3
FROM t2
)

For reference, I found my answer at: http://www.java2s.com/Code/Oracle/Subquery/WritingMultipleColumnSubquerieswithtablejoin.htm

Wednesday, July 15, 2009

More Jboss SEAM Nuggets

As I dig farther into the Jboss SEAM world, I figured I would share a few nuggets of info as I find them. It's more notes than tutorial, so don't expect too much....


ORACLE TIMESTAMP ISSUES

If you are using Oracle, more specifically Oracle 9i and newer, you will probably have issues with date fields. There was a change in Oracle's JDBC driver somewhere between 8i and 9i that changes how the driver reports a DATE field in the metadata. Anyways, running seamgen gets you entities with Date objects with annotations like @Temporal(TemporalType.DATE).

When you go to deploy though, The validation fails because it is expecting a TIMESTAMP field, but gets a DATE field. That keeps the EJB from deploying and keeps the EntityManager from being bound.

Luckily, there is an easier fix than manually updating the data types and annotations in all your generated entities. You can add the following JVM argument to your startup to force the Oracle driver to report DATE fields based on the Oracle 8 driver behavior instead of the 9i+ driver:
-Doracle.jdbc.V8Compatible=true


RENDERING ISSUES ON SERVER

Speaking of JVM args, I noticed on my dev box (Windows), my SEAM app rendered beautifully. When I deployed to the Linux server, some of the fancy "3d" type components suddenly looked flat. There were exceptions in the log for some Swing classes (sorry I don't have the exact exception or stack trace, it was a while ago). Why is it using Swing to render page elements? Don't know, and at this point, don't care, as long as there is a simple fix. And alas, there is...

I added the following JVM argument to my Jboss startup to let it know it's a headless server. Seems to have fixed my issue.
-Djava.awt.headless=true


MULTIPLE PAGE DEFINITIONS FOR ONE PAGE

When you build out a new application using seamgen, you will notice that for each entity, you will have several view components. For example, you will have a TableName.xhtml and a TableName.page.xml file. The *.page.xml contains your <page> definition, that will define the view id, parameters, conversation settings, etc.

You will also notice that the SEAM pages.xml file also has (or can have) <page> definitions. Guess what, the pages.xml definition for a given page, if it exists, overrules the *.page.xml version. Remember that when changes you make to *.page.xml don't seem to take effect, or other odd behavior where those values seem to be ignored.

It's not a hierarchy, it's not an inheritance, it's a one-or-the-other situation. It caused me quite a bit of grief until I figured that out.



USING SEAM COMPONENTS FROM SERVLETS

So you need to throw in some regular old-school Servlet's into the mix? But you want your SEAM goodies too? Damn, you just want the best of everything.

There are a few ways to do it, and I found the easier way is to "wrap" your Servlet(s) in the SEAM filter. Add a line something like this to your SEAM components.xml file (make sure to change your URL pattern appropriately. In my case my Servlet is to download a CSV file).
<web:context-filter pattern="/csv"/>
And then in your Servlet code, you can get your SEAM stuff from the Components object like the sample below:
UnmappedAccount unMapAcct = (UnmappedAccount)Component.getInstance("unmappedAcct");
In this example, UnmappedAccount is a class in my EJB module annotated as a SEAM component.
import org.jboss.seam.annotations.Name;
...

@Name("unmappedAcct")
public class UnmappedAccount { ... }


CASCADING EJB'S

Allow me to throw out a minor warning on the generated SEAM code. The default CascadeType in the generated EJB's is "ALL", as seen in the annotation below.
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "...")
It's not devastating, it's not a bug, but it is something you should be aware of in case you don't want cascading (or worse, aren't aware of cascading and what it really means, and just happily go with the defaults).

See http://java.sun.com/javaee/5/docs/api/javax/persistence/CascadeType.html for more information on the various CascadeTypes, in case you don't already know. If you don't want cascading, remove the "cascade = CascadeType.ALL" portion of the generated annotation.

Let's say you try to delete a record that has children records attached to it. You might expect to get an error back saying you can't delete a record that has children attached. That's what you would get from, say TOAD or Squirrel or SQL-Plus, or even from applications written using plain old ODBC or JDBC statements. But with cascading, that delete will happily take care of those children for you without complaining ;-)



NAMED QUERY DEFINED IN COMPONENTS.XML

I just found this one, and it seems to be a good fit with what I have to do right now. I haven't finished it yet, so not much to share here yet. Once I get that working, it might be worth mentioning in my next nuggets post.

Thursday, May 28, 2009

Emergency Startup CD for Windows

BartPE, because sometimes you actually have to run Windows.

If you have Windows and your system did not come with a "rescue", "restore", or "emergency startup" type CD (yes, I'm talking to the cheap bastards at Dell who don't include the Windows CD), then you NEED to follow the instructions at http://www.howtohaven.com/system/live-windows-rescue-cd.shtml. This creates a bootable "BartPE" CD with all the right utilities for fixin' what ails ye.

Do it now! Before you need it, not after. I learned the hard way, and after this past week, I can't sing the praises of BartPE enough. It was a life saver.

My wife's laptop booted to a BSOD when I was trying to VPN in to work. Oh well, a night off....but then it kept doing it, over and over. I couldn't get Windows to start for the life of me.

Since I didn't have a bootable Windows CD, I was left trying to boot FreeDOS from my thumbdrive (using LiveUSB Creator) . I made sure to have a copy of NTFS4DOS installed on there as well, and ran through some exercises where I got a command prompt to manually copy registry files around. That was painful, but it actually worked enough to get the machine to boot into XP. But it was a version of XP that had all sorts of issues, error messages, drivers crashing, no USB support, no CD recording, no network, etc. Without USB, network, or CD burning, I couldn't get our important files off the machine.

Anyway, to make a long story short, the FreeDOS/ntfs4dos route was crappy and painful with no real reward.

The BartPE rocks the house! It boots into a minimal XP interface with all the right utilities for fixing your issues, and USB drives are recognized, so I can copy important files off the machine in case I feel the need to wipe it clean.

I guess I really should do regular backups, but what fun is that? Preventing problems is boring, solving problems is heroic....

Wednesday, April 08, 2009

Google App Engine And Java

I recently posted about my experience playing with the Google App Engine and the Python language, in which I wrote:
For now, the only supported language is Python....I wouldn't mind seeing other languages supported in GAE, though not sure it really matters or if it is worth Google's time, money, and effort to expand support to other languages. I'm sure if they asked 100 developers they would get 100 different answers of what languages should be supported.
Well, just when I was getting used to the idiosyncrasies of the Python language, I went to look something up on http://code.google.com/appengine/ and found that they have an early preview of Java running on the engine. Here's the blog posting.

If I were one of the 100 developers mentioned above, my first answer would have been Java. I signed up as soon as I saw it, but alas, I'm on a waiting list. Looks like I'll be flirting with Python a little longer while I wait for my true love....

The really cool part of getting Java running in the engine is that should bring the other languages that run on the JVM as well, e.g. Scala, Groovy, JRuby, BeanShell, and, yes, even Jython.

Oh the fun!

Tuesday, March 31, 2009

Google App Engine & Python

I finally took the dive into the Google App Engine last week. It's free to get started (up to 10 applications per Google account) and gets my feet wet for this whole "cloud computing" crapfest. Here are my first impressions of Google App Engine and Python. I won't go into my issues with cloud computing in general and all the hype surrounding it, and how it will magically solve all of our scalability and maintenance issues.

I was surprised at how well done the Google App Engine is, and how quickly I could get started. Downloading and installing the local development environment was quick and painless, and walking through the tutorial, I had a very basic "guest book" application written and deployed out in the vast Google cloud for the world to see. The local development server was up and running within minutes of downloading and installing, and making changes to the Python scripts didn't require any redeployment or restarts. Uploading to the Google servers was a matter of running a single script and entering your user id and password. There is even an admin console where you can see stats on your page visits, bandwidth used, performance, etc.

I like that the Google users and authentication is pretty much built in, as well as the simple "webapp" MVC framework, and that you can use any pure Python library or framework you want to use (as long as there aren't any extensions written in C). The data access layer and GQL query language is interesting -- one big free-form data store where you aren't dealing with individual tables so much as just defining your entities in your code's data structures, and reading and writing from them as if they are tables.

For now, the only supported language is Python, which I have never dealt with. That really wasn't much of a hurdle since the syntax is pretty straight forward and easy to learn. I wouldn't mind seeing other languages supported in GAE, though not sure it really matters or if it is worth Google's time, money, and effort to expand support to other languages. I'm sure if they asked 100 developers they would get 100 different answers of what languages should be supported.

I'm a little more ambivalent toward Python. I didn't dislike it, but it just didn't grab me by the balls and make me exclaim it's superiority either. I can say I'm not a fan of the whole "indentation exception" crap. As a guy with more of a C and Java background, I like my curly brackets instead of relying on indentation levels, which remind me too much of COBOL, yuck!

Anyway, here's my trivial little application. It's all "tutorial-ware", straight out of the book with a few CSS enhancements and a simple "about" page. It's not useful, but not bad considering how little time it took to write.

Next step.... write something useful. I definitely want to get into this more and add it to my development toolbox.

So Tempting....

Eleven turkeys recently found themselves really lucky they weren't in season....

Tuesday, March 03, 2009

An Overzealous SEAM Validation

I am using the Jboss SEAM framework for the project I am currently working on. The first thing that really bit me was a validation on single character fields that seems a bit "too stringent". I'm sure I'm not the first to run into this. In fact it may be fixed by now in a newer version of SEAM, but figured it's worth a post anyways.

When you use Jboss Developer Studio (JBDS) to reverse engineer your database (I imagine the seam-gen tools do the same since JBDS uses them), the getter method on the EJB looks something like this...

@Column(name = "DEFAULT_REMAP_IND", length = 1)
@Length(max = 1)
public Character getDefaultRemapInd() {
return this.defaultRemapInd;
}
Looks fine, looks reasonable. Single character fields are often used for flags or indicators, as this one above is -- it's a simple Y/N field. So in my XHTML I use a radio button control instead of a free form text field.

<h:selectOneRadio id="defaultRemapInd" value="#{ocamCustTypeDfltHome.instance.defaultRemapInd}" required="true">
<f:selectItem itemValue="Y" itemLabel="Yes" />
<f:selectItem itemValue="N" itemLabel="No" />
<a:support event="onblur" reRender="defaultRemapIndDecoration"/>
</h:selectOneRadio>

The SEAM framework will use that @Length annotation to perform some field validations for you automagically, which is pretty cool as it can be a real time-saver. But the funny thing is that when this "max length of 1" validation fires, you get the lovely message shown in this partial screen shot ....

Not sure how to get a single character with a length greater than 0 but less than 1, but I do know that the easiest thing to do in this case is remove the @Length annotation for that field. I had to do that for a few different tables. Luckily they were all flags that could be replaced with radio buttons, but in the case where you had to allow free input, you might have to get more creative (you can always put a max length on the input text field).

For reference, I am using Jboss 4.2.2, SEAM 1.2GA, Jboss's EJB3 implementation (which is Hibernate under the hood), XHTML and Facelets for the views. Like I said, this might be fixed in a later release of SEAM.

Tuesday, February 17, 2009

A Lesson In Tracking

I took my daughters for a walk in the woods behind our house Sunday. In the patches of snow and mud, I showed them various animal tracks and we worked on identifying deer, foxes, raccoons, etc. I showed them "deer beans", which they had a lot of fun finding and pointing out. We even kicked up 3 deer as we came around the creek bend.

When we turned to come back, I explained that we should be able to find the tracks we made on the way in, and follow them to get back the same way we came in. I told them this was called 'tracking'. To this, Raina responded with Sid the Sloth's line from the "Ice Age" movie -- "I see a tree, I eat a leaf, that's my tracking."

I love the way kids will pick up what you are telling them, and make associations to stuff they already know. I also love that they show an interest in the outdoors, at least for now. They will probably "turn into girls" at some point, and not want to hunt, fish, camp, etc., so I am enjoying it while I can.

Tuesday, January 20, 2009

My RAZR Woes

My Motorola RAZR v3m phone I have had for a year and half suddenly started acting strange last week. I noticed every time I went to use it, it was turned off, but the battery had a full charge. Then I started paying more attention, and noticed that it would suddenly lose all signal and the screen would go all white for split second and come back, but then the keypad seemed to be frozen -- I couldn't get it to do anything. From there, it would either turn itself off or "reboot" itself (went back to main screen and was OK for a while.

Also, while trying to save pictures in anticipation of the phone either being replaced or flashed, the phone would completely lock up when I inserted the micro-SD card. I had been using this same micro-SD card for almost a year with no issue. Another thing I noticed was now all my contacts show a group of a single, solid "block" character instead of "family", "work", etc.

The phone has not been wet and has not been dropped or otherwise abused. The battery is holding it's charge just fine. The strangest part is that we haved the same model phones at work for our on-call phones. My group's on-call phone started having the same symptoms around the same time mine did. And now I am hearing of at least one other group here having the same issues with their RAZR. From that, I concluded this has to be a more widespread problem, but the lady at the Verizon store refused to even look into it. The phone is out of warranty, so wouldn't do any troubleshooting -- just the offer to buy a new one or wait a month until my contract is eligible to upgrade.

If I were more paranoid and prone to believing conspiracy theories, I might think Motorola put in some sort of "upgrade timer" to break right around the time people are eligible to upgrade their phones. It's probably more likely that there is a Zune-type "leap second" bug in the firmware.

Model: v3m
s/w: NEWC_01.09.02
Date code: 1407