Ramblings from a Bihari!

Just another WordPress.com weblog

interesting fact about identityHashCode() method in java.lang.System Class

The following four lines of code is provides such outputs which confused me about the identityHashCode() method of System class. System.identityHashCode() method is supposed to give the default hashcode value irrespective of whether you have overridden hascode in your class. And as we know that default implementation maps the internal memory address to an integer value.

1  String s = new String(new char[]{‘j’, ‘a’,’v’,’a’});
2  String s1 = new String(new char[]{‘a’, ‘b’,’c’,’d’});

3  System.out.println(System.identityHashCode(s));
4  System.out.println(System.identityHashCode(s1));

When I created a String instance by executing line 1 it would have got some memory location allocated to it. Lets say that is “x”. Then I created another instance s1 with passing some other different array to the String constructor. So s1 would have also got some memory location  allocated for it. Lets say that is “y”.

Now when I print the identity hash code by executing the line number 3 and 4 every time I run the program it gives me the same two integer values. And the order of values depends on the execution of line number 3 and 4 but not on 1 and 2 where actual allocation of memory happened. Thats strange for me 😦

July 31, 2008 Posted by | techie stuff | 8 Comments

Interesting inconsistency with java String pool

I was just trying out the intern() method of java.lang.String class and found an interesting issue.

The intern() method is supposed to put the string literal in the intern pool and give you back a handle to that.

Let me explain the scenario with two programs:-

public static void main(String[] args) {

char[] c = new char[]{‘a’,’b’,’c’};
String s = new String(c).intern();
System.out.println(System.identityHashCode(s));
s = null;
for (int i = 0; i < 20; i++) {
System.gc();
}
String s1 = new String(c).intern();
System.out.println(System.identityHashCode(s1));

}

What are the two values this program is supposed to print ?? I think since the intern is an WeakHashMap so after the gc call it should print two different values of identityHashCode.  Yes till now we are correct theortically and practically both.  But  if you replace the character array with any of

1. new char[]{‘a’,’b’,’c’};

2. new char[]{‘a’,’b’};

3. new char[]{‘a’};

The program will print both the hashcode values as same. Thats strange and very inconsistent. As per my understanding  the value of elements in the array should not be responsible for the behavior of intern() or any other java method.

July 31, 2008 Posted by | techie stuff | 1 Comment

did u know u can find the location of the .class file from the instance??

In general there is no guarantee that u can always get the location(Basically URL) from where ur instance or object is loaded but luck u can’t completely discard.. 🙂

The following class which i am putting tries to find out the location of teh instance from where it is loaded. All you need to do is call the getClass method on your concerned instance and pass the output to this method.

package com.deepak.classloader;

import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.CodeSource;
import java.security.ProtectionDomain;

public class FindClassLoaction {

public static URL getClassLocation (final Class clazz)
{
URL clazzLocation = null;
final String clazzFileName = clazz.getName().replace (‘.’, ‘/’).concat (“.class”);

final ProtectionDomain pd = clazz.getProtectionDomain ();
if (pd != null)
{
final CodeSource codeSourceOfClazz = pd.getCodeSource();
if (codeSourceOfClazz != null) clazzLocation = codeSourceOfClazz.getLocation ();

if (clazzLocation != null)
{
if (“file”.equals (clazzLocation.getProtocol ()))
{
try
{
if (clazzLocation.toExternalForm ().endsWith (“.jar”) ||
clazzLocation.toExternalForm ().endsWith (“.zip”))
clazzLocation = new URL (“jar:”.concat (clazzLocation.toExternalForm ())
.concat(“!/”).concat (clazzFileName));
else if (new File (clazzLocation.getFile ()).isDirectory ())
clazzLocation = new URL (clazzLocation, clazzFileName);
}
catch (MalformedURLException ignore) {}
}
}
}

if (clazzLocation == null)
{
final ClassLoader clsLoader = clazz.getClassLoader ();

clazzLocation = clsLoader != null ?
clsLoader.getResource (clazzFileName) :
ClassLoader.getSystemResource (clazzFileName);
}

return clazzLocation;
}

}

The luck factor here is that u can’t guarantee the fact that every class is loaded with some ProtectionDomain i.e. It depends on the classloader whether it is creating the ProtectionDomain before loading the class….:(

also the CodeSource can be null depending on the classloader implementation. U can almost be sure that protection domain and code source will be populated for the classloders which are instance of URLClassLoader. So better you can put a check on the claasloader whether its an instance of URLClassLoader to be on safe side.

Sun’s implementation seems to allow finding the class file as resource ..

enjoy….

April 24, 2008 Posted by | techie stuff | 6 Comments

Cases for Shortcomings of Single Request-Response model

My personal experience about implementing a single request response model had been very discouraging. Consider a situation in which u want two remotely hosted instances of database to be synchronized.  The synchronization essentially means  changes at either side to be reflected  at the  other side  whenever  synchronization request  is made.  The changes here essentially means inserts, updates, deletes at either side and not the DDL changes to be reflected.

I have a solution which does this synchronization using transfer of changes at either side as XML data packets and applying the changes after successfully receiving the changed XML data packets from the other side. The solution I implemented initially was a single request response model.

This simply means that

Step 1. I will fetch the database changes at the requester side from the last stable synchronized state and convert the changes resultset to java.sql.rowset.WebRowSet kind of XML format and transfer the changes to the receiver end with the request.

Step 2. The receiver side will receive the changes and try to parse the XML data packets and apply the changes on the database.

Step 3. After committing the changes received from the requester end I will fetch the changes at the receiver end and will prepare the XML data packets out of it.

Step 4. The changes at the receiver end will reach and received at the requester end the same commit will happen.

At the end I ll have the two ends in a synchronized state.

The problem with this approach is that this approach is highly unreliable as it is tightly coupled with network. Any network failure will lead to again creating the synchronization request. Which is not necessary as it is always easier to cache the changes at each step(After fetching the changes, After receiving the changes at either end). Also in the single request response model I feel that acknowledgment of  a particular atomic activity  is not exchanged which will highly increase the reliability or at least we can have a save point based approach. what say ??

April 21, 2008 Posted by | techie stuff | Leave a comment

Sharing the same connection or transaction space between derby sql and java.

Think of a situation in which you want to write a stored procedure in Derby and the procedure is calling a static java method inside the same JVM. The important requirement here is that the java method is is being executed by the SQL stored procedure is modifiying some data in the database. So finally the scenario is :: SQL is modifying the data as well as the java method is also modifying the data in the same database. So one must be thinking of transaction safety…. e.g when u rollback both the changes(made by SQL and the corresponding java method) must get rollback. Following is the example…….

Trigger which calls a stored procedure.:::::

CREATE TRIGGER COMPOSITE_U_T AFTER UPDATE ON COMPOSITE REFERENCING NEW AS NEWROW FOR EACH ROW MODE DB2SQL CALL PRO_TRIGGER(‘ID1’, ‘ID2’, NEWROW.ID1, NEWROW.ID2, ‘COMPOSITE’, ‘U’);

Procedure which is called by trigger and which in turn calls the static java method::::

CREATE PROCEDURE PRO_TRIGGER(P_K_1 VARCHAR(50), P_K_2 VARCHAR(50), PK_VAL1 INTEGER, PK_VAL2 INTEGER, TABLE_NAME VARCHAR(100), FLAG VARCHAR(2)) PARAMETER STYLE JAVA MODIFIES SQL DATA LANGUAGE JAVA EXTERNAL NAME ‘com.pramati.bfly.sync.util.db.TriggerClass.executeTriggerLogic’;

The java method which shares the same transaction space as the Procedure which is calling it.

public static void executeTriggerLogic(String pKColName1,String pKColName2, int pKValue1, int pKValue2, String tableName,

String flag) {

String updateDashTableQry = “update “

+ tableName

+ “_dash set time = current_timestamp, flag = ‘”

+ flag

+ “‘, user_id = ‘error’ “

+ (flag.equalsIgnoreCase(“I”) ? “, inserted_time = current_timestamp”

: “”) + ” where “ + pKColName1 + ” = “ + pKValue1

+ ” AND “ + pKColName2 + ” = “ + pKValue2;String insertIntoDashTableQry =

“insert into “ + tableName + “_dash values( “ + pKValue1 + “, “ + pKValue2

+ “, current_timestamp, ‘” + flag + “‘, “

+ (flag.equalsIgnoreCase(“I”) ? “current_timestamp” : null)

+ “, ‘error’)”;

try {

Connection conn = DriverManager

.getConnection(“jdbc:default:connection”);

String query = “select count(*) from “ + tableName + “_dash where “

+ pKColName1 + ” = “ + pKValue1 + ” AND “ + pKColName2

+ ” = “ + pKValue2;

int count = 1;

PreparedStatement ps = conn.prepareStatement(query);

ResultSet rs = ps.executeQuery();

if (rs.next()) {

count = rs.getInt(1);

}

if (count > 0) {System.out.println(“update query ::” + updateDashTableQry);

PreparedStatement ps1 = conn

.prepareStatement(updateDashTableQry);

ps1.executeUpdate();

} else {System.out.println(“insert query ::” + insertIntoDashTableQry);

PreparedStatement ps2 = conn

.prepareStatement(insertIntoDashTableQry);

ps2.executeUpdate();

}

conn.close();

} catch (SQLException e) {

e.printStackTrace();

}

 

}

The most important line as per sharing the same transaction space or sharing the same connection instance between the procedure and the static java method is

Connection conn = DriverManager

.getConnection(“jdbc:default:connection”);

You even dont need to load the Driver as in normal JDBC routine. The above is a very good example which can solve a major migration issue from a Oracle  database trigger to the Java Database(derby) trigger.

 

Cheers!!!!

September 21, 2007 Posted by | techie stuff | 1 Comment

Did u know that u can shutdown someone’s machine(windows) using java????

ha ha ha, there is no particular fundoo java is involved here. Here is the code…u must know the location where windows is installed. Currently i assumed it to be….C:\Windows. So, the cmd.exe is inside C:\Windows\System32. Now follows the code….

package com.deepak.entertainment;

import java.io.IOException;
import java.io.OutputStream;

public class Deepak {
 
 public static void main(String[] args) throws InterruptedException {
  Runtime runtime = Runtime.getRuntime();
  try {
   Process process = runtime.exec(“C:\\WINDOWS\\system32\\cmd.exe”);
   OutputStream os = process.getOutputStream();
   os.write(“shutdown -s -f -t 90 \n\r”.getBytes());
   os.close();
   process.waitFor();
  } catch (IOException e) {
   e.printStackTrace();
  }
 }

}

package this class in a jar file with proper Main-Class entry in manifest file. U can always use jar -mcvf command to create a jar file if u have a proper manifest file. Otherwise the IDEs like eclipse allow tou to export ur main class as a jar file. Done!!!

Now, give this jar file a good name something like “titanic.jar” or something and send it to ur friends. If they have a jdk instlled and they double click the file(open with java) the machine will be shutdown in 90 seconds(configurable in the above code). You cant kill the shutdown process untill you open a command prompt and type

shutdown -a

a is for aborting shutdown.

Cheersssssssssssss!!!!!

September 17, 2007 Posted by | database, techie stuff | 3 Comments

Utilizing JAVA’s power in Derby Database Triggers

In oracle we know that we can do a hell lot of things inside a trigger which is database specific. For example, just consider the following trigger statement….

create or replace trigger <table_name>_u_t after update on <table_name>

referencing new as newRow

for each row

declare counts integer:=0;

begin

select count(*) into counts from <table_name>_dash where  primary_key_column_name = :newRow.primary_key_column_name  ;

if(counts > 0) then update <table_name>_dash set time = sysdate, flag = ‘U’, user_id = ‘error’ where  primary_key_column_name = :newRow.primary_key_column_name  ;

else

insert into <table_name>_dash values( :newRow.primary_key_column_name, sysdate, ‘U’, null, ‘error’); end if;

end;

You can see that almost a procedure is executed inside the trigger statement after update on the table. But these things u can’t do in derby database. Also, it is not that readable code. So here comes using the power of java and getting the above functionality of the trigger in derby database…..

1. First u need to write a method which u want to execute when some update is happening on table.

package com.deepak.test;

 

import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.PreparedStatement;

import java.sql.ResultSet;

import java.sql.SQLException;

 

public class TriggerClass {

 

public static int createTrigger(String primaryKeyColumnName, int primaryKeyValue, String tableName, String flag) {

String updateDashTableQry = “update “

+ tableName

+ “_dash set time = current_timestamp, flag = ‘”

+ flag

+ “‘, user_id = ‘error’ “

+ (flag.equalsIgnoreCase(“I”) ? “, inserted_time = current_timestamp”

: “”) + ” where “ + primaryKeyColumnName + ” = “

+ primaryKeyValue;

String insertIntoDashTableQry = “insert into “ + tableName

+ “_dash values( “ + primaryKeyValue + “, current_timestamp, ‘”

+ flag + “‘, “

+ (flag.equalsIgnoreCase(“I”) ? “current_timestamp” : null)

+ “, ‘error’)”;System.

out.println(“update query ::” + updateDashTableQry);

try {Class.forName(

“org.apache.derby.jdbc.EmbeddedDriver”);

Connection conn = DriverManager

.getConnection(“jdbc:derby:deepakdb”);

String query = “select count(*) from “ + tableName + “_dash where “

+ primaryKeyColumnName + ” = “ + primaryKeyValue;int count = 0;

PreparedStatement ps = conn.prepareStatement(query);

ResultSet rs = ps.executeQuery();

if (rs.next()) {

count = rs.getInt(1);

}

if (count > 0) {

PreparedStatement ps1 = conn

.prepareStatement(updateDashTableQry);

ps1.executeUpdate();

} else {

PreparedStatement ps2 = conn

.prepareStatement(insertIntoDashTableQry);

ps2.executeUpdate();

}

conn.close();

} catch (ClassNotFoundException e) {

e.printStackTrace();

} catch (SQLException e) {

e.printStackTrace();

}

 

return 1;

}

 

}

2. Now u need to create a Function or procedure which will call this createTrigger method written above.

CREATE FUNCTION FUNC_TRIGGER(PK_COLUMN_NAME VARCHAR(50), PK_COLUMN_VALUE INT, TABLE_NAME VARCHAR(50), FLAG VARCHAR(2)) RETURNS INT LANGUAGE JAVA PARAMETER STYLE JAVA NO SQL EXTERNAL NAME ‘com.deepak.test.TriggerClass.createTrigger’;

3. And finally you can call this database function created above in a trigger like the following code snippet.

create trigger <TABLE_NAME>_u_t after update on <TABLE_NAME>

 referencing new as newRow 

for each row

MODE DB2SQL

SELECT FUNC_TRIGGER(‘ID’, newRow.ID, ‘TEST_TRIGGER’, ‘U’) from sysibm.sysdummy1; 

I have used sysibm.sysdummy1 because i dint want to pass any of the table data inside the function.

September 17, 2007 Posted by | techie stuff | 4 Comments

Dids u know that u can search across multiple columns in a database table??

Problem :- There are three columns in a table on MySQL database.

Table Name :- Files

Column Names :- Title, Tags, Description

Lets Say that the search term is “red apple fresh”.

Here is the current wrong query which tries to search this term:

SELECT * FROM files WHERE (files.title LIKE ‘%”red apple fresh”%’ OR files.tags LIKE ‘%red apple fresh”%’ OR files.description LIKE ‘%red apple fresh”%’) ;

The problem with this query is  that it will only select items from the database that have “red apple fresh” together as one term in either the title, tags or description fields. Also if the term “fresh apple red” rather than “red apple fresh” is in either of the fields it will not select the item from the database.

So i needed a query that could select the item if the word “red” is in one field and “apple” is in another field and “fresh” is in the  third field. Also the search should be order insensitive. A one word search like “apple” should result in fetching any item with that word in any of these three fields.

Also with the current query if the person searches “red” then the results will show irrelevant items such as items with anything starting with “red…” such as “reddish” “reddy” ect. This is another error I’s trying to overcome.

Solution:-

Steps of the solution of the above pages is as follows:-

1. The storage engine of the above table should be MyISAM for the coming query to work. So we need to fire the following query to change the Storage engine of the table.

Alter table Files ENGINE=MyISAM;

2. Also the FULLTEXT search shall be enabled where the FULLTEXT is constituting all the three columns where the search term is supposed to occur.

Alter table files add FULLTEXT(title, tags, description);

3. Now the following query will solve the above problem.

query = Select * from files where (match(files, tags, description) Against (‘+red+apple+fresh’);

Cheers!!!

August 31, 2007 Posted by | techie stuff | Leave a comment

Did you know that you can compare RAW columns in a DB?

You can compare two similar tables or two identical tables in the same database using simple SQL query. The Only limitations for this query is it works on only one databse. This will not work for comparisons of table across the network or tables present in different database schemas.
Example:-
create table table1 (id number(18) primary key, price RAW(255));
create table table2 (id number(18) primary key, price RAW(255));

Now you can insert same data in both the tables using JDBC or any other way.(can u insert RAW, BLOB, CLOB directly from sql prompt like insert into table1 values()??). Now change the tables by updating the RAW column in both tables. You can find the non matching by firing this simple SQL query:-

select id as changed_ID from table1 where id in (select id from table2 where table1.price != table2.price and table1.id = table2.id);

This query will fetch the non matching rows of table1 and table2.
For having the same comparison across the network or across the schema go to the following link:-
http://www.oracle.com/technology/oramag/code/tips2004/012504.html

May 24, 2007 Posted by | techie stuff | Leave a comment