Wednesday, 20 February 2013

My "small" project for Saturday... reupholstering my £60 eBay purchase...


This was the disgusting state and the reason I paid £60 for 6 chairs and a table.

Step 1 - seat removed -

Throwing out old and nasty foams...
Brand new foams.... set of 6 was £46 including p&p

Here you will need staple gun. ...

I bought this one:

200 staples later...


Final effect:
:)

Monday, 11 February 2013

JBoss clustering...

So... I had to set up cluster on JBoss to use it as a load balancer for data loading.

I had a problem with deployment of test and production servers.

If you have several servers pointing to different databases and running different versions of application then it's not that great if you are using the same partition configuration setup.

The solution is to deploy each server with different partition name. Without it "master-node" will schedule jobs on all known nodes in the same partition which means it won't load data into one database but to all of them - and this obviously isn't our goal :)

Sunday, 10 February 2013

Time for new working rig...

For some time I'm thinking about buying new computer. Mainly because I've built the old one in 2007 and I feel that over 5 years for a computer is enough. In my mind it's old and doesn't perform as it should... but...

There's always some "but" :)

The old machine is powered by Intel Core 2 Quad Q6700 2.66GHz processor which is running flawlessly overclocked to 3.55GHz (no voltage increase needed). It has 8GB of performance RAM from Corsair (Dominator 1066MHz 5-5-5-15) and quite good motherboard from ASUS (P5E).

The best part of the setup is RAID-10 array. 4 Seagate 500GB discs are running for all of these years with speed comparable to low-end SSD drives.

Volume 1:
Volume 2:

As you can see the first volume (closer to the edge of the spinning discs) is faster than the second one and on average performs with amazing speed of 177 MB/s. Second volume is obviously slower but still performs with average result of 131 MB/s.
I was planing to buy something new, probably:
- i7 3770K
- Asrock Z77 OC Formula or Asus Z77 Sabertooth
- GSkill 16GB 2600MHz
- Ati Radeon HD 7950
- 4 x 120GB SSD (to run them in RAID 10) - you might think this would be an overkill but believe me, even in XXI century in middle of London, UK we have power outages at least once in couple of months. 99% of them last for few seconds but it is still enough to corrupt your data and make you angry! :)

I'll have to rethink this whole thing.

ps YES I know that SSD is still much faster because of the access time :)

Thursday, 20 August 2009

Time to write some tests....

There is always time in your Enterprise Application's life when your code base is just to big to remember every class, then you don't remember what some projects do, then some modules... this is the time when you have to sit down and "waste" some time, and by wasting I mean not write some application code ;)

So today I'm starting building a test framework for our EJB3s...

http://jakarta.apache.org/cactus/getting_started.html

I'll try first with cactus... we will see if it's useful.

Thursday, 13 August 2009

Oracle blobs...

Oracle again...

We have huge amount of data stored on Oracle database in blobs. Data is processed and compressed on middle tier box and then appended to blob. When I need to get the stream back I execute stored procedure looking more or less like that:

SELECT [blobtable].blobdata INTO v_blob
FROM [blobtable] WHERE blobId=v_blobId FOR UPDATE;

Dbms_Lob.OPEN(v_blob, dbms_lob.lob_readonly);
Dbms_Lob.READ(v_blob, v_length, v_offset, p_blob);
Dbms_Lob.CLOSE(v_blob);

COMMIT;


For 99% of the data it works perfectly but.... there always have to be some "but"... and Oracle sometimes throws an exception:

ORA-21560: argument 2 is null, invalid, or out of range
ORA-06512: at "SYS.DBMS_LOB", line 751
ORA-06512: at "[dbname].[packagename]", line 5535


Which points to line with Dbms_Lob.READ method.
I logged all parameters for this call and length and offset are definetely in range, they are not null nor invalid....

Sometimes I really hate Oracle ;)

Solution:

Dbms_Lob.READ outputs BLOB chunk into RAW type which can store up to 32767 bytes so we have to put chunks of our BLOB into RAW buffer and append it each time to out param BLOB.

Don't forget to initialize out BLOB before the while loop:

DBMS_LOB.CREATETEMPORARY(p_blob, true);

Tuesday, 4 August 2009

Java reflection joy :)

Today I had to get database credentials to create connection manually. Of course in JBoss you are defining DataSource in default-ds.xml or in our case oracle-ds.xml which is then parsed by JBoss and you can get a Connection from JNDI (if its registered ;).

But if you have to create connection with the same credentials inside the EAR file which means you would have to specify username, password and db URL again the whole idea about keeping one information in one place fall apart and coding and deploying become to be huge pain and its error prone!

So... of course, the easiest way to get those credentials which are kept in private field called mcf in WrappedDataSource is to use reflection. mcf is a LocalManagedConnectionFactory (org.jboss.resource.adapter.jdbc.local) object which exposes all database configuration as properties. But if you think that you can write:

Field localManagedConnectionFactory = WrapperDataSource.class.getDeclaredField("mcf");


you are wrong ! ;)

Even if getDeclaredField method returns explicitly Field (java.lang.reflection) you still have to cast it to Field!!! So the final code looks like that:

Context ctx = new InitialContext();

DataSource ds = (DataSource) ctx.lookup("java:OracleDS");

Field localManagedConnectionFactory = (Field)WrapperDataSource.class.getDeclaredField("mcf");



localManagedConnectionFactory.setAccessible(true);

LocalManagedConnectionFactory mcf = (LocalManagedConnectionFactory )localManagedConnectionFactory.get(ds);

String database = mcf.getConnectionURL();


I can enjoy java over and over again ;)

Monday, 3 August 2009

Oracle partitioning pain

I spent pretty much whole day trying to load data to Oracle Database. The problem was that partitions should be created automatically while data is loaded but this code apparently didn't work.

So I was getting:
java.sql.SQLException: ORA-14400: inserted partition key does not map to any partition
ORA-06512: at "####################.#########", line 307

and when I was trying to create partition manually:
java.sql.SQLException: ORA-20000: QEM00000000000000002296-ORA-00936 : Unanticipated error occured in PrepareMsgStream. At RunPoint, Adding a partition to MSGBLOB.

The code to create the partition looks like that:

v_DDL := 'ALTER TABLE '||v_TableName||' ADD PARTITION '||v_PartitionName;
v_DDL := v_DDL ||' VALUES LESS THAN ('||v_HighValue||') TABLESPACE '||v_TableSpace;
v_DDL := v_DDL ||' LOB (BlobData) STORE AS '||v_PartitionName||' (TABLESPACE '||v_TableSpace||')';

EXECUTE IMMEDIATE v_DDL;

The problem was with helper function which gets v_HighValue... so it's good to use Dbms_Output.Put_line(v_DDL); to make sure you are executing the code you think you execute ;)