BibleGateway.com Verse Of The Day
Wednesday, May 23, 2012
OSB Table Poller Issue Setting Status
Monday, November 01, 2010
Oracle Service Bus - Getting XML Out of Table Column
Let's say you have a table you need to query from the OSB. The result set you get back from the JCA DB adapters gets turned into XML for you. If one of the columns is a LOB containing XML, then it gets escaped using CDATA. Anything in CDATA is basically ignored by XML, XSL, XPath, etc.
It is a 2 step process to extract that value and make it usable XML:
- Use the fn:string() function to turn the value into a string. In this case, it strips off the CDATA wrapper and gives you a string that looks like XML.
- Use the fn-bea:inlinedXML() function to parse that string into XML.
You can use an ASSIGNMENT task to jam that XML into a variable, and then run any XSL, XPath, etc on it. You can also use INSERT or REPLACE tasks to embed it back into your original XML.
Enabling Oracle Trace For WLS Connection Pools
Wednesday, October 13, 2010
A Few More SEAM Nuggets
Showing Number of Matched Records in List View
When you generate a SEAM application from a database, you end up with a set of components for each table - for example a list view, record view, and record edit. When you are displaying a list of records, it is common to want to show how many records match the current query (or the total records if you went to list view without a search criteria).
You can easily get this function by accessing the "resultCount" attribute on your view, like this:
<h:outputtext value="#{yourTableList.resultCount} rows found." rendered="#{not empty yourTableList.searchResults}">
Change Default Sort Order, But Still Allow Click-To-Sort
One requirement we ran into on one of my SEAM projects was to change the default sort order for some of the list views. However, the views that the SEAM gen tool creates allows the user to click on the column headers to change sorting as well. To achieve a default sort order on initial load, and still allow clickable headers, override the getOrder() method in your
@Override
public String getOrder() {
String order = super.getOrder();
if ("".equals(order) || order == null)
{
order = "col1 asc,col2 desc";//your default sort columns here
}
return order;
}
Wednesday, August 18, 2010
Oracle Sorting of NULL Values
SELECT * FROM sometable ORDER BY col1 ASC NULLS FIRST
ORA-24777 When Using XA Driver
We are calling some PL/SQL stored procedures through JCA adapters on the Oracle Service Bus (OSB). Our connection pool on WebLogic is setup using the XA JDBC driver.
Everything was great until we called a stored procedure that queries across a database link. Then we got the dreaded ORA-24777 - use of non-migratable database link not allowed.
Turns out there are at least 3 ways to rectify this issue....
- Set up Oracle to use multi-threaded server, a.k.a. shared server. There are ups and downs, and depending on who you talk to, mostly downs, especially concerning performance. We haven't tried this, but it does come up often as a fix.
- Create a "shared" database link. The syntax is a little different than a "normal" link. This is what we did, and it worked fine.
- Third option, though not right for everyone, would be to use the non-XA driver.
CREATE SHARED DATABASE LINK
CONNECT TOIDENTIFIED BY
AUTHENTICATED BYIDENTIFIED BY
USING;
Wednesday, October 21, 2009
Running Multiple Versions of Oracle JDBC Driver on same JBoss server
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.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.
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!
Links:
- My post to Jboss forums asking the question: http://www.jboss.org/index.html?module=bb&op=viewtopic&t=162701
- The wiki article that answers the question http://www.jboss.org/community/wiki/IWantToDeployMyOwnJdbcDriverInAScopedClassloader
- Which Oracle JDBC Drivers support which versions of Oracle RDBMS? http://www.oracle.com/technology/tech/java/sqlj_jdbc/htdocs/jdbc_faq.html#02_02
- Jaikiran Pai's blog - gotta give props to the guy who answered our question: http://jaitechwriteups.blogspot.com/
Tuesday, August 18, 2009
Multiple Column Subqueries (Oracle)
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
-Doracle.jdbc.V8Compatible=true
-Djava.awt.headless=true
<web:context-filter pattern="/csv"/>
UnmappedAccount unMapAcct = (UnmappedAccount)Component.getInstance("unmappedAcct");
import org.jboss.seam.annotations.Name;...@Name("unmappedAcct")public class UnmappedAccount { ... }
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.
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).@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "...")
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 ;-)
Thursday, May 28, 2009
Emergency Startup CD for 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....
Tuesday, March 03, 2009
An Overzealous SEAM Validation
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...
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.
@Column(name = "DEFAULT_REMAP_IND", length = 1)
@Length(max = 1)
public Character getDefaultRemapInd() {
return this.defaultRemapInd;
}
<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>
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.
Monday, August 18, 2008
Simple JSP To List Java JVM Environment
I'm sure every Java developer has written similar code at some point, so I won't claim it's original, unique, or ingenious. But if you find it useful, go ahead and use it instead of writing another.
Wednesday, July 16, 2008
Making Your JVM Trust Those SSL Certificates
So the second step for me was to import them so my JVM(s) would recognize the certificate as "trusted".
To get your JVM to trust the certificate, you import it into your keystore using the keytool executable (found in your JDK bin directory):
[jboss@j2apptest01 bin]$ ./keytool -import -alias SomeWebserviceName -file ~/SomeCertificateFileName.CERIf the keystore does not exist yet, the tool will prompt you to enter a keystore password. Remember that password, as you will need to use it to import new certificates or export or view current ones.
It will then display all the keys and other info about the certificate and ask you to confirm that you really want to import. You will want to verify the keys match up to what you think you are importing, of course. Then type "yes" and it should tell you the certificate was added.
After that, our calls to the web service started to ork again, like magic.
Tuesday, July 15, 2008
Saving SSL Certificates From A Website
Thursday, May 01, 2008
Some Old-School JAM and JPL Tips
I was cleaning out the barn and found a CD of some old code and documents I had written at an old job, kind of a "portfolio" CD if you will. We used JAM to build Motif screens.
JAM let you visually build your screens, and had it's own procedural programming language, JPL (JAM Programming Language). JAM came with the necessary C code to handle launching of the screens and handling events. You could write your own custom C code to be called from the screens, or write your code in the JPL file for the screen, or a combination of both. One nice thing is you could write SQL code right inline with the rest of your JPL (just prepend the keyword "sql") and everything was taken care of, even down to binding the result set to variables.
It's not exactly cutting edge technology now, but I know it is still in use by at least a few companies. This is not a tutorial for non-JAMsters, but rather a collection of troubleshooting tips I had taken note of. Maybe this could be of use to someone just inheriting legacy apps, or who knows when I might run into JAM again. Yuck!
For reference, these tips are mostly for JAM 5 and 7, but they may be applicable for other versions as well.
SELECT 1 FROM table... | This is often done to see if a record meeting your criteria (where clause) exists in the table. Doing this from a JAM screen (at least in Jam 5) will produce a @dmrowcount of 0 (zero), even if there are records in the table meeting the criteria. There are two alternatives within JAM to get the same information: 1. SELECT COUNT(*) temp_var FROM table... 2. SELECT column temp_var FROM table... |
SELECT column FROM table | This one can be tricky. If there is no JAM variable with the same name as the the selected columns, then JAM will create those variables and put the results of the query in those variables. If the variables do exist already, JAM will overwrite the values with the results of the query, even when the query returns nothing (it will essentially clear the variables). |
Mixed Case Variables | Mixed case variables can be a real problem with JAM, and the error messages are not intuitive enough to let you know what the real problem is. Keep tihs in mind when you can’t figure out some quirky behaviour, and all the other logic and syntax is proper. |
Changes in screen file don’t seem to take effect | Check the local directory you are running from. JAM will use screen, JPL, and dictionary files fro mthe current directory before checking in the SMPATH, regardless of what the SMPATH is set to. Check the data dictionary. The screen fields and variables can be stored in here, as well as in the screen definition file. Data dictionary tends to overwrite local (screen) vars. |
Some Useful environment Vars | Most of the relevant environment variables start with SM, e.g. SMVARS, SMPATH |
- Also worth noting is that while it might make sense that they would just make use of the underlying Motif widgets, in some cases that was not the case. Simple text boxes for instance would not work with bi-directional Hebrew whereas pure Motif screens did. We had to have JYACC / Prolifics issue a patch for us before we could release to an Israeli customer.
- There were also issues with some characters in the Turkish (ISO-8859-9) character set. Their database layer simply could handle it for some reason. Wouldn't bring back results, wouldn't update, and yet We ended up having to write our own generic database access layer using Pro-C, and replacing all the JPL "sql" statements with "call" statements into our library.
Thursday, April 10, 2008
A Servlet Filter For Easier Debugging
This isn't meant to be a tutorial on Servlet filters, I am assuming you either know (or know how to figure out) what filters are, and how to tie them into your application in the web.xml descriptor.
I "printed" the source into a PDF to keep the formatting in tact. Here is the link, or if your PDF plugin is working, it should appear in an iframe below....
Monday, March 17, 2008
Oracle on Windows Authentication Woes (And Solutions)
Except that several times already, when trying to run imports or simply connecting via SQL-Plus, I get the following crap:
C:\oraclexe\app\oracle\product\10.2.0\server\BIN>sqlplus XXXXXX/XXXXXThe first time it happened, I simply restarted the OracelServiceXE and OracleXETNSListener services. Then it happened again today, and restarting services had no effect. And I am NOT rebooting my whole machine just to get Oracle to work.
SQL*Plus: Release 10.2.0.1.0 - Production on Mon Mar 17 08:50:29 2008
Copyright (c) 1982, 2005, Oracle. All rights reserved.
ERROR:
ORA-12638: Credential retrieval failed
But thanks to someone named "babu george" on this forum, I fixed the issue quite simply by getting rid of NTS authentication.
In your sqlnet.ora file, simply comment out the (NTS) line and create a new line with (NONE) in place of (NTS).
#SQLNET.AUTHENTICATION_SERVICES = (NTS)Alas, don't get me started on how much I love Windows.
SQLNET.AUTHENTICATION_SERVICES = (NONE)
Friday, March 14, 2008
Trashy Yet Effective Oracle Trick
I need to post this so I can remember it next time I screw up...
I was running an Oracle import (imp) on my local Oracle 10g XE instance today, and realized I did it incorrectly and imported everything into the SYSTEM schema. Oh crap, I can't just wipe everything out, it's my SYSTEM schema! I need surgical precision to only remove the crap and leave all the Oracle stuff unscathed.
Then, like a tornado in a trailerpark, it hit me. An idea that walks the fine line between genius and insanity. All the new table names started with a common prefix, which for sake of discussion I will call "BLAH_". So in Squirrel I run the following query:
select 'drop table system.' || table_name || ';' from all_tables where owner = 'SYSTEM' and table_name like 'BLAH_%'
Then cut and paste the results back into the Squirrel query runner and run the results as a script.
I'm sure there's an "official" way to accomplish the same thing, but screw that, this was extremely quick and kind of fun.
Trashy yet effective.
Thursday, February 07, 2008
Reading And Writing Text Files in Ruby
I ended up writing some Ruby scripts to run through a file of transaction responses, and sort out the various error types into separate files, and produce a summary report of the error counts in each category. Now the only manual part was cutting and pasting the summary into an email, and attaching the various sorted files.
I was pleasantly surprised at how easy it was to read and write text files in Ruby. Let's say you just want to read a text file, line by line, and spit it back out, a la "cat"...
File.new(filename, "r").each { |line| puts line }Wow, that was easy, eh? Let's try reading that file into an array for use later...
results = []Let's say you want to capitalize everything in the file, and spit it out to a new file...
File.new(filename, "r").each { |line| results << line }
out_file = File.new("upper_case.txt","w")
results.each do |line|
out_file.puts line.upcase
end
That was easy. It's probably obvious, but the first argument passed to the File constructor is the filename, and second is the read/write flag.
For comparison' sake, let's read a file in Java and spit it out line for line...
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
...
BufferedReader is = new BufferedReader(new FileReader(fileName));
String line = "";
try {
while (line != null)
{
line = is.readLine();
System.out.println(line);
}
catch (Exception e) { /* do nothing for now */ }
finally
{
try {is.close();}catch(Exception f) { }
}
Definitely not "hard", but it is a bit more code. Writing a file is very similar, except of course you use FileWriter and BufferedWriter instead of FileReader and BufferedReader, and write to the file instead of reading from it.
I'm not really trying to prove anything here -- Ruby isn't better than Java, Java isn't too hard or too verbose, etc. I like Java. I like Ruby. Against my better judgment, I even like Oracle, but that's another topic. I just found that working with files was easier than I expected, even for a Ruby beginner like myself.
Thursday, September 06, 2007
PDFCreator
But if you're running apps on Windows that don't have this feature, you can download and install PDF Creator. It installs itself as a "printer" on your PC. When you choose to print from any application, choose this printer instead of your normal printer.