我的目的 - 为DAO层创建测试。我的Hibernate配置有通过JNDI指定的数据。我也使用Jboss 5.1,因此需要进行事务查找。
<property name="hibernate.connection.datasource">java:jdbc/MysqlDS</property>
<property name="hibernate.transaction.factory_class">org.hibernate.transaction.JTATransactionFactory</property>
<property name="hibernate.transaction.manager_lookup_class">org.hibernate.transaction.JBossTransactionManagerLookup</property>
要进行测试我需要绑定这些东西。 Todo这个我创建类util来绑定。完整代码
public class RegisteringJNDIWithDataSource {
public static final String JNDI_MY_DS = "java:jdbc/MysqlDS";
private static final String MYSQL_USER = "user";
private static final String MYSQL_PASS = "pass";
private static final String MYSQL_HOST = "localhost";
public static String CTX_INITIAL_CONTEXT_FACTORY = "org.jnp.interfaces.NamingContextFactory";
public static String CTX_URL_PKG_RPEFIXES = "org.jboss.naming";
private void startRegistry() throws NamingException, RemoteException {
System.out.println(LocateRegistry.getRegistry());
Registry reg = LocateRegistry.createRegistry(1099);
NamingServer server = new NamingServer();
NamingContext.setLocal(server);
System.out.println("RMI registry Stared.");
}
public InitialContext createInitialContextContext() throws NamingException {
System.setProperty(Context.URL_PKG_PREFIXES, CTX_URL_PKG_RPEFIXES);
System.setProperty(Context.INITIAL_CONTEXT_FACTORY, CTX_INITIAL_CONTEXT_FACTORY);
InitialContext initialContextcontext = new InitialContext();
return initialContextcontext;
}
/**
* Registry the following JNDIs
*
* @throws RemoteException
* @throws NamingException
*/
public void registrate() throws RemoteException, NamingException {
startRegistry();
InitialContext ic;
ic = createInitialContextContext();
String[] cxts = JNDI_MY_DS.split("/");
String inCxt = cxts[0];
createSubcontext(ic, inCxt);
for (int i = 1; i < cxts.length - 1; i++) {
// if the data source name is like java:/comp/mysqldatasource
// this takes care of creating subcontexts in jndi
inCxt = inCxt + "/" + cxts[i];
createSubcontext(ic, inCxt);
}
ic.rebind(JNDI_MY_DS, createMysqlDataSource("db_name"));
// the following requires JBoss dependent class. May be sth can be done to generalize this
TransactionManager tm = new CustomTXNManager();
ic.bind("java:/TransactionManager", tm);
UserTransaction ut = new CustomUserTransaction();
ic.bind("UserTransaction", ut);
}
private static Context createSubcontext(Context ctx, String cxtName) throws NamingException {
System.out.println(" creating subcontext " + cxtName);
Context subctx = ctx;
Name name = ctx.getNameParser("").parse(cxtName);
for (int pos = 0; pos < name.size(); pos++) {
String ctxName = name.get(pos);
try {
subctx = (Context) ctx.lookup(ctxName);
} catch (NameNotFoundException e) {
subctx = ctx.createSubcontext(ctxName);
}
// The current subctx will be the ctx for the next name component
ctx = subctx;
}
return subctx;
}
public void unregistrate() throws NamingException {
InitialContext context;
context = createInitialContextContext();
context.unbind(JNDI_MY_DS);
}
private MysqlConnectionPoolDataSource createMysqlDataSource(String database) throws NamingException {
MysqlConnectionPoolDataSource dataSource;
dataSource = new MysqlConnectionPoolDataSource();
dataSource.setUser(MYSQL_USER);
dataSource.setPassword(MYSQL_PASS);
dataSource.setServerName(MYSQL_HOST);
dataSource.setPort(3306);
dataSource.setDatabaseName(database);
return dataSource;
}
public static void main(String args[]) {
RegisteringJNDIWithDataSource dataSource = new RegisteringJNDIWithDataSource();
try {
dataSource.registrate();
} catch (RemoteException ex) {
ex.printStackTrace();
} catch (NamingException ex) {
ex.printStackTrace();
}
}
public static class CustomTXNManager extends TransactionManagerImple implements Serializable {
private static final long serialVersionUID = 1L;
public CustomTXNManager() {
}
}
public static class CustomUserTransaction extends UserTransactionImple implements Serializable {
private static final long serialVersionUID = 1L;
public CustomUserTransaction() {
}
}
}
如果从控制台调用,一切正常。但是当我从JUnit调用它时,我得到了异常。
@Test
public void test() throws RemoteException, NamingException {
RegisteringJNDIWithDataSource j = new RegisteringJNDIWithDataSource();
j.registrate();
}
javax.naming.OperationNotSupportedException
at com.sun.jndi.rmi.registry.RegistryContext.createSubcontext(RegistryContext.java:230)
at javax.naming.InitialContext.createSubcontext(InitialContext.java:464)