Showing posts with label Java. Show all posts
Showing posts with label Java. Show all posts

2007/11/19

Java Shell Collection

JBash v0.88

http://www.quignon.de/index.php?goto=downloads&cat=all



JBash ist eine linux-like Shell Konsole in pure Java. Vorteil ist, dass man sowohl auf Windows oder MAC mit Linux gewohnten Bash Kommandos arbeiten kann. Die Jar-Datei beinhaltet sowohl die Konsolanwendung als auch einen Multisession Swing GUI.
Es unterstützt viele bekannte Kommandos: echo, cat, grep, ll, touch, find, wc...

Download - Source

-----
JCmd
jcmd.sourceforge.net

-----
Jsh

non is I want

2007/11/14

Original Code: WinCuiClient MonitorReader


package my.man

import java.io.BufferedReader;
import java.io.IOException;
import java.io.Reader;

/**
* make read no wait and
*
* monitorReader = new MonitorReader(getReader());
* monitorReader.asyncRead(this);
* synchronized (this) {
* wait ();
* }
* monitorReader.getLines();
*
* @author f.yang
*/
public class MonitorReader extends Reader {
/** actual reader */
private BufferedReader reader;
/** history */ // TODO deal with large history that out of memory
private StringBuffer history = new StringBuffer(1000);
/** current lines buffer */
private StringBuffer lines = new StringBuffer(100);
/** asynchronized reading waiter */
private Object waiter = null;
/** continue reading signal */
private Object readSignal = new Object();
/** closed boolean */
private boolean closed = false;
/** this for inner class */
private MonitorReader monitorReader = this;

/**
* reader monitor thread
*/
protected Thread readerMonitorThread = new Thread(new Runnable () {
public void run () {
while(!closed) {
// wait read sinal
try {
synchronized (readSignal) {
readSignal.wait();
}
if (closed) {
break;
}
} catch (InterruptedException ex) {
}
synchronized (monitorReader) {
readAll();
// notify one waiter
synchronized (waiter) {
waiter.notifyAll();
}
waiter = null;
}
}
}
});

/**
* constructor
* @param reader
*/
public MonitorReader(BufferedReader reader) {
this.reader = reader;
this.readerMonitorThread.start();
}

/**
* get read lines
* @return
*/
public StringBuffer getLines () {
synchronized (lines) {
return new StringBuffer(lines);
}
}

/**
* @param waiter
*/
public void asyncRead (Object waiter) {
synchronized (this) {
// TODO add waiter to waiters list for furture notification


if (this.waiter != null) {
throw new RuntimeException ("Re-enter asyncReadLines");
}
this.waiter = waiter;

history.append(lines);
lines.delete(0, lines.length());

// wake up worker thread read line
synchronized (readSignal) {
readSignal.notify();
}
}
}

/**
* provides a method to determine wether the monitor is under reading
* @return is read waiting
*/
public boolean isReading () {
synchronized (this) {
return this.waiter != null;
}
}

//-------------------------------------------------
// compatible public methods

/**
* for compatible with BufferedReader
* @return readLine
*/
public String readLine () throws IOException {
synchronized (history) {
synchronized (lines) {
history.append(lines);
lines.delete(0, lines.length());
String str = reader.readLine();
lines.append(str);
return str;
}
}
}


/**
* for read abstract class compatible
* @override
*/
public synchronized int read(char[] cbuf, int off, int len) throws IOException {
archiveToHistory();
int readLen = reader.read(cbuf, off, len);
lines.append(cbuf, off, readLen);
return readLen;
}

/**
* for read abstract class compatible
* @Override
*/
public synchronized void close() throws IOException {
if (!closed) {
closed = true;
synchronized (readSignal) {
readSignal.notify();
}
}
}

//-------------------------------------------------
// private

/**
* read all ready information into lines buffer
* @return
*/
private synchronized void readAll () {
try {
archiveToHistory();
// read all lines that generated in the buffer once
char[] buf = new char[100];
while (reader.ready()) {
int readLen = reader.read(buf, 0, buf.length);
lines.append(buf, 0, readLen);
}
} catch (IOException e) {
throw new RuntimeException (e);
}
}
/**
* move lines to history with protecting history and lines
*/
private synchronized void archiveToHistory () {
history.append(lines);
lines.delete(0, lines.length());
}
}



package my.man;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Map;

/**
* windows command line auto-answer utility
* Asynchronized read/write console
* but have some problem on process synchronizing and lock
* should be debug furture.
* Demo:
public static void main(String[] args) {
// TODO code application logic here
//new MainJFrame().setVisible(true);
Map param = new HashMap ();
WinCuiClient cuiClient = new WinCuiClient(param);
cuiClient.execute("dir");
cuiClient.exit();
}
* @author f.yang
*/
public class WinCuiClient extends CuiClientImpl {
/** proc */
protected Process proc;

public static final String COMMAND_LINE_KEY = "commandLine";

public WinCuiClient(Map param) {
init(param);
}

/**
* init shell process
* @param param
* @throws java.io.IOException
*/
public void initProc(Map param) throws IOException {
if (param.containsKey(COMMAND_LINE_KEY)) {
proc = Runtime.getRuntime().exec(
(String) param.get(COMMAND_LINE_KEY));
} else {
proc = Runtime.getRuntime().exec("cmd.exe /k");
}
}

/**
* execute command with shell process
* @param command
*/
public void execute(String command) {
try {
// TODO add check and rule
System.out.print("[man]" + "executing :" + command);
stdinWriter.println(command);
stdinWriter.flush();
stdoutReader.asyncRead(this);
stderrReader.asyncRead(this);
Thread.sleep(5000L);
synchronized (this) {
wait();
}
System.out.println("[out]" + stdoutReader.getLines().toString());
System.out.println("[err]" + stderrReader.getLines().toString());
System.out.println("[man]" + "executing finished");
} catch (InterruptedException ex) {
new RuntimeException(ex);
//Logger.getLogger(WinCuiClient.class.getName()).log(Level.SEVERE, null, ex);
}
}

public void exit() {
try {
execute("exit");
stdinWriter.close();
stdoutReader.close();
stderrReader.close();
proc.destroy();
} catch (IOException e) {
new RuntimeException(e);
}
}

/**
* execute multiple commands with shell process
* @param commands
*/
public void executeBatch(String[] commands) {
// TODO add check and rule
for (int i = 0; i < commands.length; i++) {
execute(commands[i]);
}
}

/**
* @Override
* @param param
* @return
*/
public void init(Map param) {
super.init(param);
try {
initProc(param);
stdinWriter = new PrintWriter(proc.getOutputStream());
stdoutReader = new MonitorReader(new BufferedReader(
new InputStreamReader(proc.getInputStream())));
stderrReader = new MonitorReader(new BufferedReader(
new InputStreamReader(proc.getErrorStream())));
} catch (IOException ex) {
throw new RuntimeException(ex);
}
}
}



import java.io.BufferedReader;
import java.io.PrintWriter;
import java.io.Reader;
import java.util.Map;

/**
* implementation
* @author funnyok
*/
public abstract class CuiClientImpl implements CuiClient {
protected PrintWriter stdinWriter;
protected MonitorReader stdoutReader;
protected MonitorReader stderrReader;
protected Map param;

public void init (Map param) {
this.param = param;
}

/**
* @Override
* @return stdoutReader
*/
public MonitorReader getStdoutReader() {
return stdoutReader;
}

/**
* @Override
* @return stderrReader
*/
public MonitorReader getStderrReader() {
return stderrReader;
}

/**
* @Override
* @return stdinWriter
*/
public PrintWriter getStdinWriter() {
return stdinWriter;
}

}

Original Code: CQL - Smalltalk/Ruby/SQL liked collection query and operation library

Do class can perform smalltalk/ruby liked collection based foreach operation. It's especially useful on complicated collection sql liked select operation.

* note the operation is not well tuned. you should implement with java native methods when performance is important for your application.

Example
The following code demostrate how to select elements in SQL-like style.
The code is pretty long than Small/Ruby/SQL, most of the are type defination and can be auto-generated by moden programming tools like Eclipse, Idea and NetBeans.

/** self test main function, usage demo */
public static void main (String[] argv) {
try {
// declare a array
Integer[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

new Do<Integer>(arr)
// select * from arr where arr.value > 3
.select(new Do.BoolFunc<Integer>() {
public boolean exec(int index, Object key, Integer value) {
return value >= 2;
}
})
// and arr.value < 3
.select(new Do.BoolFunc<Integer>() {
public boolean exec(int index, Object key, Integer value) {
return value <= 8;
}
})
// dump the result
.exec(new Do.VoidFunc<Integer>() {
public void exec(int index, Object key, Integer value) {
System.out.println("[" + index + "]=" + value + ", key ['" + key + "']=" + value);
}
});
} catch (Exception e) {
e.printStackTrace();
}
}

The result is shown as following.

[0]=2, key ['1']=2
[1]=3, key ['2']=3
[2]=4, key ['3']=4
[3]=5, key ['4']=5
[4]=6, key ['5']=6
[5]=7, key ['6']=7
[6]=8, key ['7']=8


package my.lang;

import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.HashMap;
import java.util.Map;

/**
* Do class can perform smalltalk/ruby liked collection based foreach operation.
* It's especially useful on complicated collection sql liked select operation.
* * note the operation is not well tuned.
* you should implement with java native methods
* when performance is important for your application.
* @author fantastechnol
* @param <T> the datatype of the content of your collection
*/
public class Do<T> {
// private data type constants
private final char NONE = 'N';
private final char ARRAY = 'A';
private final char COLLECTION = 'C';
private final char MAP = 'M';

// private constant
private T[] arr;
private Collection<T> coll;
private Map<Object, T> map;
private char type = NONE;

public interface BoolFunc<V> {
boolean exec (int index, Object key, V value);
}

public interface VoidFunc<V> {
void exec (int index, Object key, V value);
}

/** foreach array constructor */
public Do(T[] arr) {
this.arr = arr;
type = ARRAY;
}

/** foreach Collection constructor */
public Do(Collection<T> coll) {
this.coll = coll;
type = COLLECTION;
}

/** foreach Map constructor */
public Do(Map<Object, T> map) {
this.map = map;
type = MAP;
}

/** each */
public void exec (final VoidFunc<T> f) {
select(new BoolFunc<T>() {
public boolean exec(int index, Object key, T value) {
f.exec(index, key, value);
return false;
}
});
}

/**
* select all the BoolFunc returns true
* @param f BoolFunc
* @return ForEach object
*/
public Do<T> select (final BoolFunc<T> f) {
int i = 0;
Object key = null;
T value = null;
Map<Object, T> ret = new HashMap<Object, T>();

switch (type) {
case ARRAY:
for (; i < arr.length; i ++) {
key = Integer.valueOf(i);
value = arr[i];
if (f.exec(i, key, value)) {
ret.put(key, value);
}
}
break;
case COLLECTION:
for (Iterator<T> it = coll.iterator(); it.hasNext(); i ++) {
key = Integer.valueOf(i);
value = it.next();
if (f.exec(i, key, value)) {
ret.put(key, value);
}
}
break;
case MAP:
for (Iterator<Object> it = map.keySet().iterator(); it.hasNext(); i ++) {
key = it.next();
value = map.get(key);
if (f.exec(i, key, value)) {
ret.put(key, value);
}
}
break;
default:
new RuntimeException ("Invalid type: " + type
+ " arr: " + arr
+ " coll: " + coll
+ " map: " + map);
}
return new Do<T>(ret);
}


public Collection<T> getCollection() {
// TODO internal data structure maybe be modified by outside program

Collection<T> ret = null;

switch (type) {
case ARRAY:
ret = Arrays.asList(arr);
break;
case COLLECTION:
ret = coll;
break;
case MAP:
ret = map.values();
break;
default:
new RuntimeException ("Invalid type: " + type
+ " arr: " + arr
+ " coll: " + coll
+ " map: " + map);
}
return ret;
}

public Object[] getArray() {
// TODO internal data structure maybe be modified by outside program
// TODO cannot convert Collect<T>.toArray() type from object to <T>, or new T[]
Object[] ret = null;

switch (type) {
case ARRAY:
ret = arr;
break;
case COLLECTION:
ret = coll.toArray();
break;
case MAP:
ret = map.values().toArray();
break;
default:
new RuntimeException ("Invalid type: " + type
+ " arr: " + arr
+ " coll: " + coll
+ " map: " + map);
}
return ret;
}

public Map<Object, T> getMap() {
// TODO internal data structure maybe be modified by outside program
Map<Object, T> ret = null;

switch (type) {
case ARRAY:
ret = new Do<T>(arr).select(new BoolFunc<T> () {
public boolean exec (int index, Object key, T value) {
return true;
}
}).getMap();
break;
case COLLECTION:
ret = new Do<T>(coll).select(new BoolFunc<T> () {
public boolean exec (int index, Object key, T value) {
return true;
}
}).getMap();
break;
case MAP:
ret = map;
break;
default:
new RuntimeException ("Invalid type: " + type
+ " arr: " + arr
+ " coll: " + coll
+ " map: " + map);
}
return ret;
}
}

2007/11/13

java 7 example writing your own foreach

One of the promises of closures was that if Java 5 had closures instead of foreach, you could have implemented foreach as a method. Let's put that to the test with the Java 7 prototype.

Firstly, the 'control invocation syntax', which is a little subjective, hasn't been implemented in the prototype, so anything I show here is certainly less than foreach could be with closures.

Here's a simple attempt:
public static <T> void foreach(T[] ts,{T=>void} block)
{
for (int a=0;a<ts.length;a++)
block.invoke(ts[a]);
}
I can call this like so:

foreach(new String[]{"hello","world"},{String s=>System.out.println(s);});

I found that I kept repeating one error in testing out this prototype, namely forgetting the ; for a statement in a {something=>void} closure.

Anyway, the above doesn't work with continue, break or return. Those are not bound yet by the closures prototype. No matter, let's roll our own (ignoring return; I don't know of a way to apply the following technique to return).

Not only can we pass a closure to a method, but the method can pass a closure to our closure! No, I've not yet gone mad:

public static <T> void foreach(T[] ts,{T,{=>void},{=>void}=>void} block)

Perhaps the T,{=>void},{=>void} is better abstracted into a ForeachControl class or something. Imagining that it was, the T field would be called 't', the first {=>void} would be called 'brake' (as in break, but avoiding collisions with the keyword), and the second {=>void} would be called 'cont' (as in continue).

For now, I'm quite happy to use the above. I'll just reiterate it:

{T,{=>void},{=>void}=>void} is a function type that takes a T, and two {=>void}s and has no return value. A {=>void} is a function type that takes nothing and returns nothing, analogous to Runnable. Here's some example usage:

String[] input={"fish","print","fingers","don't print"};

foreach(input,{String s,{=>void} cont,{=>void} brake=>
if (s.startsWith("fish"))
cont.invoke();

System.out.println(s);

if (s.startsWith("fingers"))
brake.invoke();
});
Ok, that kind of looks like a foreach statement now, plus some baggage for loop control. Actually that's as far as I can go in the current prototype. Let's implement foreach then.

cont and brake both need to 'send a message' to the foreach method, without allowing the closure to finish. Without convoluting the usage code above, I can do that by making cont and brake throw exceptions, which is very similar to how continue and break are planned to be supported in closures, except I'm doing it in-language.
public static <T> void foreach(T[] ts,{T,{=>void},{=>void}=>void} block)
{
class Continue extends RuntimeException { }
class Break extends RuntimeException { }

for (int a=0;a<ts.length;a++)
{
try
{
block.invoke(ts[a],{=>throw new Continue();},{=>throw new Break();});
}
catch (Continue c)
{
continue;
}
catch (Break b)
{
break;
}
}
}
Look at the block.invoke line. I'm passing two closures to block.invoke - one that throws a Continue and one that throws a Break. Other than that, this method is pretty simple.

As I've said elsewhere, even when/if the control invocation syntax appears, you won't be able to implement foreach exactly as in Java 5, because int cannot be a type parameter, and the closures spec doesn't specify any boxing between int and Integer for type parameters.

Even if you never use this code (I won't!), you can see at a small scale the power of thinking in closures, especially for implementing language features. This is one of the reasons why Smalltalk was such a small language - you could implement much of what Java programmers think of as language as library methods. Lisp and FORTH are small languages (at least conceptually - ignore Common Lisp!) for similar reasons. Java 7 is aiming in the same direction.

Lucene:基于Java的全文检索引擎简介

This summary is not available. Please click here to view the post.

DB Browser RDBMS Tool

DBBrowser is a program which can be used to view the structure of databases as well as to run queries against them. The program is written to work with as many RDBMS systems as possible, using the JDBC API. Currently, the program supports connections to PostgreSQL, MySQL, Microsoft SQL Server versions 6.5 and newer, as well as Oracle RDBMS systems.

The DBBrowser uses a plugin API to connect to various databases and can be made to connect to any system for which a JDBC driver exists. More information on how to do this will be written at a future time. Until then, you may be able to use the generic JDBC plugin included in the DBBrowser release. It has been reported that the generic plugin works well with FireBird and the author of DBBrowser has used it to access HSQLDB databases.

Scripting support is provided through the BeanShell scripting language . It gives DBBrowser a powerful, Object Oriented, Java-like scripting language. Scripts can be created that will access a database's data and manipulate it using language constructs for which SQL does not provide, such as variables, branching logic, and loops. More information can be found in the documentation on scripting .

Tuning Java Performance: Java 2 C++ Compiler

NetBeans - Mixing Java and Ruby Applications

Mixing Java and Ruby Applications
Contributed by Tor Norbye and maintained by Beth Stearns
October 2007 [Revision number: V6.0-1]
This publication is applicable to NetBeans IDE 6.0 release

This article shows how to combine Ruby and Java applications using the NetBeans IDE.

Contents

- Article Requirements
- Create the Java Project
- Edit the Java Project
- Write the Rails Application



Article Requirements


This article shows how to combine Java applications with Ruby applications. Along the way, it demonstrates some of the latest Ruby capabilities in the NetBeans IDE 6.0.

This article requires the following:

A basic knowledge of programming with the Ruby technologies
NetBeans IDE 6.0 with Ruby (download) on your compouter
Set Up Instructions
There are several set-up tasks, principally involving database set up and including TopLink JAR files. Here is how to add the required currency data to a database table. When you set up the Rails project, you will add the necessary TopLink JAR files.

You need to configure a database as follows:

Create a table named CURRENCY.
Create three string (or VARCHAR) columns in the CURRENCY table: Country, Currency, and Name.
Populate the table with some data. For example, you might add these three currencies plus any others you want: "USA", "Dollar", "USD"; "Czech Republic", "Koruna", "CZK"; "Norway", "Krone", "NOK".
You also must set up NetBeans so that it can access the database table. That is, if need be, configure a JDBC driver for the database and add a data source in the Services window.

For example, the following SQL creates a CURRENCY table in a Derby database called SAMPLE (with a username and password combination of APP/APP). If you want to use the same SAMPLE database, you can execute this SQL from within the IDE (after connecting to the SAMPLE database) and create the table. Feel free to create your own Derby database, too, using the Tools->Java DB Database->Create Database action. The SQL to create the same table on a different database system may differ from this example.

drop table "APP"."CURRENCY";
create table "APP"."CURRENCY" (
country VARCHAR(20), currency VARCHAR(20), name VARCHAR (20),
id INTEGER GENERATED always AS IDENTITY);

alter table CURRENCY add constraint currencyPK PRIMARY KEY (id);
INSERT INTO CURRENCY VALUES ('USA', 'Dollar', 'USD',DEFAULT);
INSERT INTO CURRENCY VALUES ('Czech Republic', 'Koruna', 'CZK',DEFAULT);
INSERT INTO CURRENCY VALUES ('Norway', 'Krone', 'NOK',DEFAULT);
INSERT INTO CURRENCY VALUES ('France', 'Euro', 'EU',DEFAULT);
Create the Java Project
Once you have completed the setup tasks, you can create your project. Begin by creating a Java Desktop application, which is really a Swing application, and choose the option for database binding. The wizard takes you through the steps to connect the project, which we call Money, to the datasource, which in our case is the CURRENCY table on the Derby sample database. In a few button clicks you have a fully functional database CRUD application.

Start the default browser from an application

Start the default browser from an application
In this snippet, we initialize a Listbox from a file containing some URLs. When we double click an item, the default browser is started with the selected HTML page as parameter. This example is Windows oriented since I have used the start command which supports the file association.

[urlList.txt]
http://www.rgagnon.com/javadetails/java-0001.html|JAVA How-to 1
http://www.rgagnon.com/javadetails/java-0002.html|JAVA How-to 2
http://www.rgagnon.com/javadetails/java-0003.html|JAVA How-to 3
http://www.rgagnon.com/javadetails/java-0004.html|JAVA How-to 4
http://www.rgagnon.com/javadetails/java-0005.htmL|JAVA How-to 5

[StartBrowser.java]
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.net.*;
import java.io.*;

public class StartBrowser {
public static void main(String s[]) {
AFrame f = new AFrame();
}
}

class AFrame extends Frame implements ActionListener {
List lbx;
String url[] = new String[50];

public AFrame() {
// dispaly setup
setTitle("URL selection");
setSize(400,400);
lbx = new List();
add(lbx);
initLbx();
// action on listbox double click
lbx.addActionListener(this);
// to close the Frame
addWindowListener
(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
}
);
setVisible(true);
}

public void actionPerformed (ActionEvent ae) {
String theUrl = url[lbx.getSelectedIndex()];
// start the default browser (Win95 platform)
// on listbox double click

String cmdLine = "start " + theUrl;
// on NT, you need to start cmd.exe because start is not
// an external command but internal, you need to start the
// command interpreter
// String cmdLine = "cmd.exe /c " + cmdLine;
try {
Process p = Runtime.getRuntime().exec(cmdLine);
}
catch (Exception e) {
e.printStackTrace();
}
}

public void initLbx() {
int i = 0;
try {
String aLine = "";
BufferedReader in
= new BufferedReader(new FileReader("urlList.txt"));
while(null != (aLine = in.readLine())) {
java.util.StringTokenizer st =
new java.util.StringTokenizer(aLine, "|");
url[i++] = st.nextToken();
lbx.addItem(st.nextToken());
// lbx.add(st.nextToken()); in JDK1.2
}
}
catch(Exception e) {
e.printStackTrace();
}
}
}
Another way on Windows platform to start the default browser is ;
Runtime.getRuntime().exec
("rundll32 url.dll,FileProtocolHandler " + theUrl);

You may have difficulty to open a URL ending with .htm. All you need is to replace the last m with %6D, like

rundll32 url.dll,FileProtocolHandler http://www.rgagnon.com/howto.htm

for

rundll32 url.dll,FileProtocolHandler http://www.rgagnon.com/howto.ht%6D


--------------------------------------------------------------------------------
JDK1.6 has java.awt.Desktop.open(File)
See http://java.sun.com/javase/6/docs/api/java/awt/Desktop.html

JDIC provides the equivalent API for 1.4 and later.

See https://jdic.dev.java.net

try {
Desktop.browse(new URL("http://www.rgagnon.com");

}
catch (MalformedURLException e1) {
e1.printStackTrace();
}
catch (DesktopException e2) {
e2.printStackTrace();
}

NetBean Visual Library 2.0

the library seems useful.

http://www.netbeans.org/download/flash/netbeans_60/jl_preso_vislib/player.html

Java SSH Implementation

I found a introduce document of Java SSH Client on openssh site.

The following "free" clients are recommended for interoperating with OpenSSH from Java clients:

  • MindTerm 1 is an SSH1-only implementation. GPL Licence.

    "MindTerm is an entirely FREE(*) SSH protocol 1 client program written in 100% pure Java (non-certified). It is distributed with source code since we believe that security related software can't otherwise be seriously trusted. MindTerm can be run as a stand-alone program or as an applet in a webpage. It can be run with or without a GUI (stand-alone). It has two notable features setting it apart from some other clients, built in scp file transfer and a special ftp-tunnel which works with "ordinary" ftpd's "behind" the sshd."

    NOTE: Mindterm 2 is not free.

  • SSH Plugin is an SSH1-only implementation, by Matthias L. Jugel and Marcus Meißner. GPL Licence.

    "This implementation of SSH provides IDEA and RSA/PKCS#1 encryption and was originally written in 1998 by Cédric Gourio. He used a part of the old Java Telnet Applet to write his Java SSH client and so the code was similar to our old applet."

  • Ganymed-SSH2. BSD style license.

    "The Ganymed-SSH2 for Java library (implementing the SSH-2 protocol) is used in Ganymed and a couple of other projects at ETH Zurich. It allows you to connect to SSH servers from within your Java programs."

But obviousely there are more implemnatations.

Netspace Foundation - Java SSH Client

JCTerm -- SSH2 Terminal Emulator in Pure Java

2007/11/02

2007/11/01

Janus - Java to C++ source code converter without GC,thread and ...

Janus

Java to C++ source code converter
without GC,thread and ...

飯田 陽彦
株式会社バックス

haruhiko_iida@vacs.co.jp
概要
Janus(ヤヌス)は、Javaソースコードから、C++ソースコードおよびヘッダファイルを生成する言語コンバータである。JavaとC++の大きな違いの一つであるガーベジコレクションについては、これをサポートしない。メモリ管理は、C++と同様、開発者の責任であり、不要なメモリの解放は、Javaソースコード内に、C++のdelete,delete[]に相当するコードを明示的に記述することで行う。マルチスレッドのサポート、例外処理におけるfinally節等、JavaにあってC++にない要素は、単純に無視され、演算子多重定義やテンプレートなども、元のソースコードがJavaである事から、使用する事は出来ない。

つまり、Janusコードは、JavaとC++の構文要素の共通サブセットを用いて記述する事になり、さらに悪く言えば、JavaとC++の短所を集めた言語である、と言うことが出来る。

にも関わらず、Janusコードを用いる事が適切であるような状況がいくつか考えられる。

まず、Java仮想マシンが実装可能な資源を持たない組み込み機器向けのソフトウェアを記述する場合である。このような機器は、資源のコスト低下により、将来的にはJava仮想マシンが実装可能になるであろうし、Java仮想マシン実装技術自体の進展や、Personal JavaやEmbedded Javaの登場で、現在の機器でもJava仮想マシンが実装可能になる事が期待できる。このような場合、Janusコードでソフトウェアを記述しておけば、その状況に応じて、Javaのまま使用するのか、Janusを用いてC++に変換してから使用するかを選択する事が出来る。

また、Java仮想マシンが実装されている通常のパーソナルコンピュータやワークステーションであっても、リアルタイム系、特にサーバー系のソフトウェアを記述する場合には、性能面でJavaが使用可能かどうかの判断を行うのが困難である。このような場合、Janusを使用する事で、開発したソフトウェアをJavaとC++の双方で試験し、その結果を元に最終的な判断を下すことが出来る。

背景
Javaとその関連技術の進展により、ソフトウェアプラットフォームとしてのJava仮想マシンの存在は、日々その重要度を増している。そのため、ソフトウェア開発者に、この新しいプラットフォームに自身のソフトウェアを移植する事が求められている。しかし、Java仮想マシンの稼働する環境が増えつつあるとはいえ、Java仮想マシンが実装出来ない環境、とりわけ組込機器等のプラットフォームは、依然存在しつづける事が予想される。そのため、開発者は、機能的には同一のソフトウェアを、Java言語と、C,C++等の既存言語との両方で開発・維持しなければならず、その負担は大きくなってしまう。

この問題を打破するために、J2C,JCC等のNative Compilerが開発されている例があり、Janus開発の前に、これらが使用出来ないかどうか検討した。しかし、これらはいずれも完全なJavaソフトウェアを移植するためのものであり、当然ながらガーベジコレクションを初めとするJava仮想マシンの持つ機能を内包しているような実行ファイルを生成する。このため、実行ファイルの規模が大きくなり、(少なくとも私自身が対象としている)小資源プラットフォーム向けに使用する事はできない事が判明した。

一方、より直接的な方法として、既存のC,C++で記述されたソフトウェアをJavaに変換する方法(C to Java Converterの開発等)も検討したが、こちらはC,C++の持つ低レベル処理(ポインタ操作等)をJavaに置換することが困難である事が判明した。また、仮にそれらの方法が確立したとしても、今後益々増加する事が予想されるJava仮想マシンプラットフォームへのソフトウェア開発を既存言語で行うというのは、あまり好ましい事ではないだろうという感覚があり、この方法も断念した。

以上のような試行錯誤の上、最後にJanusのコンセプトである、JavaからC++への変換という着想を得た。一般に知られている通り、Javaの構文はC++のそれに酷似しており、JavaのソースコードをC++に変換する事が可能ではないかという事は以前から考えてはいたが、私自身、lexやyacc等の言語操作系ソフトウェアの扱いに不慣れだった事もあり、自分自身に開発が可能であるとは思われなかった。しかし、Sun Microsystemsが開発し、一般公開している、Javaで記述され、Javaを使ってソフトウェア記述が可能なコンパイラ・コンパイラJavaCCの存在を知り、これを用いると比較的容易にJavaソースコードの構文解析が出来る事が判明した。そこで、試しに簡単なconverterを試作したところ、たった3日で、望むものにかなり近い結果を得ることが出来、これが、今回のJanus開発につながった。

変換の実際
以下に、具体的な変換規則を順を追って説明する。

プリミティブ型の変換
Javaにおけるプリミティブ型は、C++と異なり、対象CPUや処理系に依存せず、言語仕様で厳密に規定されている。しかし、その事を無視すれば、意味的にはC++のプリミティブ型とほぼ1対1に対応するので、Janusでは、それらプリミティブ型の宣言を以下のように変換する。

変換前 変換後 備考
byte signed char -
short signed short -
int signed int -
long signed int64_t C++言語規定ではない
float float -
double double -
char unsigned short wchar_tではない
boolean signed int -

クラスとその参照
参照は、ガーベジコレクションという安全装置の存在、また参照値に対する演算が出来ない事を除けば、C ++のポインタと意味的に酷似している。そこで、参照型をポインタ型に置換する。具体的には、Javaで定義したクラス名に'_'(アンダースコア)を付加したものをC++のクラス名とし、そのポインタ型に対し、Javaのクラス名を使用する。 C++のクラス定義は、Javaソースコードと同名で、末尾が.Hであるヘッダファイルに出力される。また、Javaのクラスは、暗黙のうちにクラスObjectのサブクラスであるため、C++への変換でもそれを踏襲する。C++におけるクラス Object(厳密にはObject_)は、利用者が自分の用途に応じて用意する事ができる。(オブジェクト破壊の際の安全性を高めるための、デストラクタ(後述)に対するvirtual属性の付加等)


Point.java Point.h



class Point {
int x;
int y;
}




class Point_;
typedef Point_* Point;
class Point_ : public Object_ {
signed int x;
signed int y;
};


以上のようにクラス定義がされているので、参照型の宣言は、new 演算子適用時等の特殊な状況を除き、そのままC++ソースコードに反映される。

また、フィールドやメソッドの参照のための'.'は、クラス参照'::'、又はポインタ参照'->'演算子に置換される。(なお、現在の Janusの実装では、与えられた識別子がクラスを示しているのか、オブジェクトを示しているのかの判断を正しく行っていない。現在の実装では、識別子の最初の文字がUpper Caseであった場合、これをクラスと見なしている。従ってクラス名は、必ずUpper Caseでなければならず、反対にオブジェクト参照型の名称は、必ずLower Caseでなければならない)


Foo.java Foo.cpp


class Foo {
aMethod() {

Point pt;

pt = new Point();
pt.x = 10;
pt.y = Constant.maxY;
;
;
}
}





Foo_::aMethod(void) {

Point pt;

pt = new Point_();
pt->x = 10;
pt->y = Constant_::maxY;
;
;
}



配列
プリミティブ型や参照型の配列もJavaにおいては一種の参照型であり、上記のオブジェクト参照型と同様、これもポインタとみなして変換を行う。C++で、デフォルトコンストラクタの存在するクラスに対して、その実体の配列を生成する演算、例えば、new Point_[10]のような記述は、Java言語仕様に対応する記法が存在しないので、記述できない。


Foo.java Foo.cpp


class Foo {
aMethod() {
int[] ia;
Point[] pa;

ia = new int[10];
pa = new Point[20];
;
;
}
}





Foo_::aMethod(void) {

int* ia;
Point* pa;

ia = new int[10];
pa = new Point[10];
;
;
}



delete,delete[]演算子
C++ではガーベジコレクションがサポートされておらず、不要なメモリは、開発者が明示的にdelete,delete[]演算子を記述して解放する必要がある。Janusでも、その方針をそのまま踏襲しており、同様の記述をする必要がある。ただし、JanusコードがそのままJavaコードとして利用可能なようにするため、クラス'CC'を定義し、そのクラスメソッド 'dispose'、及び、'disposeArray'の呼び出しを、delete,delete[]演算子に置換するようになっている。Janus コードをJavaコードとして利用する場合には、上記のクラスメソッドを持つクラスCCを自身のパッケージ内に含める必要がある。

また、Javaでオブジェクトの持つ資源を解放するために利用されるメソッド'finalize'は、C++のデストラクタに置換される。


Foo.java Foo.cpp


class Foo {
aMethod() {

Point pt;
int[] ia;

pt = new Point();
ia = new int[10];
;
;
CC.dispose(pt);
CC.disposeArray(ia);
}
void finalize() {
CC.dispose(x);
CC.dispose(y);
}
}





Foo_::aMethod(void) {

Point pt;
int* ia;

pt = new Point_();
ia = new int[10];
;
;
delete pt;
delete[] ia;
}
Foo_::~Foo_(void) {
delete x;
delete y;
}


CC.java


public final class CC {
public static void dispose(Object o) {}
public static void disposeArray(Object o) {}
}



disposeを減らすための特別な場合
Javaではほとんどの場合、オブジェクト生成をnew演算子で行う。そのため、Janusコードを記述する場合、それと対になるCC.disposeが必要になり、メモリ管理に関する危険性が高くなる。一方、純粋にC++で記述する場合、new演算子の他に、スタティック領域やスタック領域に直接オブジェクトを生成するためのいくつかの記法が用意されている。そこでJanusでは、final属性を持つ型宣言があり、その初期演算子としてnewが記述されている場合に限り、new演算を取り去り、そこに直接オブジェクトを生成するようなC++コードに置換する。


Foo.java Foo.h


class Foo {
final Point x = new Point();
final Point[] y = new Point[10];






class Foo_ : public Object_ {
Point_ x;
Point y[10];
};


Foo.cpp



aMethod() {

final Point pt = new Point();
final Point[] apt = new Point[10];
final int[] ai = new int[20];

pt.x = 10;
pt.y = 20;
}
}





Foo_::aMethod(void) {

Point_ pt;
Point apt[10];
int ai[20];

pt->x = 10;
pt->y = 20;
}


この特別な記法を用いた場合の問題点とJansuの対処方法を以下に示す。

メンバー選択演算子の変換について
C++に変換後のPointオブジェクトのメンバーにアクセスするには、'->'ではなく、'.'を用いなければならないが、Janusでは、上記に見られるように、他のオブジェクトと同様、一律に'->'に変換している。その代わり、Janusでは、Pointクラスを変換する際、各々のクラスに以下のような演算子多重定義宣言を付加し、'->'演算やキャスト演算が、結果として正しく動作するようにしている。

Foo.h

class Point_ : public Object_ {
public: inline Point operator ->(void) {return this;}
public: inline operator Point(void) {return this;}
}


配列の添え字
この方法で配列を宣言する場合、C++では、[]内に記述する値は定数式でなければならないが、この検査はJanus内では行っていない。従って、記述の際には注意が必要である。

ローカル変数として使用する場合
この方法で生成されたオブジェクトは、メソッド終了時に破壊される。従って、生成したオブジェクトを保存したり、戻り値として使用してはならない。


定数宣言
Janusでは、'static final [プリミティブ型] = 値'の形式を持つフィールド宣言に限り、以下のような特殊な置換を行う。これは、このフィールドが定数式である事をC++に明示するために必要な措置である。

Foo.java Foo.h


public class Foo {
public static final int LIMIT = 10;
public final int[] ia = new int[LIMIT];
;
;
}





class Foo_ : public Object_ {
public: enum {LIMIT = 10};
public: int ia[LIMIT];
;
;
}



throw式に現れるnewのdispose
throw文で一般に行われるnew演算に限り、以下のような形式に変換される。Janusで例外をthrowする場合、この形式に沿わなければならない。また、この形式に沿う限り、生成された例外オブジェクトのdisposeに関して意識する必要はない。


Foo.java Foo.cpp


throw new Exception();





throw &Exception_();



マルチスレッドに関する制限
マルチスレッドに関する構文、synchronized属性およびsynchronized ブロックは、単純に無視される。マルチスレッド操作を含む(OS・処理系依存の)純粋なC++コードを記述し、これと変換済のJanusコードとを組み合わせてマルチスレッドソフトウェアを開発する事は可能ではあるが、上記の同期命令は使用できないので、注意が必要である。


Foo.java Foo.cpp


public synhronized void foo() {
;
synchronized(x) {
a = 1;
b = 2;
c = 3;
}
}





void Foo_::foo(void) {
;
{
a = 1;
b = 2;
c = 3;
}
}



finally節に関する制限
Janusではfinally節をサポートしていない。C++に対応する言語要素が存在せず、goto命令を用いたエミュレーションも、複雑なfinally節の動作順序を正しく真似るのはほぼ不可能である事からである。従って、Janus コードを記述する際には、finally節を用いてはならない。もし、記述してあった場合、そのfinally節は、後続のブロックを含めて、除去される。なお、finally節を含まない、try-catchは、C++でもサポートされているので、そのまま利用する事が出来る。
パッケージの使用
Janusには、Javaの優れた特徴の1つである、コアパッケージがない。ただし、これは、単にコアパッケージに相当するライブラリを作成する手間がなかったという問題であり、Janus自身の制約ではない。コアパッケージを使用したい場合、利用者自身が、必要とするコアパッケージの機能を持つライブラリを別途作成する必要がある。このような場合のため、packege宣言及びimport宣言を以下のように変換する。

まず、暗黙のうちにimportされているjava.lang.*のための#includeプリプロセッサ命令を付加する。

import宣言は、必ず、最後が*で終わる形式でなければならない。宣言は、区切りのピリオドをスラッシュに置換し、さらに、最後の*を、直前の名称に置き換え、末尾に.Hを付加したものを挿入する#includeプリプロセッサ命令に置換される。最後に、package宣言は、ピリオドで区切られた名称最後の部分を名称とし、末尾に.Hを付加したものを挿入する#includeプリプロセッサ命令に置換される。順番を入れ替えるのは、importされたクラス群をパッケージ内で参照する場合のためである。

他のパッケージをimportせずに使用する構文は、Janusではサポートしていない。他のパッケージを使用する場合には、必ず(末尾が *であるような)import宣言を行う必要がある。このため名前の衝突が起きる可能性があるが、これについては良い回避策がないため、何も行っていない。複数のパッケージを用いる場合、名前の衝突が起きないよう注意する必要がある。


Foo.java Foo.cpp


package JP.co.vacs.Test;
import lang.util.*;





#include
#include
#include "Test.h"



予約語の問題
Javaの予約語ではなく、C++では予約語である語がいくつか存在する。それらの語は、Javaでは識別子として使用できるが、そのままではC++に変換する事ができない。以下に、そのような語の一覧を示す。

asm signed auto
operator sizeof typedef
delete friend union
struct unsigned virtual
inline register template
enum extern

そこで、Janusではこれらの語に限り、語の後ろに'_'(アンダースコア)を付加する。しかし、この変換を行った結果、名前の衝突が発生する可能性があるため、上記の語は識別子としての使用をなるべく避ける方が望ましい。

Janusの使用法
単一のソースコードをコンバートする。

java JP.co.vacs.janus.Janus Foo.java

Foo.javaを元に、Foo.h,Foo.cppを生成する。現実には、単一クラスの生成はあまり意味がなく、Janusの生成試験以外にはあまり使えない。
同一パッケージの全ソースコードをコンバートする。

java JP.co.vacs.janus.Janus @files.txt

packages.txtに記述されたクラス群を全て変換する。同時に、パッケージ全体を他所から参照するためのヘッダファイル<パッケージ名>.hファイルも生成する。 files.txtには、変換対象となるJavaファイル名を列挙する。また、先頭に#がある場合は、その行をコメントとみなす。また、クラスが継承関係にある場合、スーパークラスのファイルはサブクラスのファイルの前に記述しなければならない。

files.txtの内容

#
# コメント(インデントは単に見やすくするためのものである)
#
Foo.java
Animal.java
Tiger.java
Dog.java
Tosa.java
Kisyu.java
#
# continue
#

ソースコード及び実行モジュール
実際のソフトウェアは以下から入手することが出来る。Janus自身はJavaで記述されているので、Java仮想マシンが実装されたプラットフォームならば、どこでも稼働するものと思われる。(ちなみに私自身はWindows95上で開発・実行している)

J970812.zip

あとがき
Janusは、Java及びJavaCCを用いて開発した。JavaCCは、とても優れたJava言語のためのコンパイラコンパイラであり、また、jjtreeという、構文木を自動生成するような定義ファイルを生成するプリプロセッサも同時に提供されている。更に、Java言語仕様のための構文定義ファイルも提供されており、Java言語解析のためには至れり尽くせりの環境である。無論、これらのツールの源となっているJavaが優れた言語/環境である事は今更言うまでもない。
Sun Microsystemsがもたらしたこれらのソフトウェア群を利用する事により、Janusは驚くほど短期間に開発する事が出来た。この場を借りて、深く感謝したい。

余談であるが、このソフトウェアの名称となったJanusは、古代ローマの双面の軍神の名前からとった。 JavaとC++の2面性を持ち、ソフトウェア開発者の戦場とも言える、現実のソフトウェア開発の現場で直ちに使用出来る事を狙いとして開発したソフトウェアの名称として相応しいものであると思う。

参考文献
書籍名 著者 出版社
プログラミング言語C++ B.Stroustrup
(訳:斉藤信男、三好博之、追川修一、宇佐美徹) アジソン・ウェスレイ・トッパン
Java言語入門 L.Lemay,C.Perkins
(訳:武舎広幸、久野禎子、久野靖) プレンティスホール出版

2007/10/31

NetBean 6 GUI Builder seems good at database application

JavaFX another Applet? (Add proxy support to WeatherFX)


Sun provides a new Scripting Language though Sun call it JavaFX Framework. It targets the Rich Content market.

The demos are interesting, but other than Silverlight, I don't think it has something new compares Flash to Ajax. Maybe Adobe Java based Flash Player is better. I hope it don't become another Applet.

I tried and read the WeatherFX demo application. It's lack of component and original functions. So the code of application is very long. Without a good GUI IDE I cannot believe it is productive.

Btw, I found WeatherFX cannot support proxy. Because the key logic is based on Java Beans. I add the proxy support to it.


private static final InputStream getInputStreamFromURL(URL url) throws IOException {
Properties properties = System.getProperties();
properties.put("http.proxyHost", httpProxyHost);
properties.put("http.proxyPort", httpProxyPort);
//String encodedLogin = new BASE64Encoder().encodeBuffer(login.getBytes());
URLConnection con = url.openConnection();
//con.setRequestProperty("Proxy-Authorization", "Basic " + encodedLogin);
con.connect();
return con.getInputStream();
}

2007/10/24

Study of J2EE Patterns

a good pdf including diagrams of j2ee design pattern

2007/10/10

Java Code Example: Using PLSQL Ref Cursors with JDBC


// -----------------------------------------------------------------------------
// RefCursorExample.java
// -----------------------------------------------------------------------------

import java.sql.DriverManager;
import java.sql.Connection;
import java.sql.Types;
import java.sql.CallableStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import oracle.jdbc.driver.OracleCallableStatement;
import oracle.jdbc.driver.OracleTypes;
import oracle.jdbc.driver.OracleResultSet;


/**
* -----------------------------------------------------------------------------
* This class provides an example on the use of REF Cursors to execute SQL from
* a JDBC program, simulating dynamic SQL.
*
* ===================
* DYNAMIC SQL IN JAVA
* ===================
*
* JDBC provides APIs for executing Dynamic SQL using PreparedStatement.
* For example:
*
* PreparedStatement pstmt;
* pstmt=conn.prepareStatement("SELECT name FROM dept WHERE deptno > ?");
* pstmt.setInt(1,104);
* ResultSet c1;
* c1=pstmt.executeQuery();
* pstmt.setInt(1,10)
* while (c1.next ()) {System.out.println (c1.getInt(1));}
*
*
* ==========
* REF CURSOR
* ==========
*
* Another option of executing dynamic SQL from JDBC is provided in this
* example. Keep in mind that this example will only work with Oracle8i and
* higher. In this case, the procedure uses a PL/SQL procedure which returns
* a REF CURSOR.
*
* A REF CURSOR is similar a pointer in the C programming language. It points
* to rows retrieved from the database using a PL/SQL cursor. The example I
* provide in this class uses a REF CURSOR to point to the result set
* returned by a SELECT statement that retrieves rows from the DEPT table
* using a PL/SQL cursor.
*
* In this example, I call a PL/SQL procedure named "get_dept_ref_cursor" which
* returns a variable of type "t_ref_cursor".
*
* Stored procedures can return user-defined types, or cursor variables, of the
* REF CURSOR category. This output is equivalent to a database cursor or a
* JDBC result set. A REF CURSOR essentially encapsulates the results of a
* query.
*
* Advantages of using a REF CURSOR are:
*
* 1.) Code Reusability
*
* The same package procedure could be used for other Java and non-Java
* applications.
*
* 2.) Load Balancing.
*
*
* =============================
* OracleCallableStatement CLASS
* =============================
*
* You will notice that in this example, I use an OracleCallableStatement class
* in place of our typical CallableStatement class. This class defines a method
* named getCursor() that enables you to read Oracle cursors.
*
*
* =================
* OracleTypes CLASS
* =================
*
* You will also notice the oracle.jdbc.driver.OracleTypes is also used
* when registering the OutParameter. This class defines those special TYPEs
* offered by the Oracle database. This class is similar to java.sql.Types.
*
*
* ===========================================================
* NOT USING OracleCallableStatement and OracleResultSet CLASS
* ===========================================================
*
* Note that you are not required to use the OracleCallableStatement and
* OracleResultSet classes; you could use the regular CallableStatement
* and ResultSet classes found in java.sql. However, you will need to
* use the getObject() method to read the Oracle cursor. An example of this is
* provided in this example with the performRefCursor2() method.
*
*
* -----------------------------------------------------------------------------
*
* NOTE: Opening a REF CURSOR for a statement present in a variable is only
* supported with Oracle8i and higher.
*
* NOTE: In order to successfully use this class, you will need to run the
* create_all_ddl.sql file included in the same section this example class
* is located.
*
* -----------------------------------------------------------------------------
*/

public class RefCursorExample {

final static String driverClass = "oracle.jdbc.driver.OracleDriver";
final static String connectionURL = "jdbc:oracle:thin:@localhost:1521:CUSTDB";
final static String userID = "scott";
final static String userPassword = "tiger";
Connection con = null;


/**
* Construct a RefCursorExample object. This constructor will create an Oracle
* database connection.
*/
public RefCursorExample() {

try {

System.out.print(" Loading JDBC Driver -> " + driverClass + "\n");
Class.forName(driverClass).newInstance();

System.out.print(" Connecting to -> " + connectionURL + "\n");
this.con = DriverManager.getConnection(connectionURL, userID, userPassword);
System.out.print(" Connected as -> " + userID + "\n\n");

} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}

}


/**
* This method is used to return a REF CURSOR that will be used to retrieve
* data from a result set. This REF CUSROR is retrieved by the JDBC program
* into a ResultSet.
*
* This method Uses the OracleCallableStatement and OracleResultSet classes.
*/
public void performRefCursor() {

OracleCallableStatement oraCallStmt = null;
OracleResultSet deptResultSet = null;

System.out.println("Using OracleCallableStatement / OracleResultSet");
System.out.println("-----------------------------------------------");

try {

oraCallStmt = (OracleCallableStatement) con.prepareCall(
"{? = call ref_cursor_package.get_dept_ref_cursor(?)}"
);
oraCallStmt.registerOutParameter(1, OracleTypes.CURSOR);
oraCallStmt.setInt(2, 104);
oraCallStmt.execute();

deptResultSet = (OracleResultSet) oraCallStmt.getCursor(1);

while (deptResultSet.next()) {
System.out.println(
" - " +
deptResultSet.getString(2) + " (" + deptResultSet.getInt(1) + "), " +
deptResultSet.getString(3)
);
}
System.out.println();

oraCallStmt.close();

} catch (SQLException e) {

e.printStackTrace();

}

}


/**
* This method is used to return a REF CURSOR that will be used to retrieve
* data from a result set. This REF CUSROR is retrieved by the JDBC program
* into a ResultSet.
*
* This method Uses the the regular CallableStatement and ResultSet classes.
*/
public void performRefCursor2() {

CallableStatement cstmt = null;
ResultSet rset = null;

System.out.println("Using CallableStatement / ResultSet");
System.out.println("-----------------------------------");

try {

cstmt = con.prepareCall(
"{? = call ref_cursor_package.get_dept_ref_cursor(?)}"
);
cstmt.registerOutParameter(1, OracleTypes.CURSOR);
cstmt.setInt(2, 104);
cstmt.execute();

rset = (ResultSet) cstmt.getObject(1);

while (rset.next()) {
System.out.println(
" - " +
rset.getString(2) + " (" + rset.getInt(1) + "), " +
rset.getString(3)
);
}
System.out.println();

cstmt.close();

} catch (SQLException e) {

e.printStackTrace();

}

}


/**
* Close down Oracle connection.
*/
public void closeConnection() {

try {
System.out.print(" Closing Connection...\n");
con.close();

} catch (SQLException e) {

e.printStackTrace();

}

}


/**
* Sole entry point to the class and application.
* @param args Array of String arguments.
* @exception java.lang.InterruptedException
* Thrown from the Thread class.
*/
public static void main(String[] args)
throws java.lang.InterruptedException {

RefCursorExample mainPrg = new RefCursorExample();
mainPrg.performRefCursor();
mainPrg.performRefCursor2();
mainPrg.closeConnection();

}

}

Open Source JDBC Proxy Drivers


JDBC drivers that are act as proxies for other JDBC drivers is quite an interesting design pattern (i.e. Decorator). It has many elements of an AOP interception based strategy albeit against a ubiquitious and standardized interface. Here's a list of open source projects that have exploited this design pattern. It'll be an interesting exercise to re-implement many of this into reusable aspects.




  1. P6Spy - P6Spy is an open source framework for applications to intercept and optionally modify database statements. The P6Spy distribution includes P6Log, which intercepts and logs the database statements of any application that uses JDBC. This application is particularly useful for developers to monitor the SQL statements produced by EJB servers, enabling the developer to write code that achieves maximum efficiency on the server. P6Spy is designed to be installed in minutes and requires no code changes.


  2. C-JDBC - C-JDBC provides a flexible architecture that allows you to achieve scalability, high availability and failover with your database tiers. C-JDBC instantiates the concept of RAIDb : Redundant Array of Inexpensive Databases. The database is distributed and replicated among several nodes and C-JDBC load balance the queries between these nodes. C-JDBC allows to build any cluster configuration including mixing heterogeneous databases. The main features provided by C-JDBC are performance scalability, fault tolerance and high availability. Additional features such as monitoring, logging, SQL requests caching can be provided as well. The architecture is widely open to allow anyone to plug custom requests schedulers, load balancers, connection managers, caching policies, etc.



  3. SSL-SQL-Proxy Server - The goal was to develop a server, that works as a proxy server, to forward SQL-Queries using SSL. The server was supposed to be mostly platform independent, and after some considerations, Java was the language of choice. The proxy-server accepts SSL-secured connections over TCP/IP, and reads the request using a specified protocol. Then the proxy-server uses a JDBC-Driver to connect to the database and forward the query, getting the result and transfer the result back to the client via SSL.


  4. Virtual JDBC - VJDBC is a vendor-agnostic type 3 JDBC-Driver with which you can remotely access every JDBC-Database in an efficient manner. Due to its command-oriented design different networking protocols can be supported quite easily. There is a similar open source project called RmiJdbc. The main difference between VJDBC and RmiJdbc is that RmiJdbc exposes the complete interface of the JDBC-Objects via RMI, so every call on an JDBC-Object will go over the network. VJDBC uses a different approach with command objects and a very thin remote interface.


  5. Proxool - Transparently adds connection pooling to your existing JDBC driver. You can monitor the performance of your database connections and listen to connection events.




  6. LDBC - LDBC (Liberty DataBase Connectivity) is a JDBC driver that provides vendor-independent database access. With LDBC, your application will just work on all major databases and you don't have to change any source code. LDBC is based on ANSI-SQL and JDBC. LDBC radically simplifies porting of existing or new applications to new databases. The main components of LDBC are a JDBC driver and a SQL grammar converter. LDBC completely shields the application from database vendor specific code. Included SQL grammar and JDBC API documentation.


  7. HA-JDBC - High-Availability JDBC. HA-JDBC is a JDBC driver implementation that provides light-weight, transparent clustering capability to groups of homogeneous JDBC-accessed databases. In contrast with the C-JDBC project, HA-JDBC does not limit the functionality of the underlying JDBC drivers and supports many JDBC 3.0 features.


  8. PFJDBC - A wrapper over any JDBC driver, it corrects some of the common mistakes the programmers do during the development process and also provides SQL execution timing information. Hints for: cache, AUTOCOMMIT, ISO LEVEL, performance reports for TX,STMTS, etc.


  9. Backpedal - Backpedal is a JDBC driver that can be messaged to roll back all SQL statements issued through it. It is intended to be used in testing scenarios, to allow you return the database to the state it was in before your test case started.


  10. jxdbc - A JDBC proxy driver for JXTA.


  11. Microsoft JDBC Driver Proxy - Tired of the Microsoft JDBC Driver running slowly and failing on Object and NVARCHAR fields? Proxy the Microsoft JDBC driver to run Faster and Better!


  12. c3p0 - c3p0 is an easy-to-use library for augmenting traditional (DriverManager-based) JDBC drivers with JNDI-bindable DataSources, including DataSources that implement Connection and Statement Pooling, as described by the jdbc3 spec and jdbc2 standard extensions. Not really a proxy but uses byte code injection to acomplish its deed. Apparently, the Hibernate folks love this project.


  13. Daffodil Replicator - Daffodil Replicator synchronizes databases by transfer and merging of changed data. It allows bi-directional synchronization with heterogeneous enterprise databases supporting JDBC drivers and key features such as triggers, procedures and auto increment columns. Its flexible publish and subscribe model has been tested with Oracle, SQL-Sever, PostgreSQL, Derby and Daffodil DB.


  14. Primrose - Primrose is a database connection pool. Current containers support are Tomcat 4 & 5, Resin 3 and JBoss 3 and a
    standalone version used for applications not running inside a container.
    Features include optional notification of crisis events, SQL statement monitoring for connections, starting/stopping pools without application restarts, adding / removing connections on the fly, a web interface for pool management, queueing of connection requests during heavy load, statistics for types of SQL statements executed and executiion times and enhanced debug information for hanging connections.


  15. Sequoia - Sequoia is a transparent middleware solution for offering clustering, load balancing and failover services for any database. Sequoia is the continuation of the C-JDBC project∞. The database is distributed and replicated among several nodes and Sequoia balances the queries among these nodes. Sequoia handles node failures and provides support for checkpointing and hot recovery.


  16. Elvyx - Elvyx is a tool designed to monitor and profile the jdbc activity. This jdbc profiler has a wrapper that intercept the access to the database and send this information to the elvix server. The server receives the information, store the data into a database and serve this information to the client. The client shows sql statements, bound sql statements, elapsed time, elapsed time preparing the statements, etc.




Ping me if you know of any other interesting JDBC proxy implementations.

2007/08/03

Note of Hibernate & Spring Testing

Recently, I complete tested the function of Hibernate and Spring.
I wrote this note to memo the experience.

* install the version is a point of hibernate
download the version at least the same major version software.
it may be the permenant weak point of the open source.
* midgen maps bit (boolean) to object
manually modify the attibute of the field to make it map to right java type.
* to make the update effact to all related object
add cascade="save-update" to set tag
* add named query







* to make spring handle the transaction

PROPAGATION_REQUIRED


* generate hbm.xml from java soruce with xdoclet
ant generate-hbm-from-xdoclet