Wednesday, 11 July 2007

SuSE Linux: Running SQLDeveloper 1.2 on openSUSE 10.2

I have just downloaded and installed SQL developer version 1.2 from Oracle.OTN .

Immediately noticeable improvement are the new GUI, the support for two additional RDBMS's like MySQL and SQL Server and also the improved data export capability. In my opinion, the support offered by the previous version was not working correctly since it offered on DML statements for creating the tables you might have wanted to copy or move to an other database using SQL.

I had one small problem though. It seems to me that sql developer is checking the values of the JAVA_HOME and JDK_HOME variables in order to determine the JDK to use. openSUSE defaults these to the /usr/lib/jvm/java path which contains a 1.4.2 jdk, so the workaround was to modify sqldeveloper.sh file so it looks like this :

#!/bin/bash
export JAVA_HOME=/home/thanassis/java/jdk1.5.0_12
export JDK_HOME=/home/thanassis/java/jdk1.5.0_12

cd "`dirname $0`"/sqldeveloper/bin && bash sqldeveloper $*

Tuesday, 3 July 2007

Oracle Table containing the list of all countries

I wanted to create a table containing all country codes and countries.so I set off looking for the list of all two letter country codes. I have to admit that today was my lucky day since I ended up finding not only the list but also ready made SQL code to create and populate a MySQL table ready to cut and paste into your PHPMyAdmin SQL window. The link for the MySQL version can be found here

The truth of the matter was that I needed this for Oracle, so cutting, pasting and dining a bit of editing resulted to the following code :


CREATE TABLE COUNTRY (
 COUNTRY_ID NUMBER(*,0) NOT NULL ENABLE,
 COUNTRY_CODE VARCHAR2(10 BYTE) NOT NULL ENABLE,
 COUNTRY VARCHAR2(4000 BYTE) NOT NULL ENABLE,
 CURRENCY VARCHAR2(4 BYTE),
 CONSTRAINT "COUNTRY_PK" PRIMARY KEY (COUNTRY_ID) ENABLE,
 CONSTRAINT "COUNTRY_CODE_UNIQUE" UNIQUE (COUNTRY_CODE) ENABLE
);

-- INSERTING into COUNTRY
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (1,'ac','Ascension Island',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (2,'ad','Andorra',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (3,'ae','United Arab Emirates',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (4,'af','Afghanistan',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (5,'ag','Antigua and Barbuda',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (6,'ai','Anguilla',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (7,'al','Albania',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (8,'am','Armenia',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (9,'an','Netherlands Antilles',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (10,'ao','Angola',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (11,'aq','Antartica',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (12,'ar','Argentina',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (13,'as','American Samoa',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (14,'au','Australia',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (15,'aw','Aruba',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (16,'az','Azerbaijan',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (17,'ba','Bosnia and Herzegovina',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (18,'bb','Barbados',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (19,'bd','Bangladesh',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (20,'be','Belgium',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (21,'bf','Burkina Faso',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (22,'bg','Bulgaria',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (23,'bh','Bahrain',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (24,'bi','Burundi',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (25,'bj','Benin',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (26,'bm','Bermuda',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (27,'bn','Brunei Darussalam',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (28,'bo','Bolivia',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (29,'br','Brazil',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (30,'bs','Bahamas',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (31,'bt','Bhutan',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (32,'bv','Bouvet Island',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (33,'bw','Botswana',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (34,'by','Belarus',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (35,'bz','Belize',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (36,'ca','Canada',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (37,'cc','Cocos (Keeling) Islands',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (38,'cd','Congo, Democratic People''s Republic',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (39,'cf','Central African Republic',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (40,'cg','Congo, Republic of',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (41,'ch','Switzerland',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (42,'ci','Cote d''Ivoire',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (43,'ck','Cook Islands',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (44,'cl','Chile',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (45,'cm','Cameroon',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (46,'cn','China',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (47,'co','Colombia',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (48,'cr','Costa Rica',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (49,'cu','Cuba',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (50,'cv','Cap Verde',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (51,'cx','Christmas Island',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (52,'cy','Cyprus',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (53,'cz','Czeck Republic',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (54,'de','Germany',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (55,'dj','Djibouti',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (56,'dk','Denmark',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (57,'dm','Dominica',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (58,'do','Dominican Republic',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (59,'dz','Algeria',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (60,'ec','Ecuador',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (61,'ee','Estonia',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (62,'eg','Egypt',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (63,'eh','Western Sahara',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (64,'er','Eritrea',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (65,'es','Spain',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (66,'et','Ethiopia',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (67,'fi','Finland',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (68,'fj','Fiji',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (69,'fk','Falkland Islands (Malvina)',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (70,'fm','Micronesia, Federal State of',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (71,'fo','Faroe Islands',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (72,'fr','France',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (73,'ga','Gabon',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (74,'gd','Grenada',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (75,'ge','Georgia',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (76,'gf','French Guiana',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (77,'gg','Guernsey',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (78,'gh','Ghana',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (79,'gi','Gibraltar',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (80,'gl','Greenland',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (81,'gm','Gambia',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (82,'gn','Guinea',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (83,'gp','Guadeloupe',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (84,'gq','Equatorial Guinea',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (85,'gr','Greece',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (86,'gs','South Georgia and the South Sandwich Islands',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (87,'gt','Guatemala',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (88,'gu','Guam',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (89,'gw','Guinea-Bissau',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (90,'gy','Guyana',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (91,'hk','Hong Kong',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (92,'hm','Heard and McDonald Islands',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (93,'hn','Honduras',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (94,'hr','Croatia/Hrvatska',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (95,'ht','Haiti',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (96,'hu','Hungary',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (97,'id','Indonesia',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (98,'ie','Ireland',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (99,'il','Israel',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (100,'im','Isle of Man',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (101,'in','India',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (102,'io','British Indian Ocean Territory',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (103,'iq','Iraq',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (104,'ir','Iran (Islamic Republic of)',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (105,'is','Iceland',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (106,'it','Italy',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (107,'je','Jersey',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (108,'jm','Jamaica',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (109,'jo','Jordan',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (110,'jp','Japan','Yen');
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (111,'ke','Kenya',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (112,'kg','Kyrgyzstan',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (113,'kh','Cambodia',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (114,'ki','Kiribati',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (115,'km','Comoros',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (116,'kn','Saint Kitts and Nevis',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (117,'kp','Korea, Democratic People''s Republic',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (118,'kr','Korea, Republic of',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (119,'kw','Kuwait',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (120,'ky','Cayman Islands',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (121,'kz','Kazakhstan',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (122,'la','Lao, People''s Democratic Republic',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (123,'lb','Lebanon',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (124,'lc','Saint Lucia',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (125,'li','Liechtenstein',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (126,'lk','Sri Lanka',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (127,'lr','Liberia',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (128,'ls','Lesotho',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (129,'lt','Lithuania',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (130,'lu','Luxembourg',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (131,'lv','Latvia',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (132,'ly','Libyan Arab Jamahiriya',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (133,'ma','Morocco',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (134,'mc','Monaco',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (135,'md','Moldova, Republic of',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (136,'mg','Madagascar',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (137,'mh','Marshall Islands',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (138,'mk','Macedonia, Former Yugoslav Republic',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (139,'ml','Mali',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (140,'mm','Myanmar',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (141,'mn','Mongolia',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (142,'mo','Macau',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (143,'mp','Northern Mariana Islands',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (144,'mq','Martinique',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (145,'mr','Mauritania',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (146,'ms','Montserrat',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (147,'mt','Malta',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (148,'mu','Mauritius',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (149,'mv','Maldives',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (150,'mw','Malawi',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (151,'mx','Mexico',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (152,'my','Malaysia',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (153,'mz','Mozambique',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (154,'na','Namibia',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (155,'nc','New Caledonia',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (156,'ne','Niger',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (157,'nf','Norfolk Island',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (158,'ng','Nigeria',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (159,'ni','Nicaragua',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (160,'nl','Netherlands',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (161,'no','Norway',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (162,'np','Nepal',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (163,'nr','Nauru',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (164,'nu','Niue',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (165,'nz','New Zealand',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (166,'om','Oman',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (167,'pa','Panama',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (168,'pe','Peru',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (169,'pf','French Polynesia',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (170,'pg','Papua New Guinea',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (171,'ph','Philippines',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (172,'pk','Pakistan',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (173,'pl','Poland',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (174,'pm','St. Pierre and Miquelon',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (175,'pn','Pitcairn Island',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (176,'pr','Puerto Rico',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (177,'pt','Portugal',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (178,'pw','Palau',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (179,'py','Paraguay',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (180,'qa','Qatar',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (181,'re','Reunion Island',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (182,'ro','Romania',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (183,'ru','Russian Federation',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (184,'rw','Rwanda',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (185,'sa','Saudi Arabia',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (186,'sb','Solomon Islands',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (187,'sc','Seychelles',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (188,'sd','Sudan',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (189,'se','Sweden',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (190,'sg','Singapore',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (191,'sh','St. Helena',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (192,'si','Slovenia',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (193,'sj','Svalbard and Jan Mayen Islands',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (194,'sk','Slovak Republic',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (195,'sl','Sierra Leone',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (196,'sm','San Marino',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (197,'sn','Senegal',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (198,'so','Somalia',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (199,'sr','Suriname',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (200,'st','Sao Tome and Principe',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (201,'sv','El Salvador',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (202,'sy','Syrian Arab Republic',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (203,'sz','Swaziland',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (204,'tc','Turks and Ciacos Islands',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (205,'td','Chad',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (206,'tf','French Southern Territories',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (207,'tg','Togo',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (208,'th','Thailand',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (209,'tj','Tajikistan',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (210,'tk','Tokelau',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (211,'tm','Turkmenistan',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (212,'tn','Tunisia',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (213,'to','Tonga',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (214,'tp','East Timor',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (215,'tr','Turkey',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (216,'tt','Trinidad and Tobago',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (217,'tv','Tuvalu',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (218,'tw','Taiwan',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (219,'tz','Tanzania',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (220,'ua','Ukraine',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (221,'ug','Uganda',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (222,'uk','United Kingdom',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (223,'gb','United Kingdom',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (224,'um','US Minor Outlying Islands',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (225,'us','United States',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (226,'uy','Uruguay',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (227,'uz','Uzbekistan',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (228,'va','Holy See (City Vatican State)',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (229,'vc','Saint Vincent and the Grenadines',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (230,'ve','Venezuela',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (231,'vg','Virgin Islands (British)',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (232,'vi','Virgin Islands (USA)',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (233,'vn','Vietnam',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (234,'vu','Vanuatu',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (235,'wf','Wallis and Futuna Islands',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (236,'ws','Western Samoa',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (237,'ye','Yemen',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (238,'yt','Mayotte',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (239,'yu','Yugoslavia',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (240,'za','South Africa',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (241,'zm','Zambia',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (242,'zr','Zaire',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (243,'zw','Zimbabwe',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (250,'at','Austria',null);
Insert into COUNTRY (COUNTRY_ID,COUNTRY_CODE,COUNTRY,CURRENCY) values (251,'ps','Palestine',null);

Enjoy ..

Wednesday, 27 June 2007

JSF Basics Getting the value of an EL expression in code

You can use the following code to get the value of any EL expression defined inside your JSF page For example the following checks the value of the expression #{requestScope.requestRowKey}

        // access the faces context
        FacesContext fc = FacesContext.getCurrentInstance();

        ValueBinding vb = fc.getApplication().createValueBinding("#{requestScope.requestRowKey}");
        String rowKey = (String )vb.getValue(fc);

Assigning a new value can be preformed by using vb.setValue( Object o)

Tuesday, 26 June 2007

Wrong date and time format when depolying an Application

All the credit for this post should go to John Stegeman for providing the solution. I will just copy the main points here, so I can find it more easily.

The story goes like this. People are seeing different date and time formats after deploying and running their applications on an Oracle IAS rather than their embedded OC4J where the dates and times display correctly.

The solution appears to be the addition of a <locale-config> tag inside the faces-config.xml file. The entire thread that explains everything can be accessed from here. Furthermore John also posted a link with all the two letter ISO country codes which is available from http://www.bcpl.net/~j1m5path/isocodes-table.html

One final remark. I have been deploying applications on Oracle IAS running on Linux (SuSE Linux 8 and SLES9), since version 9i and never run into anything like it. Could that be a Windows issue ? :-)

Monday, 18 June 2007

ADF Tables. Setting an alternative sort property

Suppose you have an ADF table somewhere inside a JSF page and you wish it to be sortable. This is fine as long as you define two things.

  • The sortproperty property of the adf:column tag which has to be one of the column names of the table binding and tell the system how to change the order by clause of the underlying view.
  • The sortbale which has to be set to true or false and determines whether to allow sorting by clicking on the column header or not

So this is a perfectly good column definition for an attribute called Matnr athat corresponds to the notorious SAP material number.

<af:column sortProperty="Matnr" sortable="true"
    headerText="#{bindings['PF_ForSale'].labels.Matnr}">
    <af:outputText value="#{row.Matnr}"/>
</af:column>

If you now happen to have a transient attribute and you wish to sort the table based on this attribute, then you just can't do it. The way I see it, sorting means changing the order by clause and re executing the entire query. ADF complains that there is simply no attribute by that name and throws an SQLException that comes straight from the JDBC driver.

My suggestion for a workaround that works most of the times is this : Since 90% pf transient attributes usually serve as simple lexical transformations of real database attributes, changing the sortProperty of the adf:column tag to the value of the real column might solve the problem

Let's suppose that the ViewObject of the previous example has a transient attribute called DisplayMatnr that simply removes the leading zeros of the SAP oriented material number stored in column Matnr. It goes without saying that if Matnr is sorted then so is DisplayMatnr. Therefore writing something like ...

<af:column sortProperty="Matnr" sortable="true"
    headerText="#{bindings['PF_ForSale'].labels.DisplayMatnr}">
    <af:outputText value="#{row.DisplayMatnr}"/>
</af:column>

... might bring the desired effect. There is one last warning though the attribute that you wish to sort by must be a part of the table definition in the bindings page

Sunday, 17 June 2007

Nvidia Howto for SuSE Linux

Tried upgrading my home Linux KDE today. Not much of of update that was but since the wind of change was already blowing into my system, I thought of updating my NVidia driver as well.

Well it worked... YaST said there was a newer version, I selected it, installed it and failed. There was no way to start X again with Sax2 complaining about amissing screen configuration. Then I did two things.

For everyone else into the same kind of trouble my suggestion is Think before you click and the all time classic.RTFM.

Friday, 8 June 2007

Setting up a Virtual Host in Oracle IAS 10.1.3.1

Sooner or later it would have to come to this. We decided we wanted to setup our application server so that we would end up with two virtual hosts

  • One providing a set of j2ee applications that will be accessible via port 80. This will be used by intra net users
  • Another virtual host, providing an application named MyApp deployed into an OC4J Instance called OC4J_MYAPP that will be accessible via a different DNS name and used by internet users. The actual application will be accessed via SSL provided by a firewall / SSL Converter hosted on a different machine.

The first thing that needed to be done was to enable Apache to run as root and change the listening port to 80. See previous post Oracle IAS 10g 10.1.3.x Enable Apache to run as root and set the default HTTP port to 80 (non SSL)

The next thing was to set up the virtual host. environment. This includes creating a location for the static documents and he log files. In our case I created a websites directory and added a virtual-host-name directory with two subdirs named htdocs and logs.

You then have to go through the patching part and there is no way you can know this unless somebody from Oracle Support tells you. (Thanks Dan!) Out of the box 10.1.3.1 Oracle IAS needs two patches to be applied one 5555875 is the one that will allow your virtual host to be able to mount OC4J exported applications and the second one 5669155 will be the one that will patch the opatch utility so it will install the first one. Both patchsets are available from Oracle metalink.

After you have successfully applied patch numbers 5669155 and 5555875 in sequence, you will have to modify the the httpd.conf file located in $ORACLE_HOME/Apache/Apache/conf/httpd.conf and add a VirtualHost entry to specify the details of your virtual host. My file looks more or less like this

# Defualt virtual host
NameVirtualHost *

# here is where you must enable acess to EM website and other applications 
# so they may be available from the default host
<VirtualHost *>

    Oc4jMountCopy on
    Oc4jMount /em home
    Oc4jMount /em/* home
</VirtualHost>

# Virtual host for example.com

Oc4jRoutingMode Static

<VirtualHost *>
#    Unique location where a unique index.html file exists:
     DocumentRoot /home/oracle/websites/www.example.com/htdocs

#    Name used for this VirtualHost:
     ServerName www.example.com

#    For this purpose, we may need also access on port 80:
     Port 80

     ServerAdmin        me@example.com

#    Must appear in one line
     CustomLog "|/home/oracle/product/10.1.3.1/OracleAS_1/Apache/Apache
                 /bin/rotatelogs /home/oracle/websites/www.example.com/logs/access_log                     
                 43200" common

    Oc4jMountCopy off
    Oc4jMount /MyApp OC4J_MYAPP
    Oc4jMount /MyApp/* OC4J_MYAPP
</VirtualHost>

More or less that does it.

The details can be found in the Apache documentation for virtual hosts, from where the basic idea is summarized as follows:

When a request arrives, the server will first check if it is using an IP address that matches the NameVirtualHost. If it is, then it will look at each section with a matching IP address and try to find one where the ServerName or ServerAlias matches the requested hostname. If it finds one, then it uses the configuration for that server. If no matching virtual host is found, then the first listed virtual host that matches the IP address will be used.

As a consequence, the first listed virtual host is the default virtual host. The DocumentRoot from the main server will never be used when an IP address matches the NameVirtualHost directive. If you would like to have a special configuration for requests that do not match any particular virtual host, simply put that configuration in a &th;VirtualHost> container and list it first in the configuration file.

So to finish it, Just restart the HTTP_Server ...

opmnctl restartproc process-type=HTTP_Server

and it works.

Just one final touch. Since the virtual server will be the home for a single j2ee application, it might be convinient that the static index.html page of the new virtual host directly sends visitors to the j2ee application URL. This is as easy as adding

<meta http-equiv="refresh" content="0; url=/MyApp">

And think that now we are ready.

Thursday, 7 June 2007

JDeveloper 10.1.3.x Screen display problems

I run into the topic on the Oracle JDeveloper forums and I thought I might keep the reference here.

A guy running JDeveloper on Windows using a laptop had serious problems with the display when the IDE tried to scroll as it was leaving visible marks. It ended up that the remedy was adding AddVMOption -Dsun.java2d.noddraw=true at the $JDEV_HOME/jdev/bin/jdev.conf file.

For anybody interested the entire thread can be found here

Friday, 25 May 2007

Adding users in the jazn-data.xml file of a deployed aplication in OC4J

Poor man's authentication in applications deployed on an OC4J instance of an Oracle 10.1.3.x application server often comes down to using basic HTTP authentication and storing user names and passwords in the jazn-data.xml file located in the src/META-INF folder of your ViewController (or UserInterface) project. The technique is documented in Chapter 10 of the Oracle Application Development Framework: Tutorial 10g Release 3 (10.1.3).

A question that I had to answer the first time i started using this was how to change a user's password. I posted this to the JDeveloper forum and Frank Nimphius explained that it is as easy as entering the text in clear text preceded by an ! and then restarting the OC4J instance. The passowrd gets automatically hashed.

The other thing I found out is that, when the application gets redeployed then the jazn-data.xml file does not get copied to the application server so you are left with the initial users created during the initial deployment.

The actual file is stored in $ORACLE_HOME/j2ee/OC4J_NAME//application-deployments/myApp where OC4J_NAME is the name of the oc4j instance and MyApp is the name of the j2ee application.

The best way for me to handle this is to edit and test it on local PC, then copy it to the application server and restart OC4J. So for my EOrders application deployed in the OC4J_SAP instance the story goes like this :

oracle@lachesis:~/product/10.1.3.1/OracleAS_1/j2ee/OC4J_SAP/application-deployments/EOrders> scp thanassis@lxBakalidis:/home/thanassis/jdevhome/mywork/EOrders/View
Controller/src/META-INF/jazn-data.xml .
Password:
jazn-data.xml                                                                100% 2419     2.4KB/s   00:00
oracle@lachesis:~/product/10.1.3.1/OracleAS_1/j2ee/OC4J_SAP/application-deployments/EOrders> vi jazn-data.xml
oracle@lachesis:~/product/10.1.3.1/OracleAS_1/j2ee/OC4J_SAP/application-deployments/EOrders> opmnctl startproc  process-type=OC4J_SAP
opmnctl: starting opmn managed processes...
oracle@lachesis:~/product/10.1.3.1/OracleAS_1/j2ee/OC4J_SAP/application-deployments/EOrders>

Wednesday, 23 May 2007

Oracle IAS 10g 10.1.3.x Enabling and using SSO Authentication

Reading again from the manual, enabling Single-Sign-On for deployed applications on a new 10.1.3.x application server midtier is a three step process For this example my new instance uses the DNS name lachesis.shelman.int and the HTTP server listens at port 80, while my 10.1.2 infrastructure host is named eudoxia:
  1. Create the SSO configuration file on the host running infrastructure services in my case this is a 10.1.2 Oracle IAS infrastructure.
    oracle@eudoxia:~/sso_reg> $ORACLE_HOME/sso/bin/ssoreg.sh 
               -oracle_home_path $ORACLE_HOME 
               -config_mod_osso TRUE 
               -site_name lachesis.shelman.int 
               -remote_midtier 
               -config_file lachesis_osso.conf 
               -mod_osso_url http://lachesis.shelman.int
    CLASSPATH=/home/oracle/OraHome_1/jlib/repository.jar:/home/oracle/OraHome_1/sso/lib/ossoca.jar:/home/oracle/OraHome_1/sso/lib/ossoreg.jar:/home/oracle/OraHome_1/lib/xmlparserv2.jar:/home/oracle/OraHome_1/jdbc/lib/classes12.jar:/home/oracle/OraHome_1/jdbc/lib/nls_charset12.jar:/home/oracle/OraHome_1/jlib/jndi.jar:/home/oracle/OraHome_1/jlib/ojmisc.jar:/home/oracle/OraHome_1/j2ee/home/jazn.jar:/home/oracle/OraHome_1/j2ee/home/jaas.jar:/home/oracle/OraHome_1/jdk/lib/rt.jar:/home/oracle/OraHome_1/jdk/lib/i18n.jar:.:/home/oracle/OraHome_1/sysman/webapps/emd/WEB-INF/lib/emd.jar:/home/oracle/OraHome_1/dcm/lib/dcm.jar:/home/oracle/OraHome_1/sysman/j2ee/lib/portalSMI.jar:/home/oracle/OraHome_1/jlib/emConfigInstall.jar:/home/oracle/OraHome_1/lib/dms.jar:/home/oracle/OraHome_1/opmn/lib/ons.jar:/home/oracle/OraHome_1/j2ee/home/oc4j.jar
    Parameters passed to SSO registration tool :
    param0:-oracle_home_path param1:/home/oracle/OraHome_1 param2:-oracle_home_path param3:/home/oracle/OraHome_1 param4:-config_mod_osso param5:TRUE param6:-site_name param7:lachesis.shelman.int param8:-remote_midtier param9:-config_file param10:lachesis_osso.conf param11:-mod_oso_url param12:http://lachesis.shelman.int
    -DinstallType=
    -DoldOracleHome=
    -DoldOHSUser=root
    Wed May 23 15:07:20 EEST 2007  Invalid argument -mod_oso_url
    Wed May 23 15:07:20 EEST 2007  Missing value for parameter: http://lachesis.shelman.int
    oracle@eudoxia:~/sso_reg> $ORACLE_HOME/sso/bin/ssoreg.sh -oracle_home_path $ORACLE_HOME -config_mod_osso TRUE -site_name lachesis.shelman.int -remote_midtier -config_file lachesis_osso.conf -mod_osso_url http://lachesis.shelman.int
    CLASSPATH=/home/oracle/OraHome_1/jlib/repository.jar:/home/oracle/OraHome_1/sso/lib/ossoca.jar:/home/oracle/OraHome_1/sso/lib/ossoreg.jar:/home/oracle/OraHome_1/lib/xmlparserv2.jar:/home/oracle/OraHome_1/jdbc/lib/classes12.jar:/home/oracle/OraHome_1/jdbc/lib/nls_charset12.jar:/home/oracle/OraHome_1/jlib/jndi.jar:/home/oracle/OraHome_1/jlib/ojmisc.jar:/home/oracle/OraHome_1/j2ee/home/jazn.jar:/home/oracle/OraHome_1/j2ee/home/jaas.jar:/home/oracle/OraHome_1/jdk/lib/rt.jar:/home/oracle/OraHome_1/jdk/lib/i18n.jar:.:/home/oracle/OraHome_1/sysman/webapps/emd/WEB-INF/lib/emd.jar:/home/oracle/OraHome_1/dcm/lib/dcm.jar:/home/oracle/OraHome_1/sysman/j2ee/lib/portalSMI.jar:/home/oracle/OraHome_1/jlib/emConfigInstall.jar:/home/oracle/OraHome_1/lib/dms.jar:/home/oracle/OraHome_1/opmn/lib/ons.jar:/home/oracle/OraHome_1/j2ee/home/oc4j.jar
    Parameters passed to SSO registration tool :
    param0:-oracle_home_path param1:/home/oracle/OraHome_1 param2:-oracle_home_path param3:/home/oracle/OraHome_1 param4:-config_mod_osso param5:TRUE param6:-site_name param7:lachesis.shelman.int param8:-remote_midtier param9:-config_file param10:lachesis_osso.conf param11:-mod_osso_url param12:http://lachesis.shelman.int
    -DinstallType=
    -DoldOracleHome=
    -DoldOHSUser=root
    Check /home/oracle/OraHome_1/sso/log/ssoreg.log for details of this registration
    SSO registration tool finished successfully.
    oracle@eudoxia:~/sso_reg>
    
  2. Now we have the file named lachesis_osso.conf that we need to copy to the actual host running the 10.1.3.x instance.
    oracle@eudoxia:~/sso_reg> scp lachesis_osso.conf oracle@lachesis:/home/oracle
    Password:
    lachesis_osso.conf                                                         100%  417     0.4KB/s   00:00
    oracle@eudoxia:~/sso_reg>
    
  3. Back in the middle tier host, we only need to run file osso1013 located in the $ORACLE_HOME/Apache/Apache/bin directory, passing it the new file as an argument.
    racle@lachesis:~> $ORACLE_HOME/Apache/Apache/bin/osso1013 lachesis_osso.conf
    
    /home/oracle/product/10.1.3.1/OracleAS_1/Apache/Apache/conf/httpd.conf successfully updated.
    /home/oracle/product/10.1.3.1/OracleAS_1/Apache/Apache/conf/mod_osso.conf successfully updated.
    
    oracle@lachesis:~>
    

Now when we want to SSO protect any deployed application we usually edit the file mod_sso.conf located in $ORACLE_HOME/Apache/Apache/conf. Let's suppose now that an already installed application uses a web content root like /MyApp. In this case users would invoke it via a URL like http://my_host:my_post/myApp.
Protecting this application with SSO requires that you enter the following in the mod_osso.file.
<Location /MyApp>
    require valid-user
    AuthType Basic
</Location>
As always bouncing the instance is the last step.

Oracle IAS 10g 10.1.3.x Enable Apache to run as root and set the default HTTP port to 80 (non SSL)

This is relatively easy and comes straight out of the Oracle Application Server Administrator's Guide. In order to set the HTTP listen port to value less than 1024 we need to set the Apache to run as root.
[oracle@barbara ~]$ su
Password: 

[root@barbara bin]#  cd $ORACLE_HOME/Apache/Apache/bin
[root@barbara bin]# chown root .apachectl 
[root@barbara bin]# chmod 6750 .apachectl
Logout from the root shell
[oracle@barbara ~]$ vi $ORACLE_HOME/Apache/Apache/conf/httpd.conf
locate the first listen directive. You should see a fragment like :
#
# Port: The port to which the standalone server listens. For
# ports < 1024, you will need httpd to be run as root initially.
#
# This port is used when starting without SSL
Port 7777
Listen 7777
Change both values to 80, save the file and restart the middle tier instance.
[oracle@barbara ~]$ opmnctl stopall
[oracle@barbara ~]$ opmnctl startall
opmnctl: starting opmn and all managed processes...
[oracle@barbara ~]$ 
The new Application server home page can then be accessed simply be typing http://myservername on your browser's address bar

Tuesday, 22 May 2007

Oracle IAS 10g 10.1.3.1

I have just finished installing a development Oracle IAS 10g version 10.1.3.1 and from what I 've seen new instances are created with support for ADF already enabled. So instead of tampering with the XML files consider the upgrade to 10.1.3.x.

Making a new OC4J Instance ADF aware in Oracle IAS 10.1.3

... or simply copy shared library definitions from one OC4J instance to an other

When you create a new OC4J instance on an Oracle Application server 10g 10.1.3 using the createinstance utility, then the new instance does not have the ADF libraries installed and therefore you cannot deploy any ADF based applications that you usually create using JDeveloper.

To resolve this issue -- thanks to Oracle support -- you have to manually add references for the adf.*libraries to the new instance's server.xml file and add references to the bc4j application to both the server.xml and the default-web-site.xml. The correct configuration is only available in the default home instance created during installation, so we are going to copy the setup from there.

The detailed list of steps required are the following. let's suppose that the new oc4j instance name is OC4J_NEW.

  1. Shutdown the server.
  2. Open $ORACLE_HOME/j2ee/home/config/server.xml using any windowed text editor.
  3. Open $ORACLE_HOME/j2ee/OC4J_NEW/config/server.xml using any windowed text editor.
  4. Copy the two shared-library tags with name="adf.oracle.domain" and name="adf.generic.domain" found in the home/config/server.xml and paste them into the OC4J_NEW/config/server.xml after the last of the shared library tags already in the file. (The same technique can be used for practically copying any server library definitions from one instance to an other).
  5. Close the home/config/server.xml file.
  6. Move towards the end of the OC4J_NEW server.xml and locate a line like:
  7. <application name="ascontrol" path="../../home/applications/ascontrol.ear" parent="system" start="false"/> 
    
  8. insert a blank line after it and add the following :
  9. <application name="bc4j" path="../../../BC4J/redist/bc4j.ear" start="true"/>
    
  10. Close and save the OC4J_NEW server.xml file.
  11. Open the OC4J_NEW/config/default-web-site.xml file. Add a line like :
    <web-app application="bc4j" name="webapp" startup="true" root="/webapp"/> 
    
    right after the <default-web-app> tag located in the top. Close and save the file and restart the instance.In case of any typing errors, the instance log provides very detailed error messages -- at least it did so for me.

Tuesday, 15 May 2007

Oracle ADF Committing master and relevant detail rows simultaneously

There is no doubt that using a trigger to provide unique id's from a database sequence is the best way to handle primary keys. (By the way, I wonder which version of Oracle database will provide an auto-increment data type like MySQL?) There are cases however that require you to create master and detail records in the application server memory and then commit everything simultaneously like in the case of an e-shop where you have to keep both the order header and lines uncommitted until the user finally decides to place the order.

In cases like these, using the DBSequence type for the corresponding entity object attribute might get you into trouble, like I did just yesterday. Theory says that the value of a DBSequence key attribute is a (unique) negative number that later becomes the value assigned by the database trigger. What I did, was try to create detail rows programatically but the master attribute reference for these rows became the negative DBSequence value assigned to the header line at the start of the transaction. So when I tried to do the final commit I got a very clear error explaining that the foreign key constraint for the detail rows was violated.

The only reliable way I found to get myself out of this was to turn back to my old JDeveloper 10g Handbook (published back in 2004) and dig out the following code to allow my entities to obtain an id value directly from the database sequence, thus moving the trigger code from the DB to the application server. So overriding the create method for my custom order header entity object gave me something like this :


import oracle.jbo.server.SequenceImpl;

  ...

  /**
   * Provide a new order id from the SQ_ORDERS database sequence.
   */
  protected void create(AttributeList attributeList)
  {
      super.create(attributeList);
    
      // get a new sequence value for the order ID
      SequenceImpl sqOrders = new SequenceImpl("SQ_ORDERS", getDBTransaction());
      setOrderId( sqOrders.getSequenceNumber());
  }

Friday, 11 May 2007

Oracle ADF How to get the Date after n days and calculate the difference between two dates

I have used this little code fragment many times and each time I try to remember where -- and in which file -- was the last.

I guess that if I put it here, I will limit my search space significantly :-)

import oracle.jbo.domain.Date;
import oracle.jbo.domain.Number;
import java.sql.Timestamp;

...
static final long MILI_SECONDS_PER_DAY = 86400000;

    /**
     * @param startDate initial date to start counting from
     * @param nDays number of days can be begative
     * @return a Date object nDays after startdate
     */
    public static Date dateAfterNDays( Date startDate, int nDays)
    {
       if (startDate == null)
           startDate = new Date(Date.getCurrentDate());  // assume today

       Timestamp ts = startDate.timestampValue();
       long nextDatesSecs = ts.getTime() + (MILI_SECONDS_PER_DAY * nDays);
       return new Date( new Timestamp(nextDatesSecs));
    }

Here is an other example that calculates the number of days between two dates. The parameter dates are oracle.jbo.domain.Date and the return type is an oracle.jbo.domain.Number.

    /**
     * return the number of days between two dates
     */

    private Number dateDifference(InDays Date startDate, Date endDate)
    {
       if (startDate == null)
           startDate = new Date(Date.getCurrentDate()); // assume today

       if (endDate == null)
            endDate = new Date(Date.getCurrentDate());  // asume today again

       Timestamp tsStart = startDate.timestampValue();
       Timestamp tsEnd = endDate.timestampValue();

       long ndays = (tsEnd.getTime() - tsStart.getTime()) / MILI_SECONDS_PER_DAY;

       return new Number(ndays);
    }

Tuesday, 1 May 2007

Linux: Synchronizing a directory tree via LAN with rsync

I keep two copies of my data -- at least I try to do that for the ones I care about like my mp3 files at home and my JDeveloper projects at work. One copy is on my local machine and the other on an other.one with a big hard disk. The command to do this is :

%> rsync -aruvzh  /src_dir user@remote_machine_ip:/dest_dir

This will add all files and directories contained below src_dir excatly under dest_dir. If you need ti remove files not contained in src_dir from dest_dir as well use the --delete option. So the previous command becomes.:

%> rsync -aruvzh --delete  /src_dir user@remote_machine_ip:/dest_dir

by the way, if you think that this is hard to remember and you need to do the synchronizing task often, then adding a line like

alias do_resync='rsync -aruvzh --delete /source_dir you@other_moahchine:/target_dir'

in your ~/.bashrc file, might be the answer, or at least it was/is for me :-)

Thursday, 26 April 2007

JavaScript: How to tell if any form fields have been modified

The following function can be used to determine if a form passed as parameter has been modified, returning true or false respectively. You may use it on submit events in order to avoid unnecessary post actions or like I do in other page links in order to warn the user of pending changes.

I have tested this with Firefox 2.0.0.3, but will post results for other browsers as well.

    /**
     * Check if a form has changed
     */    
    function formModified(aForm)
    {                
        for (var i=0; i < aForm.elements.length; i++) {
            // get the form current element
            var curElement = aForm.elements[i];
            // get the current element type            
            var myType = curElement.type;
            // assume that the form is modified
            var valueChanged = true;
            
            if (myType == 'checkbox' || myType == 'radio') {
                // if both the checked state and the DefaultCheck state are equal
                if (curElement.checked == curElement.defaultChecked) {
                    valueChanged = false
                }                     
            } else if (myType == 'hidden' || myType == 'password' || myType == 'text' || myType == 'textarea') {
                // if the current text is the same as the default text i.e. the original in the
                // HTML Document
                if (curElement.value == curElement.defaultValue) {
                    valueChanged = false
                }
            } else if (myType == 'select-one' || myType == 'select-multiple') {
                for (var j=0;  j < curElement.options.length; j++) {
                    if (curElement.options[j].selected && curElement.options[j].defaultSelected) {
                        valueChanged = false
                    }
                }
            } else
                // unhandled type assume no change
                valueChanged = false;
                    
            // the previously checked element has changed
            if (valueChanged)
                return true;
        }

        // all elements have their default value
        return false;
    }

In order to warn the user of pending changes you would have to write something like :

    /**
     *  returns true if a user can leave a page based on wheither the
     *  aform parameter is committed.
     */
    function canLeavePage(aForm)
    {
        // if no changes were made in the form
        if (formModified(aForm) == false)
            return true;

        // else ask user
        return confirm('Form data have been modified.\n' +
                       ' Are you sure you want to leave this page ?') ;
    }

To use this in your Web page, name your form with something like myForm or InputForm and place anywhere in the page a link like :

              <a href="myPage.php"
                onclick="return canLeavePage(InputForm);"/>
                <img src="images/exit.png"
                    border="0"
                    align="middle"
                    hspace="2"
                    vspace="2"
                    title="Exit"/>
                </a>

Enjoy!

Monday, 23 April 2007

PHP: Directory Listing

Here is a snipper I use to get the contents of a directory. I have many times searched the WEB -- and my files -- for similar functionality so I thought I might put it here to save me the the next searches. The PHP manual for opendir that contains similar code can be found here.

/**
 * returns an associative array containing the file list of the $directory parameter
 * $fileList[$file_name]contains the size of the file or 0 if file_name is a irectory
 */
function fileList($disrectory)
{
   $files = array();
   if (!is_dir($directory))
      return $files;

   if (false == ($d = @opendir($directory)))
     return NULL;

   while (false != ($f = readdir($d))) {
      $fullName = "$directory/$f";
      $files[$f] = is_file($fullName) ? filesize($fullName) : 0;
   }
   closedir($d);

   return $files;
}

Tuesday, 17 April 2007

SAP via Delphi Re-executing the same SAP function

After running the examples from BAPI / RFC with Delphi, I run into the following problem: Each time the Button2Click function was called the grid would show the results already displayed plus any data returned from SAP after the current call. A little bit of debugging showed that the table returned from the SAPFunctions object in statement Table := Funct.tables.item('DATA'), was the one that would not get initialized prior to Funct.call(). Aa I have no clues regarding the available methods of the table or the SAPFunctions object that would allow me to clear the table data before each call, I ended up rewriting the example performing the following changes.

  1. Create one connection object and retain it throughout the entire program session during FormCreate.
  2. Create and destroy a SAPFunctions object at each invocation of the ExecuteButtonClick() function. The way the table returned always has new data returned from SAP. This has been the only way I could avoid the problem of not initializing the returned table. Since I use similar code to perform data transfers between SAP and an other Oracle database at user defined intervals , this optin was more or less a one way.
The actual code of the get cost centers example now looks like this :
unit MainUni;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, OleCtrls, SAPLogonCtrl_TLB, Grids,
 StdCtrls, ComCtrls, ExtCtrls, Buttons;

type
 TFormMain = class(TForm)
   PanelLogin: TPanel;
   StatusBar: TStatusBar;
   ButtonExec: TButton;
   Grid: TStringGrid;
   SAPLogonControl: TSAPLogonControl;
   BitBtnClose: TBitBtn;
   procedure ButtonExecClick(Sender: TObject);
   procedure FormCreate(Sender: TObject);
 private
   { Private declarations }
   Table, Funct, Connection : VARIANT ;
 public
   { Public declarations }
 end;

var
 FormMain: TFormMain;

implementation
{$R *.dfm}

Uses
  SAPFunctionsOCX_TLB;

procedure TFormMain.FormCreate(Sender: TObject);
  begin
     (* create a new connection object to be used
      * for all sessions
      *)
     Connection                  := SAPLogonControl.newConnection;
     Connection.System           := 'R3Q';
     Connection.Client           := '100';
     Connection.ApplicationServer:= 'sapqa_prd.shelman.int';
     Connection.SystemNumber     := '00';
     Connection.Language         := 'EN' ;
  end;

procedure TFormMain.ButtonExecClick(Sender: TObject);
  var
     txt : String;
     r : integer;
     SAPFunctions: TSAPFunctions;
  begin
     SAPFunctions := nil;

     // parameter "true" = SilentLogOn
     if Connection.LogOn(0, false) = true then
        try
           (* Create a new SAPFunctions obejct and
            * assign the existing connection to it
            *)
           SAPFunctions := TSAPFunctions.Create(Self);
           SAPFunctions.Connection := Connection;

           Funct := SAPFunctions.add('RFC_READ_TABLE');
           Funct.exports('QUERY_TABLE').value := 'CSKT';

           // attempt to call
           if not Funct.call then
              // called failed display the error in the statusbar
              StatusBar.SimpleText := Funct.Exception
           else begin
              // Call is successfull display returned data
              Table := Funct.tables.item('DATA');
              grid.rowCount := Table.rowcount + 1;
              grid.cells[0,0] := 'RecNo';
              grid.cells[1,0] := 'Client';
              grid.cells[2,0] := 'CostCent-No';
              grid.cells[3,0] := 'CostCent-Des.';
              for r := 1 to grid.rowCount -1 do begin
                 txt := Table.value(r,1);
                 grid.cells[0,r] := IntToStr(r);
                 grid.cells[1,r] := copy(txt,0,3);
                 grid.cells[2,r] := copy(txt,9,10);
                 grid.cells[3,r] := copy(txt,27,20);
              end;
           end;
        finally
           // close connection
           Connection.LogOff;
           // get rid of the SAPFunctions Object
           SAPFunctions.Free;
        end
     else
        StatusBar.SimpleText := 'Unable to login';
  end;

end.

Wednesday, 11 April 2007

BAPI / RFC with Delphi 6

A sad story with a happy end.

I wanted to write a small application that would update some Oracle tables based on data read from SAP using Delphi 6. Very soon I realized that it all came down to installing the various ActiveX components required for Delphi to connect to SAP, be able to execute functions and read the returned results.

And this is where the sad part of the story begins. Looking around at various sources I could find some instructions explaining how to perform the required installation but none of them seemed to be accurate enough or straightforward enough in order to produce the desired results. In my opinion the problem occurs because our German colleagues who provided the "how-to's" tried to translate the menus from their German Delphi to English and that caused the misunderstanding. Additionally, while following the directions provided I also run into compilations errors increasing my frustration. The following article provides my how to install SAP ActiveX controls on Delphi 6 and I hope to make it as clear as possible.

I have to admit that I owe everything to the guy who wrote and maintained the BAPI/RFC Programming with Delphi Page and to my good friend Marilena who found the page for me. The page has enough examples required in order for the average Delphi programmer to understand how to program the necessary communication. An other page that gives information regarding the pre-installation steps is this one found at SDN.

So here is the list of the steps I followed in order to install SAP ActiveX controls on my version of Delphi 6 If you are using Delphi 2006 then it you might beter have a look here.

  1. Create an additional package page to host the new components.
    1. Right click on the Delphi palette → Properties → Click the Add button.
    2. Type a name for the new page SAP will do just fine
    3. Use the Move Up and Move Down buttons to position the page at the correct position. Caution : Since the page will initially be empty it will not appear on the Delphi palette.
  2. Create an additional directory to hold the units for the new controls. In my case I created : C:\Program Files\Borland\Delphi6\Imports\SAPControls\.
  3. Go to main menu Component → Import ActiveX Control
    1. Select the SAP Logon Control Version 1.1 (wdtlog.OCX). The displayed class name should be TSAPLogonControl
    2. Select SAP as the Palette Page
    3. Change the directory of the unit file name to the new path created in the previous step.
    4. Click install. The first time select to create a new package, name it SAPControls and put it the path we are already using. The controls we will install next will be added to the package as well.
    5. Perform the same steps this time installing the TSAPBapiControl class from SAP BABPI Control Version 1.2
  4. Go to main menu Project → Import Type Library.
    1. Select SAP Remote Function Call Controll (Version 5.0). This will provide you with the TSAPFunctions, TFunction, TParameter, TExports, TImports, TStructure clases
    2. Click install and choose the SAPCOntrols package created previously.
  5. Press compile to compile the project. At this point I got many errors, but I will show you how to resolve them.
Many errors appear in functions with code like the following :
procedure TStructure.Set_Value(index: OleVariant; Param2: OleVariant);
 begin
   DefaultInterface.Set_Value(index) := Param2;
 end;
This should be corrected like this :
procedure TStructure.Set_Value(index: OleVariant; Param2: OleVariant);
 begin
   // DefaultInterface.Set_Value(index) := Param2;
   DefaultInterface.Value[index] := Param2;
 end;
The general error pattern is that there are unknown identifiers for functions of the form Set_XXX(i). These should be changed to indexed properties like XXX[i] Additionally I have had many functions not returning a value. The worst part is that the Delphi complier did not issue any warnings for some of them, so I had to look at each one separately. The worst case was the NewConnection method of the TSAPLogonControl class. The generated code was
function  TSAPLogonControl.NewConnection: IDispatch;
 begin
   DefaultInterface.NewConnection;
 end;
and it had to be corrected to
function  TSAPLogonControl.NewConnection: IDispatch;
 begin
   // had to add Result :=
   Result := DefaultInterface.NewConnection;
 end;
Failure to correct this results to all new Connections being returned null afterwards, making connections to R3 practically impossible. After you correct all the functions with warnings, you should be finished. Just press "Install" on the package dialog and you 're done The examples in BAPI RFC with Delphi page are good and they may get you started immediately. If I ever get any examples of my own I will post them in this page for future reference.