JBoss 5.0에서 Network Derby를 쓸 일이 있어 만들었습니다. 기본적으로 들어가 있는데 embedded derby는 local server 용입니다.
jboss-beans.xml
데이터베이스 생성은 다음과 같이 됩니다. 자바 애플리케이션을 실행하는 디렉토리하위에 data/derby가 생기게 되며 접속은 다음과 같습니다.
IJ : connect 'jdbc:derby://127.0.0.1:1527/data/derby';
jboss-beans.xml
<?xml version="1.0" encoding="UTF-8"?> <deployment xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:jboss:bean-deployer bean-deployer_2_0.xsd" xmlns="urn:jboss:bean-deployer:2.0"> <bean name="DerbyDatabase" class="org.jboss.jdbc.DerbyDatabase"> <property name="database">derby</property> </bean> </deployment>
package org.jboss.jdbc;
/*
Derby - Class SimpleNetworkServerSample
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import org.apache.derby.drda.NetworkServerControl;
import org.jboss.aop.microcontainer.aspects.jmx.JMX;
import org.jboss.logging.Logger;
/**
* In order for a database to be consistent, only one JVM is allowed to access
* it at a time. The embedded driver is loaded when the Network Server is
* started. Hence, the JVM that starts the Network Server can get an embedded
* connection to the same database that Network Server is accessing to serve the
* clients from other JVMs. This solution allows you to take advantage of the
* performance benefits of embedded driver as well as allow for client
* connections from other JVMs to connect to the same database.
*
*
* In particular,this sample program 1) starts the Derby Network Server using a
* property and also loads the embedded driver 2) checks if the Derby Network
* Server is up and running 3) creates the database 'NSSimpleDB' if not already
* created 4) obtains an embedded database connection 5) tests the database
* connection by executing a sample query 6) allows for client connections to
* connect to the server until the user decides to stop the server and exit the
* program 7) closes the connections 8) shuts down the Derby Network Server
* before exiting the program.
*
* Note, on running this program, there will be a NSSimpleDB database directory
* created if not present already and there will be a derby.log file which
* contains messages from Derby
*
* <P>
* Usage: java SimpleNetworkServerSample
*
*/
@JMX(name="org.jboss.jam.admin.jdbc:service=DerbyDatabase", exposedInterface=DerbyDatabaseMBean.class)
public class DerbyDatabase implements DerbyDatabaseMBean {
private static final Logger log = Logger.getLogger(DerbyDatabase.class);
private org.apache.derby.drda.NetworkServerControl server;
private Connection embeddedConn = null;
/**
* Default password: <code>empty string</code>.
*/
private static final String DEFAULT_PASSWORD = "admin";
/**
* Default user: <code>sa</code>.
*/
private static final String DEFAULT_USER = "admin";
/**
* JDBC Driver class: <code>org.apache.derby.jdbc.EmbeddedDriver</code>.
*/
private static final String JDBC_DRIVER_CLASS = "org.apache.derby.jdbc.EmbeddedDriver";
// private static final String JDBC_DRIVER_CLASS = "org.apache.derby.jdbc.ClientDriver";
/**
* JDBC URL common prefix: <code>jdbc:derby:</code>.
*/
private static final String JDBC_URL_PREFIX = "jdbc:derby:";
/**
* Default data subdir: <code>derby</code>.
*/
private static final String DERBY_DATA_DIR = "data";
/**
* Default database name: <code>default</code>.
*/
private static final String DEFAULT_DATABASE_NAME = "default";
/**
* Database name.
*/
String name = DEFAULT_DATABASE_NAME;
/**
* Database user.
*/
private String user = DEFAULT_USER;
/**
* Database password.
*/
private String password = DEFAULT_PASSWORD;
/**
* Set the database name.
*
* @jmx.managed-attribute
*/
public void setDatabase(String name) {
if (name == null) {
name = DEFAULT_DATABASE_NAME;
}
this.name = name;
}
/**
* Get the database name.
*
* @jmx.managed-attribute
*/
public String getDatabase() {
return name;
}
/**
* @return the password
*
* @jmx.managed-attribute
*/
public String getPassword() {
return password;
}
/**
* @return the user
*
* @jmx.managed-attribute
*/
public String getUser() {
return user;
}
/**
* @param password
*
* @jmx.managed-attribute
*/
public void setPassword(String password) {
if (password == null) {
password = DEFAULT_PASSWORD;
}
this.password = password;
}
/**
* @param user
*
* @jmx.managed-attribute
*/
public void setUser(String user) {
if (user == null) {
user = DEFAULT_USER;
}
this.user = user;
}
@Override
public String getMBeanClassName() {
return MBEAN_CLASS_NAME;
}
@Override
public String getDerbyDatabaseName() {
return OBJECT_NAME_STR;
}
public synchronized void create() {
}
public synchronized void stop() {
try {
if (embeddedConn != null) embeddedConn.close();
getConnection("jdbc:derby:;shutdown=true");
} catch (SQLException e) {
log.info("Derby shutdown successfully.", e);
} catch(Exception ee) {}
embeddedConn = null;
try {
server.shutdown();
} catch (Exception e) {
e.printStackTrace();
}
}
public synchronized void destroy() {
log.info("Derby has detroyed!");
}
/*
* The database is located in the same directory where this program is being
* run. Alternately one can specify the absolute path of the database
* location
*/
private static String DBNAME = "derbyDb";
public void start() throws Exception {
try {
startNetworkServer();
/*
* Can now spawn threads to do many wonderous things with embedded
* connections but allow others to connect via Network Server. But
* for sample purposes, an embedded connection will be obtained and
* a sample query executed before waiting for the user to give input
* to shutdown the server.
*/
String dbURL = JDBC_URL_PREFIX
+ DerbyDatabase.DERBY_DATA_DIR + '/' + name
+ ";create=true";
log.info("starting derby " + dbURL);
this.embeddedConn = getConnection(dbURL);
} catch (Exception e) {
log.error("Failed to start NetworkServer: " + e);
}
}
/**
* Get the connection.
*
* @param dbURL
* jdbc url.
*
* @return the connection, allocate one if needed.
*
* @throws Exception
*/
private synchronized Connection getConnection(String dbURL)
throws Exception {
if (embeddedConn == null) {
ClassLoader cl = Thread.currentThread().getContextClassLoader();
Class.forName(JDBC_DRIVER_CLASS, true, cl).newInstance();
embeddedConn = DriverManager.getConnection(dbURL, user, password);
}
return embeddedConn;
}
/**
* Setting the derby.drda.startNetworkServer property to true, either in the
* System properties as we do here or in the derby.properties file will
* cause Network Server to start as soon as Derby is loaded.
*
* To load Derby we just need to load the embedded Driver with:
* Class.forName("org.apache.derby.jdbc.EmbeddedDriver").newInstance();
*
* Then we will test for a while and make sure it is up, before we give up.
*
* Alternately Network Server might be started from the command line or from
* some other program. Note: only the JVM that starts Network Server can
* make an embedded connection.
*/
public void startNetworkServer() throws Exception {
// Start network server using the property
// and then wait for the server to start by testing a connection
startWithProperty();
waitForStart();
}
/**
* Start Derby Network Server using the property
* derby.drda.startNetworkServer. This property can be set as a system
* property or or by setting in derby.properties file. Setting this property
* to true , starts the Network Server when Derby boots up. The port at
* which the Derby Network Server listens to can be changed by setting the
* derby.drda.portNumber property. By default, the server starts at port
* 1527 Server output goes to derby.log
*/
private void startWithProperty() throws Exception {
log.info("Starting Network Server");
System.setProperty("derby.drda.startNetworkServer", "true");
// Booting derby
Class.forName("org.apache.derby.jdbc.EmbeddedDriver").newInstance();
}
/**
* Tries to check if the Network Server is up and running by calling ping If
* successful, then it returns else tries for 50 seconds before giving up
* and throwing an exception.
*
* @throws Exception
* when there is a problem with testing if the Network Server is
* up and running
*/
private void waitForStart() throws Exception {
// Server instance for testing connection
server = null;
// Use NetworkServerControl.ping() to wait for
// NetworkServer to come up. We could have used
// NetworkServerControl to start the server but the property is
// easier.
server = new NetworkServerControl();
log.info("Testing if Network Server is up and running!");
boolean knowIfServerUp = false; //do we know if server is ready to accept connections
int numTimes = 5;
// Test to see if server is ready for connections, for 15 seconds.
while(!knowIfServerUp && (numTimes >0)) {
try {
// testing for connection to see if the network server is up and running
// if server is not ready yet, this method will throw an exception
numTimes--;
server.ping();
knowIfServerUp = true;
}
catch(Exception e) {
log.error(" Unable to obtain a connection to network server, trying again after 3000 ms.");
Thread.currentThread().sleep(3000);
}
}
log.info("Derby Network Server now running");
}
}
데이터베이스 생성은 다음과 같이 됩니다. 자바 애플리케이션을 실행하는 디렉토리하위에 data/derby가 생기게 되며 접속은 다음과 같습니다.
IJ : connect 'jdbc:derby://127.0.0.1:1527/data/derby';
http://www.javapattern.info/trackback/238





