piątek, czerwca 27, 2008

Glassfish + Oracle... JDBC

czwartek, czerwca 26, 2008

SQL Module in details

It is quite OK to put user and pass in connection string. For SQL Module the connection string should be exactly the same as in Servers tab. Before generating WSDL you should call SQL probably with some given parameter (that is replace ? or :1 with some real values). When you see that query works do the right job.



For my example I have created nasty SQL function returning clob with XML inside.



As you can see the result from WebService doesn't look like real business function.
Let's try to fix it. First, create XSD schema for the output coming from DB.



Looking at the WebService WSDL we can see address for SQL-Engine handling our DB function.



To fix beauty (or the lack of) of our WebService BPEL Module will be needed.



From the left there is Partner Link from more business friendly WSDL (that we created on the side), some magic inside, and Partner Link for SQL-Engine WSDL.

First obvious action - pass input of left Partner Link to SQL-Engine and Invoke it.



That was easy, but what's up with mangled XML string? We need to get some real XML nodes from it. OK, create variable of type covered by schema generated from db output.



Do unmarshall on XML string (output of operation might require manual edition of BPEL's source: from and to parameters - if drag-and-drop doesn't work; probably NetBeans sees foreign namespace 'http://sys.one.pl/db1' of XSD schema and refuses to use it).



Now we have XML tree and can take some data from it and put into 'beatifull' WS result.



Let's drop in BPEL module into CompositeApp and make connections. Here it is:



CompositeApp with 2 WebServices: one beautifull and one ugly.

We can see business accepted output in test of 2nd WS.





To sum up:
  • SQL module for wrapping SQL command

  • EnterpriseApp for deploying JDBC connections

  • WebApp for nothing (EnterpriseApp cannot be empty and needs to have WebApp at least)

  • BPEL module for transforming ugly WS (SQL-Engine based) into beautifull WS

  • CompositeApp for hosting and linking modules

Oracle Connection for Glassfish

It can be easilly created from NetBeans. All you need to do is new EnterpriseApplication (with some content, for example with WebApp as the wizard suggests). Then is Server Resources you can add JDBC Connection Pool and JDBC Resource. Deploy ear and you will have Oracle Connection on your Glassfish.

NetBeans SOA with Oracle

NetBeans is the default IDE for OpenESB platform and uses SOA Pack common with Sun JCAPS. JCAPS comes with DataDirect OEM JDBC driver for Oracle and somehow NetBeans doesn't fully support Oracle JDBC driver - it can't generate WSDL file for SQL Module operations. I have fixed this limitation and you can download SQL Module supporting Oracle JDBC driver from NetBeans Bugzilla.


Here you can see bug report. While generating WSDL for database operation SQL Module tries to get some description of parameters used in prepared statement. However Oracle JDBC driver doesn't have this information until after the statement is executed. As a result in NetBeans messages.log you can see:

java.sql.SQLException: Handle does not exist: getMetaDataorg.netbeans.modules.sql.project.dbmodel.DBMetaData.getPrepStmtResultSetColumns

From NetBeans Bugzilla you can get patch. NetBeans SOA Pack sources are available at hg.netbeans.org (there is mercurial package for Unices and TortoiseHg for Windows). You can do patching yourself or download fixed jar file. But...

if you download new OpenESB build every two weeks the jar file will probably have wrong version number of module. Unpack jar and fix it inside MANIFEST file.

Here is some Oracle function created few posts ago.

Let's try to generate WSDL for it.

OK, it probably worked. Now create new CompositeApplication, drop inside SQL Module, call 'Clean and Build'...

... add SOAP port, deploy CompositeApp...

and run Test Cases...

(remeber to set port for SOAP endpoint)

You should have now WebService for you DB operation.

Proste serializowanie obiektu do XML-a

private static StringBuffer describeNodeMark(StringBuffer sb, Object o, String name, int level, boolean end) {
for (int i = 0; i < level-1; i++)
sb.append("\t");
sb.append(end ? "</" : "<").append( name ).append(">\r\n");
return sb;
}

private static StringBuffer describeNode(StringBuffer sb, Object o, String name, int level) throws Exception {
if (o==null) {
for (int i = 0; i < level; i++)
sb.append("\t");
sb.append("<").append( name ).append("/>\r\n");
return sb;
}
else if (o.getClass().getName().startsWith("[B")) {
sb.append("<byte[]>").append( new String( (byte[]) o) ).append("</byte[]>");
return sb;
}
else if (o.getClass().getName().startsWith("[C")) {
char[] cs = (char[])o;
for (int i=0; i<cs.length; i++) {
Character c = (Character)cs[i];
sb.append(c);
//toXmlString(sb, c, level);
}
return sb;
}
else {
for (int i = 0; i < level; i++)
sb.append("\t");
sb.append("<").append(name).append(">");
sb.append(o);
sb.append("</").append(name).append(">\r\n");
return sb;
}
}

@SuppressWarnings("unchecked")
public final static StringBuffer toXmlString(StringBuffer sb, Object o, int level) throws Exception {
if (sb==null)
sb = new StringBuffer();
level++;
if (o!=null) {
String nm = o.getClass().getName();
if (nm.contains("org.apache.axis") || nm.endsWith(";")) // skip axis TypeDef and list terminator
return sb;
}
File f = new File( o.getClass().getName().replaceAll("\\.", "/") );

if (o==null) {
return describeNode(sb, o, f.getName(), level);
}
if ((o.getClass().getName().startsWith("java.lang") || // basic Java types
o.getClass().getName().startsWith("java.math") ||
o.getClass().getName().startsWith("[B") ||
o.getClass().getName().startsWith("[C")) &&
( !o.getClass().getName().startsWith("java.lang.String")) &&
!o.getClass().getName().startsWith("java.lang.Character")
)
{
return describeNode(sb, o, f.getName(), level);
}

/////////////////////

describeNodeMark(sb, o, f.getName(), level, false);

for (Field fld : o.getClass().getDeclaredFields()) {
fld.setAccessible(true);
String name = fld.getName();
Object obj = fld.get(o);

if (!name.startsWith("__")) { // skip axis fields
if (obj==null) {
describeNode(sb, obj, name, level);
}
else {
String cname = obj.getClass().getName();

if (cname.startsWith("[L")) {
Object[] objs = (Object[]) obj;
for (Object oo : objs) {
if (oo!=null)
sb.append( toXmlString(null, oo, level) );
}
}

if (cname.startsWith("java.lang.Class"))
return sb;

if (cname.startsWith("java.lang") || cname.startsWith("java.math")) {
describeNode(sb, obj, name, level);
}
else {
if (cname.startsWith("java.util.LinkedList$Entry")) {
List list = (List)o;
for (int i = 0; i < list.size(); i++)
sb.append( toXmlString(null, list.get(i), level-1 ) );
}
else if (cname.startsWith("java.util.TreeMap$Entry")){
Map map = (TreeMap) o;
for (Object k : map.keySet()) {
sb.append( toXmlString(null, k, level-1 ) );
}
}
else {
sb.append( toXmlString(null, obj, level) );
}
}
}
}
}

for (int i = 0; i < level-1; i++)
sb.append("\t");
sb.append("</").append( f.getName() ).append(">\r\n");
return sb;
}

Yet Another Logging Utility


package com.company.util.debug;

import java.io.File;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

/**
* Modul logowania
*
*/
public class Debug {

public final static int TRACE_DEPTH = 25;
public final static boolean LOG_INFO = true;
public final static boolean LOG_ERR = true;
public final static String THIS_PACKAGE = "com.company";

public final static int TRACE_DEPTH = 25;
public final static boolean LOG_INFO = true;
public final static boolean LOG_ERR = true;

@SuppressWarnings("unchecked")
public final static void println(String txt, Object thiz) {
if (LOG_INFO) {
Exception e = new Exception();
StringBuffer msg = new StringBuffer();
msg.append("[").append(new Date()).append("] [Caller: ");
if (thiz instanceof Class)
msg.append( ((Class)thiz).getName() ).append("@static=");
else
msg.append( thiz.getClass().getName() ).append("@");

msg.append( thiz.hashCode() ).append("]");
msg.append(" th").append(Thread.currentThread().getId());
String thName = Thread.currentThread().getName();
if (thName!=null)
msg.append("=").append(thName);
msg.append("\r\n\tat ").append(e.getStackTrace()[1]);
msg.append("\r\n\tINFO: ").append(txt).append("\r\n");
System.out.println(msg);
}
}

public final static StringBuffer describeException(StringBuffer msg, Throwable err) {
msg.append("\r\n\tERR: ").append(err.toString()).append("\r\n");
StackTraceElement[] st = err.getStackTrace();
int n = (st!=null) ? Math.min(st.length, TRACE_DEPTH) : 0;
String prev = "";
for (int i=0; i < sti =" st[i]+"> ").append(st[i]);
else
msg.append("\r\n\t").append(st[i]);
prev = sti;
}
if (n>0)
msg.append("\r\n");
return msg;
}

@SuppressWarnings("unchecked")
public final static void printlnErr(String txt, Throwable ex, Object thiz) {
if (LOG_ERR) {
Exception e = new Exception();
StringBuffer msg = new StringBuffer();
msg.append("[").append(new Date()).append("] [Caller: ");
if (thiz instanceof Class)
msg.append( ((Class)thiz).getName() ).append("@static=");
else
msg.append( thiz.getClass().getName() ).append("@");

msg.append( thiz.hashCode() ).append("]");
msg.append("\r\n\tat ").append(e.getStackTrace()[1]);
msg.append("\r\n\tERR: ").append(txt);
Throwable t = ex;
while (t!=null) {
describeException(msg, t);
t = t.getCause();
}
System.out.println(msg);
}
}

@SuppressWarnings("unchecked")
public final static String describeErr(String txt, Throwable ex, Object thiz) {
if (LOG_ERR) {
Exception e = new Exception();
StringBuffer msg = new StringBuffer();
msg.append("[").append(new Date()).append("] [Caller: ");
if (thiz instanceof Class)
msg.append( ((Class)thiz).getName() ).append("@static=");
else
msg.append( thiz.getClass().getName() ).append("@");

msg.append( thiz.hashCode() ).append("]");
msg.append("\r\n\tat ").append(e.getStackTrace()[1]);
msg.append("\r\n\tERR: ").append(txt);
Throwable t = ex;
while (t!=null) {
describeException(msg, t);
t = t.getCause();
}
return msg.toString();
}
return ex.getLocalizedMessage();
}
}

select-cursor + xml w Oracle'u















Proszę zwrócić uwagę, że poprzez 'select cursor(), cursor()..' można zwrócić kilka ResultSet-ów.

poniedziałek, czerwca 23, 2008

Ciekawostka

BEA AquaLogic Service Bus wykorzystuje komponenty z Sun Java Application Server.

niedziela, czerwca 22, 2008

Solaris 11 is coming

W pewnym momencie wszystkie buildy 8x Nevady (Solaris Express) przestały domyślnie instalować się na ZFS-ie, dodatkowo straciły instalator, który jest
w OpenSolarisie. W najnowszym snapshocie nv91 można wybrać na czym chcemy mieć rootfs.





Można wysnuć z tego wnioski, że Solaris 11 się stabilizuje i za jakiś czas będziemy mieli wersję produkcyjną.
Tymczasem narzędzia do zarządzania pakietami są chyba w wersji z OpenSolarisa - nie daje
się zainstalować Blastwave'a.

czwartek, czerwca 19, 2008

Jak zrobić żeby beowy driver oracle-owy (DataDirect-a) działał z czymkolwiek

Są do tego 3 jary: wloracle.jar, wlbase.jar, wlutil.jar. Rozpakowujemy tego drugiego, wchodzimy do wlbase\weblogic\jdbc\base\connectjdbc.properties i tam pozostawiamy
applicationKey=class\:java.lang.Object

weblogic.jdbc.oracle.OracleDriver wloracle_drv = new OracleDriver();
Connection conn = null;
conn = DriverManager.getConnection("jdbc:bea:oracle://127.0.0.1:1521;SID=ORA", "user", "pass");

sobota, czerwca 07, 2008

Pierwsze benchmarki Pumy

http://www.notebookjournal.de/praxis/81/5 - Sam procesor jest wolniejszy od Core 2 Duo, ale w testach grafiki Puma bije na głowę C2D T8100 z GMA X3100/GF 8400.

niedziela, czerwca 01, 2008

IBM Lotus Symphony

OpenOffice osadzony w Eclipsie, z podziałem na pluginy.



Produkt ma w standardzie polski interfejs.







Dzięki temu, że IBM Lotus Symphony jest pochodną Eclipse'a (RCP) może być wzbogacany o nowe funkcjonalności za pomocą wtyczek.



Rendering czionek jest nieco dziwny, odbiega od tego w OOo. Zaletą aplikacji są zakładki,
w jednym oknie aplikacji można wygodnie edytować tekst, pracować z arkuszem kalkulacyjnym lub prezentacją i przeglądać strony WWW.