Üdv!
A helyzet a következő:
Van egy ANT scriptem ami egy ORACLE SQL adatbázison hajt végre műveleteket. Azt kéne megoldanom, hogy ez az ANT script ne a JDBC-t használja kapcsolódásra, hanem az applikációs szerveren is használt JNDI-t. Tehát valahogy kölcsön kéne adnom a kapcsolatot az ANT scriptnek. Az ANT taskokat egy servlet-ből hívogatom, tehát ha kész leszek akkor úgy fog kinézni az egész, hogy webes felületről lehet ANT scripteket futtatni és műveleteket végezni egy adatbázison. Eddig nem találtam semmi megoldást arra, hogy használhatnám az ANT berkein belül a JNDI-t kapcsolódásra. Viszont arra gondoltam, hogy lehet egy saját ANT task-ot írni amit ezt hívatott megoldani.
A kérdésem az lenne, hogy mennyire nehéz ezt megoldani, illetve valaki csinált-e már ilyet. Illetve kéne egy kis segítség, hogyan induljak el.
Ezeket találtam eddig amik relevánsak lehetnek: 1, 2
A végére valami ilyesmit szeretnék:
< echo message="deleting database ${dbName} ..."/ >
< sql driver="${dbJDBCDriver}" url="${dbJDBCMasterUrl}" userid="${dbAdminUser}" password="${dbAdminPwd}" onerror="abort" autocommit="true" >
< transaction>DROP DATABASE ${dbName};
< classpath refid="jdbc.drivers"/ >
< /sql >
ahol az url tetszőlegesen választható és lehet akár egy JNDI url is. Pl "java:VALAMI-DATASOURCE"
- 1347 megtekintés
Hozzászólások
Irjal egy jdbc drivert, ami az url-ben megadott jndi datasourcebol szedi a kapcsolatokat.
- A hozzászóláshoz be kell jelentkezni
Igen igen, most pont azon vagyok. :) [FIX: Nem a drivert írom meg, hanem a kapcsolat lekérési módját definiálom felül.]
Kiterjesztettem a JDBCTask osztályt:
package de.intelligrator.ant;
import java.sql.Connection;
import org.apache.tools.ant.taskdefs.JDBCTask;
public class UniversalDBConnectorTask extends JDBCTask{
}
Úgy gondolom ezt kéne felülírnom:
protected Connection getConnection() throws BuildException {
if (userId == null) {
throw new BuildException("UserId attribute must be set!", getLocation());
}
if (password == null) {
throw new BuildException("Password attribute must be set!", getLocation());
}
if (url == null) {
throw new BuildException("Url attribute must be set!", getLocation());
}
try {
log("connecting to " + getUrl(), Project.MSG_VERBOSE);
Properties info = new Properties();
info.put("user", getUserId());
info.put("password", getPassword());
Connection conn = getDriver().connect(getUrl(), info);
if (conn == null) {
// Driver doesn't understand the URL
throw new SQLException("No suitable Driver for " + url);
}
conn.setAutoCommit(autocommit);
return conn;
} catch (SQLException e) {
throw new BuildException(e, getLocation());
}
}
Már az is megvan, hogy tudom megszerezni a JNDI connection-t:
private Connection getConnection() {
Connection connection = null;
try {
InitialContext context = new InitialContext();
DataSource dataSource = (DataSource) context.lookup("java:FLOW-DATASOURCE");
connection = dataSource.getConnection();
} catch (NamingException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
return connection;
}
És majd lesz egy plusz property amivel ki lehet választani, hogy JDBC vagy JNDI. Természetesen a JNDI-nek akkor van értelme ha fut az applikációs szerver. A gond az, hogy ha simán felüldefiniálom a getConnection metódust akkor Exceptiont kapok, gondolom nem képes megtalálni a JNDI-t, mert az applikációs szerverhez sem fér hozzá. Viszont ha ugyanezt a kódot egy servletből futtatom akkor működik a dolog. Azt gondolom, hogy az lehet a megoldás hogy a szervletbe kérem le a kapcsolatot és valahogy tovább passzolom a UniversalDBConnectorTask-nak?
Itt az exception amit kapok ha az UniversalDBConnectorTask-bol hívom meg a getConnection-t:
JNDI:
[SQLExecExtended] javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file: java.naming.factory.initial
[SQLExecExtended] at javax.naming.spi.NamingManager.getInitialContext(Unknown Source)
[SQLExecExtended] at javax.naming.InitialContext.getDefaultInitCtx(Unknown Source)
[SQLExecExtended] at javax.naming.InitialContext.getURLOrDefaultInitCtx(Unknown Source)
[SQLExecExtended] at javax.naming.InitialContext.lookup(Unknown Source)
[SQLExecExtended] at de.intelligrator.ant.UniversalDBConnectorTask.getConnection(UniversalDBConnectorTask.java:19)
[SQLExecExtended] at de.intelligrator.ant.SQLExec.execute(SQLExec.java:414)
[SQLExecExtended] at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:291)
[SQLExecExtended] at sun.reflect.GeneratedMethodAccessor4.invoke(Unknown Source)
[SQLExecExtended] at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
[SQLExecExtended] at java.lang.reflect.Method.invoke(Unknown Source)
[SQLExecExtended] at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
[SQLExecExtended] at org.apache.tools.ant.Task.perform(Task.java:348)
[SQLExecExtended] at org.apache.tools.ant.Target.execute(Target.java:390)
[SQLExecExtended] at org.apache.tools.ant.Target.performTasks(Target.java:411)
[SQLExecExtended] at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1399)
[SQLExecExtended] at org.apache.tools.ant.Project.executeTarget(Project.java:1368)
[SQLExecExtended] at org.apache.tools.ant.helper.DefaultExecutor.executeTargets(DefaultExecutor.java:41)
[SQLExecExtended] at org.eclipse.ant.internal.launching.remote.EclipseDefaultExecutor.executeTargets(EclipseDefaultExecutor.java:32)
[SQLExecExtended] at org.apache.tools.ant.Project.executeTargets(Project.java:1251)
[SQLExecExtended] at org.eclipse.ant.internal.launching.remote.InternalAntRunner.run(InternalAntRunner.java:424)
[SQLExecExtended] at org.eclipse.ant.internal.launching.remote.InternalAntRunner.main(InternalAntRunner.java:138)
- A hozzászóláshoz be kell jelentkezni
Hat, en egy java.sql.Driver implementaciora gondoltam, de valahol mindegy. Az sql taskon belul lehetnek connectionProperty tagek, ott meg lehetne adni a jndis configot.
- A hozzászóláshoz be kell jelentkezni
Ahh hülye vagyok Eclipse-ből futtatom az ANT targetet. Nyílván nem tudja lekérni a JNDI kapcsolatot, mert az egy másik Java proccess, ha viszont a servlet-ből futtatom az ANT targetet, akkor az ugyanaz a Java proccess és akkor már van rá esély h megtalálja.. :)
- A hozzászóláshoz be kell jelentkezni