Oracle Change Notification not firing when table changes - oracle

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:

Related

How to implement a worker thread that will process Kinesis records and update GUI in javaFx?

I'm working on a micro-services monitoring app.
My app supposes to update a GUI accordingly when receiving a new consumed
record, meaning:
When I receive a new record:
1)I check if the request it represents is a part of a legal flow, and
if that flow already has representation in the GUI.
By representation, I mean a set of circles that represent the full flow.
For example, if I get a transaction (MS1 received request) a legal flow num 1: that is MS1 to MS2 to MS3, so my GUI will add a table column with 2 grey circles: MS1 to MS2 and MS2 to MS3. Next, when a record: MS2 received from
MS1 is consumed I will paint the first circle green and so on.
My problem is:
I don't understand how to "tap into" Amazon's KCL code (presented here).
meaning, I don't know how to make that a consumed record will trigger event in my JavaFX GUI that will update the GUI accordingly.
Help would be much appreciated!
package com.kinesisdataconsumer;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
import com.DATA_STATUS;
import com.DataBase;
import com.MonitoringLogicImpl;
import com.kinesisdataproducer.Producer;
import com.Transaction;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.amazonaws.auth.DefaultAWSCredentialsProviderChain;
import com.amazonaws.services.kinesis.clientlibrary.interfaces.IRecordProcessor;
import com.amazonaws.services.kinesis.clientlibrary.interfaces.IRecordProcessorCheckpointer;
import com.amazonaws.services.kinesis.clientlibrary.interfaces.IRecordProcessorFactory;
import com.amazonaws.services.kinesis.clientlibrary.lib.worker.InitialPositionInStream;
import com.amazonaws.services.kinesis.clientlibrary.lib.worker.KinesisClientLibConfiguration;
import com.amazonaws.services.kinesis.clientlibrary.lib.worker.Worker;
import com.amazonaws.services.kinesis.clientlibrary.lib.worker.ShutdownReason;
import com.amazonaws.services.kinesis.model.Record;
public class Consumer implements IRecordProcessorFactory {
private static final Logger log = LoggerFactory.getLogger(Consumer.class);
public DataBase dataBase;
public ArrayList<Transaction> transactionList;
public MonitoringLogicImpl monitoringLogic;
private final AtomicLong largestTimestamp = new AtomicLong(0);
private final List<Long> sequenceNumbers = new ArrayList<>();
private final Object lock = new Object();
public Consumer(DataBase database, ArrayList<Transaction> transactions, MonitoringLogicImpl monitoringLogicImplementation){
dataBase = database;
transactionList = transactions;
monitoringLogic = monitoringLogicImplementation;
}
private class RecordProcessor implements IRecordProcessor {
#Override
public void initialize(String shardId) {}
#Override
public void processRecords(List<Record> records, IRecordProcessorCheckpointer checkpointer) {
long timestamp = 0;
List<Long> seqNos = new ArrayList<>();
for (Record r : records) {
timestamp = Math.max(timestamp, Long.parseLong(r.getPartitionKey()));
try {
byte[] b = new byte[r.getData().remaining()];
r.getData().get(b);
seqNos.add(Long.parseLong(new String(b, "UTF-8").split("#")[0]));
//this thread adds the transaction to the DB
Thread addTransactionToDBThread = new Thread() {
public void run() {
try {
JSONObject jsonObj = new JSONObject(new String(b, "UTF-8").split("#")[1]);
Transaction transaction = Transaction.convertJsonToTransaction(jsonObj);
//add the transaction to the database
dataBase.addTransactionToDB(transaction);
//update the user-interface about the last transaction in the system
DATA_STATUS transactionStatus = monitoringLogic.getStatus(transaction);
monitoringLogic.updateUI(transaction.getUuid(), transaction.getSender(), transaction.getReceiver(), transactionStatus);
Thread.sleep(1000);
} catch(InterruptedException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
};
addTransactionToDBThread.start();
} catch (Exception e) {
log.error("Error parsing record", e);
System.exit(1);
}
}
synchronized (lock) {
if (largestTimestamp.get() < timestamp) {
log.info(String.format(
"Found new larger timestamp: %d (was %d), clearing state",
timestamp, largestTimestamp.get()));
largestTimestamp.set(timestamp);
sequenceNumbers.clear();
}
// Only add to the shared list if our data is from the latest run.
if (largestTimestamp.get() == timestamp) {
sequenceNumbers.addAll(seqNos);
Collections.sort(sequenceNumbers);
}
}
try {
checkpointer.checkpoint();
} catch (Exception e) {
log.error("Error while trying to checkpoint during ProcessRecords", e);
}
}
#Override
public void shutdown(IRecordProcessorCheckpointer checkpointer, ShutdownReason reason) {
log.info("Shutting down, reason: " + reason);
try {
checkpointer.checkpoint();
} catch (Exception e) {
log.error("Error while trying to checkpoint during Shutdown", e);
}
}
}
/**
* Log a message indicating the current state.
*/
public void logResults() {
synchronized (lock) {
if (largestTimestamp.get() == 0) {
return;
}
if (sequenceNumbers.size() == 0) {
log.info("No sequence numbers found for current run.");
return;
}
// The producer assigns sequence numbers starting from 1, so we
// start counting from one before that, i.e. 0.
long last = 0;
long gaps = 0;
for (long sn : sequenceNumbers) {
if (sn - last > 1) {
gaps++;
}
last = sn;
}
log.info(String.format(
"Found %d gaps in the sequence numbers. Lowest seen so far is %d, highest is %d",
gaps, sequenceNumbers.get(0), sequenceNumbers.get(sequenceNumbers.size() - 1)));
}
}
#Override
public IRecordProcessor createProcessor() {
return this.new RecordProcessor();
}
public void consumeData() {
KinesisClientLibConfiguration config =
new KinesisClientLibConfiguration(
"KinesisProducerLibSampleConsumer",
Producer.STREAM_NAME,
new DefaultAWSCredentialsProviderChain(),
"KinesisProducerLibSampleConsumer")
.withRegionName(Producer.REGION)
.withInitialPositionInStream(InitialPositionInStream.LATEST);
final Consumer consumer = new Consumer(dataBase, transactionList, monitoringLogic);
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable() {
#Override
public void run() {
consumer.logResults();
}
}, 10, 1, TimeUnit.SECONDS);
new Worker.Builder()
.recordProcessorFactory(consumer)
.config(config)
.build()
.run();
}
}

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) {
}
}
}

JDBC database java using vector of vectors

Does someone can help my by creating an database query with vectors?
I want to query the Lieferranten Table of the nordwind database and showing it on a JTable.
My problem is how to show data sets in the jTable1?
This is my previous code:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;
import java.sql.*;
import java.util.*;
public class Anzeige extends JFrame {
private JTable jTable1 = new JTable(5, 5);
private DefaultTableModel jTable1Model = (DefaultTableModel) jTable1.getModel();
private JScrollPane jTable1ScrollPane = new JScrollPane(jTable1);
public Anzeige (String title) {
super (title);
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
int frameWidth = 676;
int frameHeight = 467;
setSize(frameWidth, frameHeight);
Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
int x = (d.width - getSize().width) / 2;
int y = (d.height - getSize().height) / 2;
setLocation(x, y);
Container cp = getContentPane();
cp.setLayout(null);
// Anfang Komponenten
jTable1ScrollPane.setBounds(72, 56, 521, 289);
jTable1.getColumnModel().getColumn(0).setHeaderValue("Title 1");
jTable1.getColumnModel().getColumn(1).setHeaderValue("Title 2");
jTable1.getColumnModel().getColumn(2).setHeaderValue("Title 3");
jTable1.getColumnModel().getColumn(3).setHeaderValue("Title 4");
jTable1.getColumnModel().getColumn(4).setHeaderValue("Title 5");
cp.add(jTable1ScrollPane);
// Ende Komponenten
setResizable(false);
setVisible(true);
}
public static void main(String[] args) {
new Anzeige("Anzeige");
try {
Class.forName("com.mysql.jdbc.Driver").newInstance();
Connection dbConn = DriverManager.getConnection("jdbc:mysql://localhost:3306/nordwind", "root", "");
Statement statement = dbConn.createStatement();
ResultSet results = statement.executeQuery("SELECT * FROM Lieferranten");
Vector vector = new Vector();
while (results.next()) {
String s1 = results.getString(2);
String s2 = results.getString(5);
System.out.println(s1 + "\n" + s2);
System.out.println(results.getString(2) + " " + results.getString(5));
Vector data = new Vector();
data.add(results.getString(1));
data.add(results.getString(2));
vector.add(data);
}
//results.close();
statement.close();
dbConn.close();
}
catch (InstantiationException e) {
System.err.println("Error in Instantiation!");
}
catch (ClassNotFoundException e) {
System.err.println("Class not found!");
}
catch (IllegalAccessException e) {
System.err.println("Access denied!");
}
catch (SQLException e) {
System.err.println("SQL Error!");
}
}
}
I assume that you will get five column values as you had added five column titles. After that use addRow(java.util.Vector) method of DefaultTableModel to insert row in jTable1.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;
import java.sql.*;
import java.util.*;
public class Anzeige extends JFrame {
private JTable jTable1 = new JTable(5, 5);
private DefaultTableModel jTable1Model = (DefaultTableModel) jTable1.getModel();
private JScrollPane jTable1ScrollPane = new JScrollPane(jTable1);
public Anzeige (String title) {
super (title);
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
int frameWidth = 676;
int frameHeight = 467;
setSize(frameWidth, frameHeight);
Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
int x = (d.width - getSize().width) / 2;
int y = (d.height - getSize().height) / 2;
setLocation(x, y);
Container cp = getContentPane();
cp.setLayout(null);
// Anfang Komponenten
jTable1ScrollPane.setBounds(72, 56, 521, 289);
jTable1.getColumnModel().getColumn(0).setHeaderValue("Title 1");
jTable1.getColumnModel().getColumn(1).setHeaderValue("Title 2");
jTable1.getColumnModel().getColumn(2).setHeaderValue("Title 3");
jTable1.getColumnModel().getColumn(3).setHeaderValue("Title 4");
jTable1.getColumnModel().getColumn(4).setHeaderValue("Title 5");
cp.add(jTable1ScrollPane);
// Ende Komponenten
setResizable(false);
setVisible(true);
}
public static void main(String[] args) {
new Anzeige("Anzeige");
try {
Class.forName("com.mysql.jdbc.Driver").newInstance();
Connection dbConn = DriverManager.getConnection("jdbc:mysql://localhost:3306/nordwind", "root", "");
Statement statement = dbConn.createStatement();
ResultSet results = statement.executeQuery("SELECT * FROM Lieferranten");
while (results.next()) {
String s1 = results.getString(2);
String s2 = results.getString(5);
System.out.println(s1 + "\n" + s2);
System.out.println(results.getString(2) + " " + results.getString(5));
Vector data = new Vector();
data.add(results.getString(1));
data.add(results.getString(2));
data.add(results.getString(3));
data.add(results.getString(4));
data.add(results.getString(5));
jTable1Model.addRow(data);
}
//results.close();
statement.close();
dbConn.close();
}
catch (InstantiationException e) {
System.err.println("Error in Instantiation!");
}
catch (ClassNotFoundException e) {
System.err.println("Class not found!");
}
catch (IllegalAccessException e) {
System.err.println("Access denied!");
}
catch (SQLException e) {
System.err.println("SQL Error!");
}
}
}

JAI tiff image conversion producing bigger file size on windows 7

Trying to compress the image using JAI with TIFF format. It works fine on Windows XP, But it produces 10 times bigger size file on Windows 7 compared to Windows XP.
Using JAI 1.1 and JRE 1.6_0_16
What might be the issue? Appreciate your assistance.
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Iterator;
import java.util.Locale;
import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.stream.ImageOutputStream;
import com.sun.media.imageio.plugins.tiff.TIFFImageWriteParam;
public class Test {
/**
* #param args
*/
public static void main(String[] args) {
File image = new File("abc.tiff");
File tempFile = new File("compressed.tiff");
try {
BufferedImage bi = ImageIO.read(image);
byte[] tiffArray = toTiff(bi, tempFile,"packBits" );
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static byte[] toTiff(BufferedImage bi, File tempFile, String compType) {
byte[] bImg = null;
try{
tempFile.delete();
String format = "TIF";
Iterator writers = ImageIO.getImageWritersByFormatName(format);
if(writers == null || !writers.hasNext()) {
throw new IllegalArgumentException("Unsupported format (" + format + ")");
}
ImageWriter writer = (ImageWriter)writers.next();
IIOImage iioImg = new IIOImage(bi, null, null);
TIFFImageWriteParam writeParam = new TIFFImageWriteParam(Locale.ENGLISH);
writeParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
writeParam.setCompressionType(compType);
ImageOutputStream ios = ImageIO.createImageOutputStream(tempFile);
writer.setOutput(ios);
writer.write(null, iioImg, writeParam);
ios.close();
writer.dispose();
bImg = readImage(tempFile);
}catch(Exception e){
e.printStackTrace();
}
return bImg;
}
public static byte[] readImage(File f) throws Exception {
byte[] bImg = null;
try {
long fLength = f.length();
if(fLength > Integer.MAX_VALUE){
throw new RuntimeException("File is too large to upload....!");
}
bImg = new byte[(int)fLength];
FileInputStream fin = new FileInputStream(f);
fin.read(bImg);
fin.close();
} catch (Exception e) {
e.printStackTrace();
throw e;
}
return bImg;
}
}

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

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;
}
}

Resources