Well always teach me this way of open and close connections from database, then i search more and more because this is very important for the performance of my application.
Here is my Class connection
public class Connection {
jdbc:oracle:thin:#//xxx.xx.x.xxx:xxxx/xxxxx.xxxxxx.xxxxx.xxx;
protected static Connection cn = null;
protected Connection getCn() {
return cn;
}
public static void setCn(Connection cn) {
Connection.cn = cn;
}
public ResultSet select(String sql) throws Exception {
ResultSet rs = null;
Statement st = null;
try {
st = this.getCn().createStatement();
rs = st.executeQuery(sql);
} catch (java.sql.SQLException e) {
throw e;
}
return rs;
}
public void insert(String sql) throws Exception {
Statement st = null;
try {
st = this.getCn().createStatement();
st.executeUpdate(sql);
} catch (java.sql.SQLException e) {
throw e;
}
}
public Connection connect() throws Exception {
try {
DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
setCn(DriverManager.getConnection(DBURL, "user", "password"));
} catch (java.sql.SQLException e) {
throw e;
}
return cn;
}
Well that was for my Connection Class, now here i have some others class that extends from my Connection class to bring me data from the DataBase.
public String checkMethod() throws Exception {
ResultSet rs;
String sql = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
try {
this.connect();
rs = this.select(sql);
while (rs.next()) {
//some data collect
}
rs.close(); //here is my dude because when may i can put the statement.close() line?
} catch (Exception e) {
throw e;
} finally {
this.cerrar();
}
return "success";
}
im using jsf and oracle, i think this snippet should be in my class Connection after the catch but generates me and error of the resulset is closed when i execute the method rs.next() and is logic because the statement must be close after the reading data of the resultSet, so how can i close the statement in my class Connection or in other place??? any suggestions? please help me
finally {
if (st != null) {
st.close();
}
}
A quick fix to the problem is:
finally {
try{ st.close(); }catch( Exception ex ) { /* do nothing*/ }
}
this prevents from throwing an error when something goes wrong with the statement in other places of the code ( st is null, st is closed etc.).
A more elegant solution might be creating a helper class with methods that close statements, resultsets etc. and hide exceptions that occur:
class DbCloser{
static void closeQuietly( Statement st ){
try{
st.close();
} catch( Exception ex ){
/* do nothing */
}
}
static void closeQuietly( ResultSet rs ){
try{
rs.close();
} catch( Exception ex ){
/* do nothing */
}
}
// .... etc.
}
and then use that helper class in finally blocks in code:
finally {
DbCloser.closeQuietly( st );
}
There is ready-made DbUtils package from Appache Commons that has already implemented such helper methods, just download this library and place it in the class-path, see this links for details:
http://commons.apache.org/proper/commons-dbutils/
http://commons.apache.org/proper/commons-dbutils/apidocs/index.html
And finally I would suggest to place close methods only in finnaly blocks:
try {
......
rs = this.select(sql);
.......
...........
// Do not close the statement here ......
// rs.close(); //here is my dude because when may i can put the statement.close() line?
} catch (Exception e) {
throw e;
} finally {
// ..... always close it here !!!
DbUtils.closeQuietly( st );
.........
}
i use this one
finally {
try{
if(st!=null){
st.close();
st=null;
}
}catch( Exception ex )
{
/* you can log this*/
}
}
Finally, I solved it like this:
public String checkMethod() throws Exception {
ResultSet rs;
String sql = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
try {
this.connect();
rs = this.select(sql);
while (rs.next()) {
//some data collect
}
rs.close();
rs.getStatement().close(); 'This works for me =)
} catch (Exception e) {
throw e;
} finally {
this.cerrar();
}
return "success";
}
Related
Java 8
import java.util.zip.GZIPOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
private void createFile(final String json) throws IOException {
final String fileName = getConfigFileName(this.getSomePath());
GZIPOutputStream out = null;
try {
out = new GZIPOutputStream(new FileOutputStream(fileName + ".gz"));
out.write(json.getBytes());
} catch (IOException e) {
throw e;
} finally {
try {
if (out != null) {
out.finish();
out.close();
}
} catch (IOException e) {
LOGGER.error("createFile: IOException while closing resources", e);
}
}
}
Nice. This work fine.
Now I want to use try-with-resource
private void createFile(final String json) throws IOException {
final String fileName = getConfigFileName(this.getSomeFile());
try (GZIPOutputStream out = new GZIPOutputStream(new FileOutputStream(fileName + ".gz"))) {
out.write(json.getBytes());
} catch (IOException e) {
throw e;
} finally {
try {
if (out != null) {
out.finish();
}
} catch (IOException e) {
LOGGER.error("createFile: IOException while closing resources", e);
}
}
}
But now I get error in this line:
if (out != null) {
Error is:
out cannot be resolved
I know this error is rise because variable out is on finally section.
But how I can use try-with-resources and execute method out.finish ?
From a technical perspective - a variable declared in the try argument isn't available in the finally clause, as you've seen. The good news here is that from a function perspective - finish() shouldn't be in the finally block anyway. finish is part of the positive (a.k.a "happy") flow, and should only be called when you're done writing to the stream. In other words, if the write operation failed and an exception was thrown, you shouldn't call finish anyway.
To make a long story short - move the finish call inside the try block:
Side note: Since your method throws an IOException, there's no reason to catch the exception and rethrow it. You can clean up the code by allowing it to be thrown from the method call directly:
private void createFile(final String json) throws IOException {
final String fileName = getConfigFileName(this.getSomeFile());
try (GZIPOutputStream out = new GZIPOutputStream(new FileOutputStream(fileName + ".gz"))) {
out.write(json.getBytes());
out.finish();
}
}
So i hava an oracle functiion like: function unbind (ids in id_table). It takes an array of ids to perform some updates on my database.
The question is how can I run my function in order to perform update operations?
What I've alreade tried:
1. Query query = getSession().createSQLQuery("call UNBIND(:ids)");
query.setParameter("ids", myIds);
query.executeUpdate();
but I got ora-06576 not a valid function or procedure name
Query query = getSession().createSQLQuery("execute UNBIND(:ids)");
query.setParameter("ids", myIds);
query.executeUpdate();
finish with ora-00900 invalid sql statement
Long [] myArray = movedIds.toArray(new Long[movedIds.size()]);
Boolean result = getSession().doReturningWork(new ReturningWork<Boolean>() {
#Override
public Boolean execute(Connection connection) throws SQLException {
CallableStatement callableStatement = connection.prepareCall("{ ? = call UNBIND(:ids)");
callableStatement.registerOutParameter(1, Types.INTEGER);
callableStatement.setArray(2, connection.createArrayOf("id_table", myArray));
callableStatement.execute();
return !(callableStatement.getInt(1) == 0);
}
});
finishes with java.sql.sqlfeaturenotsupportedexception unsupported feature
The app conects to the database via jboss, so I suppose that could be the problem in p. 3?
SELECT
UNBIND( id_table (6271789) ) FROM DUAL
does not work because my function performs updates...
Anyway is there any other method to run a function that takes an array as a parameter directly from java code?
here is a simple example, does this help?
import java.sql.*;
public class Class1 {
public static void main(String[] args) throws SQLException {
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Connection conn = null;
try {
conn = DriverManager.getConnection(
"jdbc:oracle:thin:#//localhost/orcl","scott","tiger");
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String query = "{ ? = call test_func(?) }";
CallableStatement cs = null;
try {
cs = conn.prepareCall(query);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
int inVal = 0;
cs.setInt(2, inVal);
cs.registerOutParameter(1, oracle.jdbc.OracleTypes.NUMBER);
cs.executeUpdate();
int res = cs.getInt(1);
System.out.println("result is " + res);
}
}
I'm using this library(https://github.com/rdavisau/sockets-for-pcl) to communicate with a TCP Server, that sends me when a event was generated, then, I have to verify all the time if the TCP Server sent to me a event, but if I try read anything before the TCP Server sends me, it's thrown the UnhandledException, but it only happens if I read inside a Task, in the main thread it thrown a timeout exception, the exception that I expected to happen in Task.
Someone can help me? Thanks. below is my code.
public class CentralTcpService
{
#region ConnectTcpAsync
public async void ConnectTcpAsync()
{
try
{
_sockecClient = new TcpSocketClient();
await _sockecClient.ConnectAsync(Central.Ip, Central.Port);
_writter = new ExtendedBinaryWriter(_sockecClient.WriteStream);
_reader = new ExtendedBinaryReader(_sockecClient.ReadStream);
_writter.WriteString(EvenNotProtocol.MobileReceiverCommand);
_sockecClient.ReadStream.ReadTimeout = int.MaxValue;
EnableTcpService();
}
catch (Exception e)
{
throw new Exception(e.Message);
}
}
#endregion
#region TcpService
private void EnableTcpService()
{
_cancelationTcpService = new CancellationTokenSource();
new Task(StartService, _cancelationTcpService.Token, TaskCreationOptions.LongRunning).Start();
}
private void StartService()
{
while (!_cancelationTcpService.Token.IsCancellationRequested)
{
var ev = EvenNotProtocol.DeserializeEvent(_reader);
if (ev == null) continue;
_writter.WriteString(EvenNotProtocol.MobileOkCommand);
EventReceived?.Invoke(this, new CentralTcpEventArgs(ev));
}
}
}
public class EvenNotProtocol
{
public static Event DeserializeEvent(ExtendedBinaryReader reader)
{
try
{
reader.SkipBytes(1);
.....
}
catch (IOException e)
{
return null;
}
}
}
I tried with the below linked steps:
https://slobaray.com/tag/execute-shell-script-from-plsql/
It consists in
creating a java object stored as BASH_OS function with
CREATE OR REPLACE AND COMPILE JAVA SOURCE NAMED "BASH_OS"..
Then to execute the java with
CREATE OR REPLACE PROCEDURE unix_command (p_command IN VARCHAR2)
AS LANGUAGE JAVA
NAME 'BASH_OS.executeCommand (java.lang.String)';
But It shows that
the object BASH_OS does not exist.
Can any one help me on how we can execute the shell script from the Toad with this method?
or Is there any other method to call shell script from Toad?
Referring your link, I found that the class name in line 13 is wrong for creating BASH_OS.
The class name should be "BASH_OS" instead of "Host". Since there is no comment feature on the blog, so i copy the fixed code here.
CREATE OR REPLACE AND COMPILE JAVA SOURCE NAMED "BASH_OS" AS
/******************************************************************************
NAME: BASH_OS
PURPOSE: To perform the shell command using Java class
REVISIONS:
Ver Date Author Description
--------- ---------- ------ ---------------------------------------------
0.1 <<>> S.Ray Initial Version
******************************************************************************/
import java.io.*;
/* public class Host { <-- THIS IS WRONG */
public class BASH_OS {
public static void executeCommand(String command) {
try {
String[] finalCommand;
{
finalCommand = new String[3];
finalCommand[0] = "/bin/sh";
finalCommand[1] = "-c";
finalCommand[2] = command;
}
final Process pr = Runtime.getRuntime().exec(finalCommand);
pr.waitFor();
new Thread(new Runnable(){
public void run() {
BufferedReader br_in = null;
try {
br_in = new BufferedReader(new InputStreamReader(pr.getInputStream()));
String buff = null;
while ((buff = br_in.readLine()) != null) {
System.out.println("Process out :" + buff);
try {Thread.sleep(100); } catch(Exception e) {}
}
br_in.close();
}
catch (IOException ioe) {
System.out.println("Exception caught printing process output.");
ioe.printStackTrace();
}
finally {
try {
br_in.close();
} catch (Exception ex) {}
}
}
}).start();
new Thread(new Runnable(){
public void run() {
BufferedReader br_err = null;
try {
br_err = new BufferedReader(new InputStreamReader(pr.getErrorStream()));
String buff = null;
while ((buff = br_err.readLine()) != null) {
System.out.println("Process err :" + buff);
try {Thread.sleep(100); } catch(Exception e) {}
}
br_err.close();
}
catch (IOException ioe) {
System.out.println("Exception caught printing process error.");
ioe.printStackTrace();
}
finally {
try {
br_err.close();
} catch (Exception ex) {}
}
}
}).start();
}
catch (Exception ex) {
System.out.println(ex.getLocalizedMessage());
}
}
};
Here is the stack trace:
java.sql.SQLException
at org.apache.tomcat.jdbc.pool.PooledConnection.connectUsingDriver(PooledConnection.java:290)
at org.apache.tomcat.jdbc.pool.PooledConnection.connect(PooledConnection.java:182)
at org.apache.tomcat.jdbc.pool.ConnectionPool.createConnection(ConnectionPool.java:702)
at org.apache.tomcat.jdbc.pool.ConnectionPool.borrowConnection(ConnectionPool.java:634)
at org.apache.tomcat.jdbc.pool.ConnectionPool.init(ConnectionPool.java:488)
at org.apache.tomcat.jdbc.pool.ConnectionPool.<init>(ConnectionPool.java:144)
at org.apache.tomcat.jdbc.pool.DataSourceProxy.pCreatePool(DataSourceProxy.java:116)
at org.apache.tomcat.jdbc.pool.DataSourceProxy.createPool(DataSourceProxy.java:103)
at org.apache.tomcat.jdbc.pool.DataSourceProxy.getConnection(DataSourceProxy.java:127)
at com.boeing.DBReader.Server.makeConnection(Server.java:85)
at com.boeing.DBReader.Server.<init>(Server.java:26)
at com.boeing.DBReader.Reader.main(Reader.java:13)
Caused by: java.lang.NullPointerException
at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:395)
at org.apache.tomcat.jdbc.pool.PooledConnection.connectUsingDriver(PooledConnection.java:278)
... 11 more
Connection closed
And here is the code:
public class Server
{
private DataSource datasource;
public Server()
{
try
{
createConnectionToDatabase();
} catch (Exception e)
{
// TODO Auto-generated catch block
System.out.println("Exception:" + e.toString());
}
makeConnection();
}
private void createConnectionToDatabase() throws Exception
{
String connectionString = null;
String login = null;
String password = null;
System.out.println("In createConnectionToDatabase");
PoolProperties p = new PoolProperties();
p.setUrl("jdbc:oracle:thin:#***");
p.setUrl(connectionString);
p.setDriverClassName("oracle.jdbc.OracleDriver");
p.setUsername("**");
p.setPassword("**");
p.setJmxEnabled(true);
p.setTestWhileIdle(false);
p.setTestOnBorrow(true);
p.setValidationQuery("SELECT 1 from dual");
p.setTestOnReturn(false);
p.setValidationInterval(30000);
p.setTimeBetweenEvictionRunsMillis(30000);
p.setMaxActive(100);
p.setInitialSize(10);
p.setMaxWait(10000);
p.setRemoveAbandonedTimeout(600);
p.setMinEvictableIdleTimeMillis(30000);
p.setMinIdle(10);
p.setLogAbandoned(true);
p.setRemoveAbandoned(true);
p.setJdbcInterceptors("org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;"
+ "org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer");
datasource = new DataSource();
datasource.setPoolProperties(p);
}
private void closeConnection(Connection con) {
if (con != null) {
try {
con.close();
} catch (Exception ignore) {
System.out.println("Could not close connection, WTF?");
}
}
}
private void makeConnection()
{
Connection con = null;
String queryString = "SQL QUERY GOES HERE ";
try {
System.out.println("Connection attempt");
con = datasource.getConnection();
System.out.println("Connection made no issues");
} catch (Exception e) {
System.out.println("Exception:" + e.toString());
e.printStackTrace();
} finally {
closeConnection(con);
System.out.println("Connection closed");
}
}
I have the driver attached to the build path.. What am I doing wrong? This is set up without maven, and just a normal java project.
Thanks!
Not entirely sure from the stack trace, but this looks wrong:
String connectionString = null;
String login = null;
String password = null;
System.out.println("In createConnectionToDatabase");
PoolProperties p = new PoolProperties();
p.setUrl("jdbc:oracle:thin:#***");
p.setUrl(connectionString);
You're setting the URL to connectionString, which is null.