I am trying to use JDBC inside my meteor application but I was not successful in loading the driver class.
the code is simple enough:
console.log("testing jdbc " + process.env.PWD + "/server/ojdbc14-11.2.jar");
var java = Meteor.require('java');
java.classpath.push(process.env.PWD + '/server/ojdbc14-11.2.jar');
console.log("class loaded");
var driver = java.newInstanceSync('oracle.jdbc.driver.OracleDriver');
console.log("driver instantiated");
var result = java.callStaticMethodSync('java.sql.DriverManager','registerDriver', driver);
console.log("driver registered");
result = java.callStaticMethodSync('java.sql.DriverManager','getConnection', 'jdbc:oracle:thin:user/password#local.sertal.ch:7788/KND1');
console.log("connection established");
I am using the Meteor npm package to include java the console never shows the message driver instantiated
I tried the same thing with a naked nodejs script and it worked fine. The code is almost the same:
var java = require('java');
java.classpath.push(__dirname + '/ojdbc14-11.2.jar');
var driver = java.newInstanceSync('oracle.jdbc.driver.OracleDriver');
var result = java.callStaticMethodSync('java.sql.DriverManager','registerDriver', driver);
var connection = java.callStaticMethodSync('java.sql.DriverManager', 'getConnection', 'jdbc:oracle:thin:user/password#local.sertal.ch:7788/KND1');
Related
My calls to Oracle via jruby aren't closing their db connections.
Here is the code from the webpage making the call:
<%
require 'jdbc_ssl_connection'
# Database settings
url = "jdbc:oracle:thin:#(DESCRIPTION=(ADDRESS=(PROTOCOL=TCPS)(HOST=**REMOVED**)(PORT=**REMOVED**))(CONNECT_DATA=(SERVICE_NAME=**REMOVED**)))"
output = ""
select_stmt, rest, select_sql = nil
begin
conn = OracleConnection.create(url)
# Display connection using the to_s method of OracleConnection
select_sql = "select FIELD from SCHEMA.TABLE WHERE FIELD='"+#subject["file-name"].first+"'"
select_stmt = conn.create_statement
rset = select_stmt.execute_query select_sql
while (rset.next)
output = output + rset.getString(1)
end
rescue
error = "Error:", $!, "\n"
ensure
if (!select_stmt.nil?)
select_stmt.close
end
if (!rset.nil?)
rset.close
end
if (!conn.nil?)
conn.close_connection
end
end
%>
Here is the class that interacts with the driver.
# jdbc_ssl_connection.rb
require 'java'
java_import 'oracle.jdbc.OracleDriver'
java_import 'java.sql.DriverManager'
java_import 'java.util.Properties'
class OracleConnection
#conn = nil
def initialize (url)
#url = url
properties = java.util.Properties.new
properties['user'] = 'REMOVED'
properties['password'] = 'REMOVED'
# Load driver class
oradriver = OracleDriver.new
DriverManager.registerDriver oradriver
#conn = DriverManager.get_connection url, properties
#conn.auto_commit = false
end
# Add getters and setters for all attributes we wish to expose
attr_reader :url, :connection
def close_connection()
#conn.close() unless #conn
end
def prepare_call(call)
#conn.prepare_call call
end
def create_statement()
#conn.create_statement
end
def prepare_statement(sql)
#conn.prepare_statement sql
end
def commit()
#conn.commit
end
def self.create(url)
conn = new(url)
end
def to_s
"OracleConnection [url=#{#url}]"
end
alias_method :to_string, :to_s
end
The code works and is pretty simple. I ran a test and I have about 100 open sessions on the db. For some reason the call to close the connection isn't stopping the session. Any ideas what might be wrong?
def close_connection()
#conn.close() unless #conn
end
because of the conditional, you really wanted: #conn.close if #conn
I wanted to implement script execution time handling, but stumbled upon this issue. If I design webdriver's script to execute in following manner, it successfully returns a variable, but it doesn't trigger ScriptTimeoutException as it should be. Any ideas why? I've adopted this script from webdriver's javadoc example
System.setProperty("webdriver.chrome.driver", "C:\\chromedriver.exe");
WebDriver driver = new ChromeDriver();
//---setting script timeout to 1ns to force ScriptTimeoutException
driver.manage().timeouts().setScriptTimeout(1, TimeUnit.NANOSECONDS);
//this script works fine, ScriptTimeoutException is triggered
String script1 = "window.setTimeout(arguments[arguments.length - 1], 500);";
//this script is able to pass his return variable back to Java, but doesn't triggers ScriptTimeoutException
String script2 = "var callback = arguments[arguments.length - 1];" +
"var stringVar = 'abcd';" +
"callback(stringVar);";
while (true) {
Instant beforeScript = Instant.now();
//((JavascriptExecutor) driver).executeAsyncScript(script1);
String result = (String) ((JavascriptExecutor) driver).executeAsyncScript(script2);
System.out.println(result + " " + Duration.between(beforeScript, Instant.now()).toMillis());
}
Well, after searching for a while and discussing this with selenium\chromedriver developers, I've found that my script wasn't actually async script.
The proper async script that will throw ScriptTimeoutException would be something like this:
var callback = arguments[arguments.length - 1];
var stringVar = 'abcd';
setTimeout(()=>callback(stringVar), 100);
if I use a web driver then it works perfectly
driver = new PhantomJSDriver(capabilities);
driver.executePhantomJS( "var page = this;");
How can I make it work?
driver = new RemoteWebDriver(capabilities);
driver.executePhantomJS( "var page = this;");
UPDATE
My code
capabilities = DesiredCapabilities.phantomjs();
driver = new RemoteWebDriver(capabilities);
driver.executePhantomJS( "var page = this; binary =0;mimetype=''; count = 0;id=0; bla = '{';"
+"page.onResourceReceived = function(request) {"
+ "if(id !== request.id){"
+"bla += '\"'+count+ '\":'+JSON.stringify(request, undefined, 4)+',';"
+"if(request.contentType.substring(0, 11) =='application'){"
+"console.log(request.contentType);"
+ "mimetype = request.contentType;"
+ "binary++;"
+ "}"
+"count++;"
+ "id = request.id;"
+ "}"
+"};");
Java gives error: The method executePhantomJS(String) is undefined for the type RemoteWebDriver.
If i use executeScript it will not work.
I need run 100 test parallel, i can't use webdriver.
I guess that you wanna run PhantomJSDriver on your Se Grid. This is how it works for me (C# Factory implementation):
public IWebDriver CreateWebDriver(string identifier)
{
if (identifier.ToLower().Contains("ghostdriver"))
{
return new RemoteWebDriver(new Uri(ConfigurationManager.AppSettings["Selenium.grid.Url"]), DesiredCapabilities.PhantomJS());
}
}
or try this one
Console.WriteLine("Creating GhostDriver (PhantomJS) driver.");
//Temporary commented for testing purposes
IWebDriver ghostDriver = new PhantomJSDriver("..\\..\\..\\MyFramework\\Drivers");
ghostDriver.Manage().Window.Maximize();
//ghostDriver.Manage().Window.Size = new Size(1920, 1080);
ghostDriver.Manage()
.Timeouts()
.SetPageLoadTimeout(new TimeSpan(0, 0, 0,
Convert.ToInt32(ConfigurationManager.AppSettings["Driver.page.load.time.sec"])));
return ghostDriver;
In case that you wonder why there is ConfigurationManager - I avoid the hard-coded values, so they are extracted from the App.config file.
If you want to run PhantomJS scripts with RemoteWebDriver (for using the Selenium Grid), I used the following solution (only C# unfortunately):
I had to extend the RemoteWebDriver so it can run PhantomJS commands:
public class RemotePhantomJsDriver : RemoteWebDriver
{
public RemotePhantomJsDriver(Uri remoteAddress, ICapabilities desiredCapabilities) : base(remoteAddress, desiredCapabilities)
{
this.CommandExecutor.CommandInfoRepository.TryAddCommand("executePhantomScript", new CommandInfo("POST", $"/session/{this.SessionId.ToString()}/phantom/execute"));
}
public Response ExecutePhantomJSScript(string script, params object[] args)
{
return base.Execute("executePhantomScript", new Dictionary<string, object>() { { "script", script }, { "args", args } });
}
}
After this you can use the ExecutePhantomJSScript method to run any JavaScript code that wants to interact with the PhantomJS API. The following example gets the page title trough the PhantomJS API (Web Page Module):
RemotePhantomJsDriver driver = new RemotePhantomJsDriver(new Uri("http://hub_host:hub_port/wd/hub"), DesiredCapabilities.PhantomJS());
driver.Navigate().GoToUrl("http://stackoverflow.com");
var result = driver.ExecutePhantomJSScript("var page = this; return page.title");
Console.WriteLine(result.Value);
driver.Quit();
I've been attempting to login to live.com with the Selenium Webdriver however every attempt results in an invalid email or password. A correct login is used. I tested it in a physical browser. I'm uncertain if this is the case but I believe sendkeys is not working. Code below.
protected static Map<String,String> settings = new HashMap<String,String>();
public static WebDriver pwb;
In Main:
// Default settings
settings.put("browser","chrome");
settings.put("os","WINDOWS8");
// Sort arguments and put into HashMap
grab(args);
// Set browser settings
DesiredCapabilities cap = DesiredCapabilities.htmlUnitWithJs();
cap.setBrowserName(settings.get("browser"));
cap.setPlatform(Platform.extractFromSysProperty(settings.get("os")));
d.log(cap.asMap().toString());
// Create web browser object
pwb = new HtmlUnitDriver(cap);
login();
In login():
Load("http://login.live.com",0); // custom load function
d.log(pwb.getTitle());
if(pwb.getTitle().contains("Sign in to your")){ // Full login
d.log("Executing full login.\nEmail:" + settings.get("email") + "\nPassword:"+settings.get("password"));
// if (pwb instanceof JavascriptExecutor) {
// ((JavascriptExecutor) pwb).executeScript("document.getElementsByName('login')[0].click();"); //value = " + settings.get("email") + "");
// ((JavascriptExecutor) pwb).executeScript("document.getElementsByName('passwd')[0].click();"); //.value = " + settings.get("password") + "");
// }
// TODO get login working
pwb.findElement(By.id("i0116")).clear();
pwb.findElement(By.id("i0116")).sendKeys(settings.get("email"));
pwb.findElement(By.id("i0118")).clear();
pwb.findElement(By.id("i0118")).sendKeys(settings.get("password"));
pwb.findElement(By.name("SI")).click();
// Attempted = true;
}
If anymore information is needed please let me know.
I am currently working in a requirement where I need to load the mysql driver runtime and connect to the database using java.
I am using URLClassLoader to load the jar file
File f = new File("D:/Pallavi/workspace/WarInstallation/mysql-connector-java-5.0.4-bin.jar"); //Jar path
URLClassLoader urlCl = new URLClassLoader(new URL[] { f.toURL()},System.class.getClassLoader());
Class sqldriver = urlCl.loadClass("com.mysql.jdbc.Driver"); // Runtime loading
Driver ds = (Driver) sqldriver.newInstance(); //Compilation failing as "sqldriver" class of type Driver is not found
//I am using now java.sql.Driver to remove the compilation error
sqldriver = Class.forName("com.mysql.jdbc.Driver", true, sqldriver.getClassLoader()).newInstance(); //Runtime fail.. "Driver" Class not Found Exception.
Although the class loads fine I can't establish a Database connection (No suitable driver found for ...) no matter which driver I try.
Please suggest a way to load the jdbc "com.mysql.jdbc.Driver" class runtime.
Let me know, if you need any further information, as this is urgent.
Thanks in advance.
I have three questions before I answer to your issues:
Statement 1:
ya, I have set the classpath of mysql jar in the environment variables, do we need to set it through system properties?
Q1: Why are to relying on custom class loader, when a class is readily available to the System class loader from the class path?
You don't need explicit class path to mysql***.jar to use custom class loader.
Statement 2:
Class sqldriver = urlCl.loadClass("com.mysql.jdbc.Driver"); // Runtime loading
//Compilation failing as "sqldriver" class of type Driver is not found
Driver ds = (Driver) sqldriver.newInstance();
Q2: Claiming Compilation failing ... is very conflicting. Is your compiler looking for such class to generate your class!?
I am sure it is not. May be the error is at run time with a java.lang.ClassNotFoundException: com.mysql.jdbc.Driver. And I also suspect the comment should go with your Statement 3 below.
If it is a CNFE, your file path to mysql***.jar is wrong. Fix it first.
Statement 3:
//I am using now java.sql.Driver to remove the compilation error
//Runtime fail.. "Driver" Class not Found Exception.
sqldriver = Class.forName("com.mysql.jdbc.Driver", true, sqldriver.getClassLoader()).newInstance();
Q3: Claiming ... "Driver" Class not Found Exception is suspectful. Because, this statement won't get compiled. Then how can it be a Runtime fail. ..!?
I also suspect the comment should go with your Statement 2 above.
And here, you need to call newInstance() and then cast to java.sql.Driver before assigning to sqlDriver variable. Because Class.forName( ... only returns a Class object associated with the class or interface with the given string name.
If issue at Statement 2 above is fixed, you can apply this fix to test further.
Let me hope you got these statements clarified.
I have a working sample code below, with a tested output shown for you.
import java.io.File; // and others as required
public class MySQLDriveClassLoader {
public static void main( String [] args ) throws Exception {
//File f = new File( "/home/ravinder/soft-dump/mysql-connector-java-5.1.18-bin.jar" );
File f = new File( "E:\\Soft_Dump\\mysql-connector-java-5.0.4\\mysql-connector-java-5.0.4-bin.jar" );
URLClassLoader urlCl = new URLClassLoader( new URL[] { f.toURI().toURL() }, System.class.getClassLoader() );
Class mySqlDriver = urlCl.loadClass( "com.mysql.jdbc.Driver" );
//*** Start: DEBUG *************************
//mySqlDriver.con // On pressing CTRL+SPACEBAR, after .con, IDE shows "No default proposals"
// meaning it still is not an instance of Driver, and hence can't call a method from Driver class.
//Incompatible conditional operand types Class and Driver
//System.out.println( mySqlDriver instanceof java.sql.Driver ) );
System.out.println( "mySqlDriver: " + mySqlDriver );
System.out.println( "Is this interface? = " + mySqlDriver.isInterface() );
Class interfaces[] = mySqlDriver.getInterfaces();
int i = 1;
for( Class _interface : interfaces ) {
System.out.println( "Implemented Interface Name " + ( i++ ) + " = " + _interface.getName() );
} // for(...)
Constructor constructors[] = mySqlDriver.getConstructors();
for( Constructor constructor : constructors ) {
System.out.println( "Constructor Name = " + constructor.getName() );
System.out.println( "Is Constructor Accessible? = " + constructor.isAccessible() );
} // for(...)
//*** End : DEBUG *************************
Driver sqlDriverInstance = ( Driver ) mySqlDriver.newInstance();
System.out.println( "sqlDriverInstance: " + sqlDriverInstance );
Connection con = null;
try {
/******************************************************************
// You may fail to register the above driver
// hence don't depend on DriverManager to get Connected
//DriverManager.registerDriver( sqlDriverInstance );
//Driver driver = DriverManager.getDriver( "com.mysql.jdbc.Driver" ); // ( "jdbc:mysql" );
Enumeration<Driver> enumDrivers = DriverManager.getDrivers();
while ( enumDrivers.hasMoreElements() ) {
Driver driver = enumDrivers.nextElement();
System.out.println( "driver: " + driver );
} // while drivers
//******************************************************************/
String dbUrl = "jdbc:mysql://:3306/test";
Properties userDbCredentials = new Properties();
userDbCredentials.put( "user", "root" );
userDbCredentials.put( "password", "password" );
// No suitable driver found for ...
//con = DriverManager.getConnection( dbUrl, "root", "password" );
// safely use driver to connect
con = sqlDriverInstance.connect( dbUrl, userDbCredentials );
System.out.println( "con: " + con );
Statement stmt = con.createStatement();
String sql = "select now()";
ResultSet rs = stmt.executeQuery( sql );
if ( rs.next() ) {
System.out.println( rs.getString( 1 ) );
} // if rs
} catch( Exception e ) {
e.printStackTrace(); // only for quick debug
} finally {
try { if ( con != null ) con.close(); } catch ( Exception ignoreThis ) {}
}
} // psvm(...)
} // class MySQLDriveClassLoader
A successful compilation and run, resulted following output:
mySqlDriver: class com.mysql.jdbc.Driver
Is this interface? = false
Implemented Interface Name 1 = java.sql.Driver
Constructor Name = com.mysql.jdbc.Driver
Is Constructor Accessible? = false
sqlDriverInstance: com.mysql.jdbc.Driver#1270b73
con: com.mysql.jdbc.Connection#32fb4f
2012-05-29 03:52:12.0
DriverManager ignores classes loaded at runtime, it will work only for classes loaded by the System class loader.
You can create a Dummy driver class which encapsulates your actual database driver. Source code can be found here.
Off topic:
File.toURL is deprecated, instead get URL from File using toURL on URI
URLClassLoader urlCl = new URLClassLoader(new URL[] { f.toURI().toURL()},System.class.getClassLoader());