How to show Oracle DB Tables on my JDeveloper Swing projects frame? - oracle

I want to show my Oracle DB tables on my application. I create a new database connection DBConnection1. But I don't bind DBConnection1 in my class. How to do it?

OK. I solve my question.
DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
Connection connection = DriverManager.getConnection(connStr,"scott","tiger");
Connector conn = new Connector(connStr);
Statement stmt = conn.getConnection().createStatement();
ResultSet rset = stmt.executeQuery(sql);
ResultSetMetaData metaData = rset.getMetaData();
int rowCount = metaData.getColumnCount();
for(i=1;i<=rowCount;i++)
headers.add(metaData.getColumnLabel(i).toString());
while(rset.next()){
Vector tmp = new Vector();
for(i=1;i<=rowCount;i++) {
tmp.add(rset.getString(i));
}
lists.add(tmp);
index++;
Here is the my connector class.
package client;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
public class Connector
{
private String connection_string;
private Statement stmt;
private Connection connection;
public Connector(String conn)
{
//String connection_string = "jdbc:oracle:thin:#<host>:<port>:<db name>";
try
{
connection_string = conn;
DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
connection = DriverManager.getConnection(conn,"scott","tiger");
} catch(Exception f)
{
f.printStackTrace();
}
}
public ResultSet execute(String sql)
{
try
{
stmt = connection.createStatement();
return stmt.executeQuery(sql);
} catch (Exception f)
{
f.printStackTrace();
}
return null;
}
public void setConnection_string(String connection_string)
{
this.connection_string = connection_string;
}
public String getConnection_string()
{
return connection_string;
}
public void setStmt(Statement stmt)
{
this.stmt = stmt;
}
public Statement getStmt()
{
return stmt;
}
public void setConnection(Connection connection)
{
this.connection = connection;
}
public Connection getConnection()
{
return connection;
}
}

Related

Oracle Change Notification not firing when table changes

First time trying to do something like this and I'm not sure what I am missing?
My code:
package SQLOCpackage;
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import oracle.jdbc.OracleConnection;
import oracle.jdbc.OracleStatement;
import oracle.jdbc.dcn.DatabaseChangeEvent;
import oracle.jdbc.dcn.DatabaseChangeListener;
import oracle.jdbc.dcn.DatabaseChangeRegistration;
import oracle.jdbc.dcn.RowChangeDescription;
import oracle.jdbc.dcn.TableChangeDescription;
#SuppressWarnings("serial")
public class SQLONframe extends JFrame {
String URL = "jdbc:oracle:thin:#xxxxx.xxxxx.xx.xxxx:1521:xxxxx";
Properties prop;
private JPanel contentPane;
static String PW = "xxxxxxxx";
static String UN = "xxxxxxxx";
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
SQLONframe frame = new SQLONframe();
frame.setVisible(true);
SQLONframe dcn = new SQLONframe();
try {
dcn.prop = new Properties();
dcn.prop.setProperty("user", UN);
dcn.prop.setProperty("password", PW);
dcn.run();
}
catch(Exception e) {
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public SQLONframe() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
contentPane.setLayout(new BorderLayout(0, 0));
setContentPane(contentPane);
}
void run() throws SQLException {
OracleConnection conn = (OracleConnection)DriverManager.getConnection(URL,prop);
DatabaseChangeRegistration dcr = null;
Properties prop = new Properties();
prop.setProperty(OracleConnection.DCN_QUERY_CHANGE_NOTIFICATION,"true");
try {
dcr = conn.registerDatabaseChangeNotification(prop);
dcnListener list = new dcnListener(this);
dcr.addListener(list);
Statement stmt = conn.createStatement();
((OracleStatement)stmt).setDatabaseChangeRegistration(dcr);
ResultSet rs = stmt.executeQuery("select script_name, current_status, Issues_found_during_run, Testers, tools from ALLDATA WHERE ID = 1");
while (rs.next())
{
}
String[] tableNames = dcr.getTables();
for(int i=0;i<tableNames.length;i++)
System.out.println(tableNames[i]+" is part of the registration.");
rs.close();
stmt.close();
}
catch(Exception e) {
//clean up our registration
if(conn != null)
conn.unregisterDatabaseChangeNotification(dcr);
e.printStackTrace();
}
finally {
try {
conn.close();
}
catch(Exception e){
e.printStackTrace();
}
}
try {
Thread.currentThread().join();
}
catch (Exception e) {
e.printStackTrace();
}
finally {
OracleConnection conn3 = (OracleConnection)DriverManager.getConnection(URL,prop);
conn3.unregisterDatabaseChangeNotification(dcr);
conn3.close();
}
}
class dcnListener implements DatabaseChangeListener {
SQLONframe dcn;
dcnListener(SQLONframe dem) {
dcn = dem;
}
public void onDatabaseChangeNotification(DatabaseChangeEvent e) {
TableChangeDescription[] tc = e.getTableChangeDescription();
for (int i = 0; i < tc.length; i++) {
RowChangeDescription[] rcds = tc[i].getRowChangeDescription();
for (int j = 0; j < rcds.length; j++) {
System.out.println(rcds[j].getRowOperation() + " " + rcds[j].getRowid().stringValue());
}
}
synchronized( dcn ){
dcn.notify();
}
}
}
}
I can see that it does register the Change Notification but when I go and change something in that table and commit it I never get anything on the code side saying something has changed?
Any help would be great!
update
Using
SELECT * from USER_CHANGE_NOTIFICATION_REGS
I do get a reg back when doing that query in SQL Developer:
And the ojdbc8.jar version info is:
Oracle 18.3.0.0.0 JDBC 4.2 compiled with javac 1.8.0_171 on
Tue_Jun_26_11:06:40_PDT_2018
Default Connection Properties Resource
Tue Mar 12 10:06:48 EDT 2019
and this is the Oracle SQL Developer status:
Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production
PL/SQL Release 12.2.0.1.0 - Production
"CORE 12.2.0.1.0 Production"
TNS for Linux: Version 12.2.0.1.0 - Production
NLSRTL Version 12.2.0.1.0 - Production
and with my program running and the query registered this is what I see for ports:

Oracle : Send latest insert/update to JMS

I have an insert/update trigger for a Oracle table.
Is there a way to send the details of the affected row(all columns) as a message to JMS?
I can write a Java Program, 'loadjava' that and call from the trigger.
Does this way affect performance?
Is there any native way of achieving this?
There is indeed a native way: use AQ JMS from PL/SQL, see https://docs.oracle.com/database/121/ADQUE/jm_exmpl.htm#ADQUE1600. In short you create an AQ queue with a JMS payload type; then you can post messages with PL/SQL from the trigger. An external Java client can connect to the database and read the messages with JMS.
I don't know how much a call into Java would affect performance, but I try to avoid it. It was a nice idea but it never really caught on, so it remains a fringe case and at least early on there were always issues. PL/SQL on the other hand works.
If you need to send data to another message queue product (tags activemq and mq) you can read the messages in Java and forward them. It adds an extra step, but it is straightforward.
loadjava have many problems and not stable if there is many classes loaded and many business, take a look Calling Java from Oracle, PLSQL causing oracle.aurora.vm.ReadOnlyObjectException
Oracle AQ as i know is not free.
I have implemented the same need after trying many possibilities by creating only 1 class loaded to oracle with loadjava which is called as a procedure by a trigger and have the responsability to call an external java program with all needed parameters and log external process output to a table, as below.
i have encoded text mesage to BASE64 because i used JSON format and some specials caracters can causes problems as a parameters to external java program.
i have used "#*#jms_separator#*#" as a separator in the sent parameter string to parse the content if i need to send many parameters to the external program.
the whole duration of ShellExecutor.shellExec is around 500ms and running since 1 year without any problem.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.sql.Clob;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.util.Arrays;
import java.util.concurrent.FutureTask;
import sun.misc.BASE64Encoder;
public class ShellExecutor {
static {
System.setProperty("file.encoding", "UTF-8");
}
private static final String INSERT_LOGS_SQL = "INSERT INTO JMS_LOG (TEXT_LOG) VALUES (?) ";
private static final String DEFAULT_CONNECTION = "jdbc:default:connection:";
public static String SQLshellExec(String command) throws Exception {
long start = System.currentTimeMillis();
StringBuffer result = new StringBuffer();
ShellExecutor worker = new ShellExecutor();
try {
worker.shellExec(command, result);
} finally {
result.append("exe duration : " + (System.currentTimeMillis() - start + "\n"));
Connection dbConnection = null;
PreparedStatement logsStatement = null;
try {
dbConnection = DriverManager.getConnection(DEFAULT_CONNECTION);
logsStatement = dbConnection.prepareStatement(INSERT_LOGS_SQL);
logsStatement.clearParameters();
Clob clob = dbConnection.createClob();
clob.setString(1, result.toString());
logsStatement.setClob(1, clob);
logsStatement.executeUpdate();
} finally {
if (logsStatement != null) {
try {
logsStatement.close();
} catch (Exception e) {
}
}
}
}
return result.substring(result.length() - 3090);
}
public void shellExec(String command, StringBuffer result) throws Exception {
Process process = null;
int exit = -10;
try {
InputStream stdout = null;
String[] params = command.split("#*#jms_separator#*#");
BASE64Encoder benc = new BASE64Encoder();
for (int i = 0; i < params.length; i++) {
if (params[i].contains("{") || params[i].contains("}") || params[i].contains("<")
|| params[i].contains("/>")) {
params[i] = benc.encodeBuffer(params[i].getBytes("UTF-8"));
}
}
result.append("Using separator : " + "#*#jms_separator#*#").append("\n")
.append("Calling : " + Arrays.toString(params)).append("\n");
ProcessBuilder pb = new ProcessBuilder(params);
pb.redirectErrorStream(true);
process = pb.start();
stdout = process.getInputStream();
LogStreamReader lsr = new LogStreamReader(stdout, result);
FutureTask<String> stdoutFuture = new FutureTask<String>(lsr, null);
Thread thread = new Thread(stdoutFuture, "LogStreamReader");
thread.start();
try {
exit = process.waitFor();
} catch (InterruptedException e) {
try {
exit = process.waitFor();
} catch (Exception e1) {
}
}
stdoutFuture.get();
result.append("\n").append("exit code :").append(exit).append("\n");
if (exit != 0) {
throw new RuntimeException(result.toString());
}
} catch (Exception e) {
result.append("\nException(").append(e.toString()).append("):").append(e.getCause()).append("\n\n");
e.printStackTrace(System.err);
throw e;
} finally {
if (process != null) {
process.destroy();
}
}
}
}
class LogStreamReader implements Runnable {
private BufferedReader reader;
private StringBuffer result;
public LogStreamReader(InputStream is, StringBuffer result) {
this.reader = new BufferedReader(new InputStreamReader(is));
this.result = result;
}
public void run() {
try {
String line = null;
while ((line = reader.readLine()) != null) {
result.append(line).append("\n");
}
} catch (Exception e) {
result.append("\nException(").append(e.toString()).append("):").append(e.getCause()).append("\n\n");
e.printStackTrace(System.err);
} finally {
try {
reader.close();
} catch (IOException e) {
}
}
}
}
The class of the external Java program packaged as an executable with all needed librairies, a simple JMS sender :
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import javax.jms.Destination;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import org.apache.commons.codec.binary.Base64;
import org.json.JSONObject;
import progress.message.jclient.ConnectionFactory;
import progress.message.jimpl.Connection;
public class JMSSender {
private static SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss.SSS");
public static void main(String[] args) throws Throwable {
doSend(args[0]);
}
public static void doSend(String text)
throws Throwable {
if (Base64.isBase64(text)) {
text = new String(Base64.decodeBase64(text));
}
String content = "\n\nsending message :" + text;
Connection con = null;
Session session = null;
try {
ConnectionFactory cf = new ConnectionFactory();
session = con.createSession(false, Session.AUTO_ACKNOWLEDGE);
Destination dest = session.createTopic(destination) ;
MessageProducer producer = session.createProducer(dest);
con.start();
JSONObject json = new JSONObject();
json.put("content", text);
json.put("date", sdf.format(new Date()));
TextMessage tm = session.createTextMessage(json.toString());
producer.send(tm);
content += " \n\n" + "sent message :" + json.toString();
} catch (Throwable e) {
content += " \n\n" + e.toString() + " \n\n" + Arrays.toString(e.getStackTrace());
if (e.getCause() != null) {
content += " \n\nCause : " + e.getCause().toString() + " \n\n"
+ Arrays.toString(e.getCause().getStackTrace());
}
e.printStackTrace(System.err);
throw e;
} finally {
write("steps on sending message : " + content);
if (session != null) {
try {
session.commit();
session.close();
} catch (Exception e) {
}
session = null;
}
if (con != null) {
try {
con.stop();
con.close();
} catch (Exception e) {
}
}
}
}
private static void write(String log) {
try {
if (System.out != null) {
System.out.println(log);
}
} catch (Exception e2) {
}
}
}

Glassfish RAR5035:Unexpected Exception While Destroying Resource From Pool

I have a Java EE web application. I am connecting database with JDBC and I am using JDBC connection pool. My application's main page is login page. After I enter the login page and wait for a while, I take this glassfish server(4.1.0) warning consistently.
Warning: RAR5035:Unexpected exception while destroying resource from
pool OraclePool. Exception message: Error while destroying resource
:IO Error: Socket read timed out
Even if I don't do any action on the page. When I monitore the statistics of the connection pool, NumConnCreated is increasing continuously. How can I solve the problem?. Thank you.
This is my managed bean class.
#ManagedBean
#SessionScoped
public class Login implements Serializable{
private String userName;
private String password;
private User user;
private #EJB DBRemote db;
public void test(){
String[] params1 = {"user","1234"};
int[] getParams = {Types.INTEGER,Types.VARCHAR,Types.VARCHAR,Types.VARCHAR};
CallableStatement statement = db.run("TBL.USERLOGIN(?,?,?,?,?,?)", params1 , getParams);
try {
int isLogin = statement.getInt(3);
if (isLogin==1) {
String uName = statement.getString(4);
String uId = statement.getString(5);
user = new User(uId, uName, isLogin);
System.out.println("LOGGED IN " + uName + "\t" + uId);
}else{
String errMessage = statement.getString(6);
user = new User(errMessage,isLogin);
System.out.println("LOG IN FAILURE " + errMessage);
}
} catch (SQLException ex) {
Logger.getLogger(Login.class.getName()).log(Level.SEVERE, null, ex);
}finally{
db.close();
FacesContext.getCurrentInstance().addMessage("infoback", new FacesMessage(FacesMessage.SEVERITY_INFO,
"TEST","Test Works"));
}
}
}
This my interface class
#Remote
public interface DBRemote {
CallableStatement run(String query, String[] setParams, int[] getParams);
void close();
String getErrorMessage();
String getSql();
}
This is my Stateless Bean class
#Stateless
public class DB implements DBRemote{
#Resource(mappedName = "pwresource")
private DataSource ds;
private String sql;
private String errorMessage;
private CallableStatement statement;
private Connection connection;
public DB() {
}
#Override
public CallableStatement run(String query, String[] setParams, int[] getParams){
sql = "{call " + query + "}";
int getParamIndex = setParams.length + 1;
try {
connection = ds.getConnection();
statement = connection.prepareCall(sql);
for (int i = 0; i < setParams.length; i++) {
statement.setString(i+1, setParams[i]);
}
for (int getParam : getParams) {
statement.registerOutParameter(getParamIndex, getParam);
getParamIndex++;
}
statement.execute();
}catch (SQLException ex) {
if (ex.getErrorCode()==17008) {
errorMessage = "Timeout";
}else{
errorMessage = "System Error";
}
Logger.getLogger(DB.class.getName()).log(Level.SEVERE, null, ex);
close();
}
return statement;
}
#Override
public void close(){
try {
if (statement != null) {
statement.close();
}
if(connection != null){
connection.close();
}
errorMessage = null;
} catch (SQLException e) {
errorMessage = "Close Connection Error";
}
}
#Override
public String getErrorMessage() {
return errorMessage;
}
#Override
public String getSql() {
return sql;
}
}
I have solved my problem. My problem is because of the connection between connection pool and database. Database closes the connections automically because of the server and database in different networks caused timeout issue.

SQLException Handling

I am trying to run a simple Java program which fetches data from the oracle database and display it. I connected the oracle database. Here is my code:
DataHandler Class:
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.ResultSet;
import oracle.jdbc.pool.OracleDataSource;
public class DataHandler {
public DataHandler() {
super();
}
String jdbcUrl = "jdbc:oracle:thin:#localhost:1521:ORCL";
//I already added the above line but still getting error.
String userid = "scott";
String password = "tiger";
Connection conn;
public void getDBConnection() throws SQLException{
OracleDataSource ds;
ds = new OracleDataSource();
ds.setUser(jdbcUrl);
conn = ds.getConnection(userid,password);
}
Statement stmt;
ResultSet rset;
String query;
String sqlString;
public ResultSet getAllEmployees() throws SQLException{
getDBConnection();
stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
query = "SELECT * FROM emp ORDER BY empno";
System.out.println("\nExecuting query: " + query);
rset = stmt.executeQuery(query);
return rset;
}
}
and the JavaClient Class as
JavaCLient CLass:
import java.sql.ResultSet;
public class JavaClient {
public JavaClient() {
super();
}
public static void main(String[] args) throws Exception{
DataHandler datahandler = new DataHandler();
ResultSet rset = datahandler.getAllEmployees();
while (rset.next()) {
System.out.println(rset.getInt(1) + " " +
rset.getString(2) + " " +
rset.getString(3) + " " +
rset.getString(4));
}
}
}
I get no compilation error but while running it I get following exception error
Error:
Exception in thread "main" java.sql.SQLException: Invalid Oracle URL specified: OracleDataSource.makeURL
at oracle.jdbc.pool.OracleDataSource.makeURL(OracleDataSource.java:1277)
at oracle.jdbc.pool.OracleDataSource.getConnection(OracleDataSource.java:185)
at student_attendence_iem.DataHandler.getDBConnection(DataHandler.java:22)
at student_attendence_iem.DataHandler.getAllEmployees(DataHandler.java:31)
at student_attendence_iem.JavaClient.main(JavaClient.java:9)
Process exited with exit code 1.
Please help me. Thanks in advance. :)
You have not set URL of your database.
Add setURL(url) method which takes URL of database as parameter. Below is the code.
OracleDataSource ds;
ds = new OracleDataSource();
ds.setURL(jdbcUrl);
Also, with ds.setUser(jdbcUrl); you are trying to setUser with the URL of database which is wrong.
You don't have to setUser like this as you are already doing that in the following line of code conn = ds.getConnection(userid,password);

JDBC connectivity issue

I'm using the NetBeans IDE(6.8). I have a DB class :
package garits;
import java.io.Serializable;
import java.sql.*;
import java.util.Properties;
public class DB implements Serializable{
private static final long serialVersionUID = 1L;
String dbURL = "jdbc:mysql:///team_project";
String user = "root";
String pwd = "arsenal";
String dbDriver = "com.mysql.jdbc.Driver";
private Connection dbCon;
private ResultSet r;
private Statement s;
public DB()
{}
public boolean connect() throws ClassNotFoundException,SQLException{
Class.forName(dbDriver);
Properties props = new Properties();
props.put(user, "root");
props.put(pwd, "arsenal");
props.put("charSet", "UTF-8");
props.put("lc_ctype", "UTF-8");
dbCon = DriverManager.getConnection(dbURL,props);
//dbCon = DriverManager.getConnection(dbURL,user,pwd);
return true;
}
public void close() throws SQLException{
dbCon.close();
if(r!=null)
r.close();
if(s!=null)
s.close();
}
public ResultSet execSQL(String sql) throws SQLException{
s = dbCon.createStatement();
r = s.executeQuery(sql);
return (r == null) ? null : r;
}
public int updateSQL(String sql) throws SQLException{
s = dbCon.createStatement();
int r = s.executeUpdate(sql);
return (r == 0) ? 0 : r;
}
public int updateSQL(String sql, String getID) throws SQLException{
s = dbCon.createStatement();
int autoIncValue = -1;
s.executeUpdate(sql, Statement.RETURN_GENERATED_KEYS);
ResultSet rs = s.getGeneratedKeys();
if (rs.next()) {
autoIncValue = rs.getInt(1);
}
return autoIncValue;
}
}
The jar file is im my library, but whenever I try to connect:
private void loginButtonActionPerformed(java.awt.event.ActionEvent evt) {
String result ="";
DB db = new DB();
try{
db.connect();
String query = "Select Role From User_Account Where Username=jTextField1.getText()AND Where Password=jTextField2.getText(); ";
ResultSet rs=db.execSQL(query);
while(rs.next())
{
result = rs.getString("Role");
}
if(result.equals(""))
{
JOptionPane.showMessageDialog(loginButton,"Access denied","Error Message",JOptionPane.ERROR_MESSAGE);
}
else if(result.equals("Administrator"))
{
MainPage_Admin admin = new MainPage_Admin();
}
}
catch(Exception e)
{
System.out.println("An error has occurred");
}
}
I get an error(the exception is caught)-the name of the database is "team_project" and password is "arsenal"-any ideas appreciated. I'm new to JDBC.
First step: use at least e.printStackTrace() in your catch-block to get some information from the exception. Otherwise you'll just be guessing.
MySQL database url connection property is wrong
jdbc:mysql://localhost:3306/<your database name>
instead of you are giving
jdbc:mysql:///team_project
modify and execute the program and better to handle the exception within the try/catch block instead of throws.

Resources