JDBC + ScriptRunner : error with runScript - java

I want to use ScriptRunner to execute a sql script file with a JDBC driver.
I can initiate ScriptRunner but I can't execute the runScript line :
ScriptRunner runner = new ScriptRunner(c, false, false);
runner.runScript("C:/Users/Pierre/Documents/create.sql");
The error is :
cannot find symbol method
runScript(java.lang.String) || line 41
The connection with the database is fine.
import java.sql.*;
public class ConnectPostgreSQL {
public static void main(String[] argv) {
System.out.println("Checking if Driver is registered with DriverManager.");
try {
Class.forName("org.postgresql.Driver");
} catch (ClassNotFoundException cnfe) {
System.out.println("Couldn't find the driver!");
System.out.println("Let's print a stack trace, and exit.");
cnfe.printStackTrace();
System.exit(1);
}
System.out.println("Registered the driver ok, so let's make a connection.");
Connection c = null;
try {
// The second and third arguments are the username and password,
// respectively. They should be whatever is necessary to connect
// to the database.
c = DriverManager.getConnection("jdbc:postgresql://localhost:5432/postgres", "postgres", "passroot");
} catch (SQLException se) {
System.out.println("Couldn't connect: print out a stack trace and exit.");
se.printStackTrace();
System.exit(1);
}
if (c != null)
System.out.println("Hooray! We connected to the PostgreSQL database!");
else
System.out.println("We should never get here.");
//temps t1
long begin = System.currentTimeMillis();
System.out.println(begin);
ScriptRunner runner = new ScriptRunner(c, false, false);
runner.runScript("C:/Users/Pierre/Documents/create.sql");
//temps t2
long end = System.currentTimeMillis();
System.out.println(end);
//différence de t2 - t1
float time = ((float) (end-begin)) / 1000f;
System.out.println(time);
}
}
Can somebody help me ?
Thanks !

It's because runScript method hasn't in argument String, look to ScriptRunner code
public void runScript(Reader reader)
Change your
runner.runScript("C:/Users/Pierre/Documents/create.sql");
To:
try {
FileReader reader = new FileReader("C:/Users/Pierre/Documents/create.sql");
runner.runScript(reader);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
and add imports like
import java.io.BufferedReader;
import java.io.FileReader;

The runScript method of ScriptRunner takes a Reader as an argument, so you need to change line 41 to
try {
runner.runScript(new BufferedReader(new FileReader("C:/Users/Pierre/Documents/create.sql")));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
and add imports like
import java.io.BufferedReader;
import java.io.FileReader;

ScriptRunner send line by line to DB. When the script has a delimiter ($$, &&, ||), the line is automatically executed. To fix this, you need to use the last version of ScriptRunner and set to send full script (runner.setSendFullScript(true)).

Related

How to use ResultSet returned by java method in SOAPUI with groovy script?

We have created jar file for a java method and imported it in SOAPUI. We are able to call method, however not able to retrieve query result returned in ResultSet by java method in groovy script def dataRow = GetData.GetRecords(preQuery). I am new to groovy script.
Below is method we have written in java and created jar for it.
package getRecords;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class GetData {
protected static Connection con = null;
protected static Statement stmt = null;
protected static ResultSet result = null;
//Opening DB connection
public static void OpenDBConnection(String dbUrl, String driver, String username, String password){
//Making connection to DB
try {
Class.forName(driver);
con = DriverManager.getConnection(dbUrl, username, password);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//Closing DB connection
public static void CloseDBConnection(){
try {
//Closing DB connection
con.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//Executing query and fetching data from DB
public static ResultSet GetRecords(String query){
//Executing query and saving result into result set
try {
stmt = con.createStatement();
result = stmt.executeQuery(query);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return result;
}
public static void main(String args[]){
System.out.println("DBConnection..");
GetData gd = new GetData();
GetData.OpenDBConnection("jdbc:oracle:thin:#test:1530/test", "oracle.jdbc.driver.OracleDriver", "******", "******");
System.out.println("DB");
}
}
I suspect your result set is being closed when you return from GetRecords (tip: use camel case for Java method names, starting with a lower-case character) and you may also be jumping JVMs. See also Is it Ok to Pass ResultSet?.
You probably don't need to use your result set as a result set back in soapUI, you just want the data, so a better option would be to populate a bean and return a List of those instead:
public static List<MyBean> GetRecords(String query){
List<MyBean> myBeans = new ArrayList<>();
//Executing query and saving result into result set
try {
stmt = con.createStatement();
result = stmt.executeQuery(query);
while (result.next()) {
MyBean myBean = new MyBean();
// Populate the bean...
myBeans.add(myBean);
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return myBeans;
}
You might also want to investigate the try-with-resources feature that came out with Java 7: it'll handle the closing of your connections automatically.
In SoapUi you can directly do the JDBC call using Groovy scripting.
If you wanted to do some Database operation in soapUI you can write the code in groovy using the corresponding database driver ( DB2, Oracle, Mysql), Until or unless any specific reason to use jar file as you have mentioned.
Making the database connection you need to download and place the jar files inside ( SoapUi install folder/bin/ext
eg.. for Oracle (ojdbc6.jar, orai18n.jar)

Why different issues are found when using different versions of SonarQube?

I'm testing sonar in order to ensure the closing database connections and I'm having extrange results I don't understand.
I'm trying two versions of the code executing the maven goal "sonar:sonar" from eclipse with the embeded maven version 3.3.9.
I've tried with three versions of sonarqube server: 5.6.6, 6.2 and 6.4.
With this code
package db;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import javax.naming.InitialContext;
import javax.sql.DataSource;
public class TestClosingResources {
public static void main(String[] args) {
Connection con = null;
ResultSet rsGet = null;
PreparedStatement psGet = null;
try {
DriverManager.registerDriver (new com.mysql.jdbc.Driver());
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "test", "test");
psGet = con.prepareStatement("SELECT * FROM TEST");
rsGet = psGet.executeQuery();
int counter = 0;
while (rsGet.next()) {
counter++;
System.err.println(counter);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (rsGet != null) {
rsGet.close();
}
} catch (Exception e2) {
e2.printStackTrace();
}
rsGet = null;
try {
if (psGet != null) {
psGet.close();
}
} catch (Exception e2) {
e2.printStackTrace();
}
psGet = null;
}
}
}
I have these issues about closing resources:
sonarqube 5.6.6:
Close this "Connection"
Close this "PreparedStatement"
sonarqube 6.2:
Close this "Connection"
Close this "PreparedStatement"
sonarqube 6.4:
Close this "Connection"
My question with this code is:
Why does 5.6.6 and 6.2 complain about PreparedStatement when it's
closed exactly the same than the ResultSet?
And whith this code (only changes the way I retrieve the connection, it doesn't matter if it would work or not)
package db;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import javax.naming.InitialContext;
import javax.sql.DataSource;
public class TestClosingResources {
public static void main(String[] args) {
Connection con = null;
ResultSet rsGet = null;
PreparedStatement psGet = null;
try {
InitialContext ctx = new InitialContext();
DataSource ds = (DataSource)ctx.lookup("java:comp/env/jdbc/testci");
con = ds.getConnection();
psGet = con.prepareStatement("SELECT * FROM TEST");
rsGet = psGet.executeQuery();
int counter = 0;
while (rsGet.next()) {
counter++;
System.err.println(counter);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (rsGet != null) {
rsGet.close();
}
} catch (Exception e2) {
e2.printStackTrace();
}
rsGet = null;
try {
if (psGet != null) {
psGet.close();
}
} catch (Exception e2) {
e2.printStackTrace();
}
psGet = null;
}
}
}
sonarqube 5.6.6:
Close this "PreparedStatement"
sonarqube 6.2:
Close this "PreparedStatement"
sonarqube 6.4:
no issues about closing resources
My questions with this code are:
Why does 5.6.6 and 6.2 complain about PreparedStatement when it's
closed exactly the same than the ResultSet?
Why doesn't any version complain about not closing the connection?
Thanks
The reason why some issues are not detected in more recent versions is due to the fact that static analyzer doing the analysis was improved.
Plugin used for Java source code analysis is called SonarJava, and it has independent release cycle than SonarQube. You should always use the latest release to obtain best results. Use update center on your SonarQube server to update to the latest available release.

Creating Connection Method Within The Class Is Valid or Not in Java

I am developing an application using Swing, so before starting up I need to know a few basics regarding working with Connection. In many tutorials, I have seen that we need to create a connection Class and get the connection within the project using getConnection().
But I have created a connectionMethod is it possible to get the connection in my entire project by creating object of the connection class and using the connection?
This is my code:
package ncl;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class Test {
Connection connection=null;
public void connectionMethod() {
try {
Class.forName("org.h2.Driver");
connection=DriverManager.getConnection("jdbc:h2:~/test","sa", "");
} catch (ClassNotFoundException | SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args) {
new Test().connectionMethod();
try {
// DO STUFF HERE
} catch (Exception e) {
// TODO: handle exception
}finally {
try {
new Test().connection.close();
} catch (Exception e2) {
// TODO: handle exception
}
}
}
}
I want to know whether this approach is good or not.
This totally depends on the practitioner that how he/she wants to code. Ideally we should follow Design Patterns in implementation to achieve many properties like Low Coupling, High Cohesion etc.
You told that in many tutorials, they make separate class which only provides connection. It is a good practice to avoid the problem of dependency and we can allocate responsibility to the classes in more efficient way. So you should also do it by creating new class which only provides the connection.
For the mentioned code, you have made some mistakes. You have first taken an instance of Test class which has connection and you didn't assign it to any variable. So you can't use it further when you need the connection. Another mistake is that you try to close the connection by creating another instance of Test class which obviously doesn't have started connection.
So, you can make appropriate suggested changes.
ConnectionFactory.java :
This will provide the connection objects.
package ncl;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class ConnectionFactory {
Connection connection=null;
public void connectionMethod() {
try {
Class.forName("org.h2.Driver");
connection=DriverManager.getConnection("jdbc:h2:~/test","sa", "");
} catch (ClassNotFoundException | SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Test.java :
Write the actual code here.
package ncl;
import java.sql.SQLException;
public class Test {
public static void main(String[] args) {
ConnectionFactory connectionObject = new ConnectionFactory();
connectionObject.connectionMethod();
try {
// DO STUFF HERE
} catch (Exception e) {
// TODO: handle exception
}finally {
try {
connectionObject.connection.close();
} catch (Exception e2) {
// TODO: handle exception
}
}
}
}
You can use below utility class :
public class MyConnection {
private Connection con = null;
public Connection getConnection() {
try {
if (con == null) {
Class.forName("org.h2.Driver");
con = DriverManager.getConnection("jdbc:h2:~/test", "sa", "");
}
} catch (Exception e) {
e.printStackTrace();
}
return con;
}
}
For getting connection you can call MyConnection().getConnection();
For example :
If you want to get connection in any class then do the following :
Connection con = new MyConnection().getConnection();

Output issue whilst using a try statement in JSP

My .jsp files are not outputting characters when I use out.println inside a try statement. For example:
out.println("testing123");
try {
connectionDB = DriverManager.getConnection(DATABASE_URL, userDB, passDB);
psDB = connectionDB.prepareStatement(sql);
rsDB = psDB.executeQuery();
out.println("hello");
while(rsDB.next()){
out.println("yay");
}
} catch (Exception errorMessage) {
}
It will output "testing123" to the page but It will not output "hello" why is this, and how do I fix this? All help is appreciated. Remember this is a .jsp page.
You seems to be eating the exception in your try/catch. It seems there is some exception happening in your try block and execution is not reaching to the statement
out.println("hello");
Try to print the stacktrace and correct the code so that execution is successful.
This works so you must have Exception in your Database code.
try{
out.println("hello there!");
}
catch(Exception e ){
e.printStackTrace();
}
I think you have error in your Database code.
try this code
import java.sql.Connection;
import java.sql.Statement;
import java.sql.ResultSet;
............................
......
...
..
.
try {
connectionDB = DriverManager.getConnection(DATABASE_URL, userDB, passDB);
stmt = connectionDB.createStatement();
rs = psDB.executeQuery("SELECT * from tblpost");
while(rs.next()){
out.println(rs.getString("column_Name"));
}
} catch (Exception errorMessage) {
out.println("error");
}
if you find it hard try to watch this Database Connection and JSP Display

Multi-threaded Oracle Update in Java

I've written code which parses a file which contains MAC Addresses and Flag values to be updated in an Oracle table. However, since this process will be run on thousands of record I wish to split up the workload and update the database simultaneously. I am unsure of the best way to implement this as I am a beginner at concurrency. I've been reading up and looking at sample code, but it is still very ambiguous and unclear to me.
My first idea was to split the list into 10 segments but it became overcomplicated and convoluted with Lists of Lists and the sort...
I'm just looking for a nudge in the right direction...
Attached is my current code:
import java.io.*;
import java.util.*;
import java.text.ParseException;
import java.text.ParseException;
import java.lang.String;
import java.sql.*;
import java.lang.Class;
import oracle.jdbc.*;
import oracle.jdbc.driver.OracleDriver;
public class Process{
public FlagProcess(){
running = false;
}
public static List<String> readFile(String filename) throws IOException {
BufferedReader macAddresses = null;
List<String> info = new ArrayList<String>();
try {
macAddresses = new BufferedReader(new FileReader(filename));
String line = null;
while ((line = macAddresses.readLine()) != null) {
//Process the data, here we just print it out
System.out.println(line);
String[] bufferArray = line.split("\\|");
String mac = bufferArray[0];
String value = bufferArray[1];
System.out.println("MAC: " + mac);
System.out.println("PPV Value: " + value);
info.add(mac);
info.add(value);
}
} catch (FileNotFoundException ex) {
ex.printStackTrace();
} finally {
//Close the BufferedReader
try {
if (macAddresses != null)
macAddresses.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
return info;
}
public static Connection getConnection() throws SQLException,ClassNotFoundException{
DriverManager.registerDriver(new oracle.jdbc.OracleDriver());
String URL = "jdbc:oracle:thin://#xxxxxxxxxx:1521:xxxxxx";
Connection conn = DriverManager.getConnection(URL, "username", "password");
System.out.println("Connection established...");
return conn;
}
public static void freeConnection(Connection conn) throws SQLException {
try {
if (conn != null) {
conn.setAutoCommit(true);
}
} finally {
if (conn != null) {
try {
conn.close();
} catch (Exception e) {
System.out.println("FlagProcess.freeConnection() - got exception while closing connection.");
e.printStackTrace();
}
}
}
}
public static synchronized void updateDatabase(String mac, String value, Connection conn) throws SQLException
{
String update = "UPDATE device set FLAG = ? where IDENTIFICATION = ?";
System.out.println(update);
try{
PreparedStatement pstmt = conn.prepareStatement(update);
pstmt.setString(1, value);
pstmt.setString(2, mac);
int x = pstmt.executeUpdate();
System.out.println("Update complete.");
}
catch(Exception e)
{
e.printStackTrace();
}
finally{
freeConnection(conn);
}
}
public static void main(String [] args){
PPVFlagProcess pfp = new PPVFlagProcess();
try{
List<String> info= readFile("values");
String mac = info.get(0);
String value = info.get(1);
Connection conn = pfp.getConnection();
pfp.updateDatabase(mac, value, conn);
pfp.freeConnection(conn);
}
catch(Exception e){
e.printStackTrace();
}
}
}
Any help would be greatly appreciated, Thank you.
This sounds like premature optimization to me. With the concurrent approach you would increase performance on the client side. But I would expect your bottleneck to be on the database side (network, database cpu, lock contention, disc io). With the concurrent approach this could even result in worse performance.
So if you want to get this stuff fast I would look into sqlldr and stuff.
And before anything: Get a simple solution working and then look for the bottleneck.
I can't see any concurrency in your code, if you want a better performance, set batch size on your prepared statement, and execute statements once a while (for example after 20 records).
If you worry about the performance of your code, start with getting rid of the autocommit. You explicitly set it to true (the (cruel) default). Your code will already be a lot faster by setting autocommit to false.
Next thing to do is to use bulk loading. See 23 Performance Extensions, use the Oracle way to perform batches, not the standard way. Do this and you may ask yourself: why did I do it so difficult.
In Oracle there are a few
things not to do:
autocommit
connect/disconnect for every small element of work
use dynamic (unprepared) SQL
I think, you are slowing down the hole thing, by executing it multithreaded. Use prepared statements and a batchupdate instead.
The System.out are a bad idea, if performance is important.

Categories