|
|
When you find your self staring at the code of a JDeveloper 11/ ADF application wondering why o why the application worked on Windows, but does not on Linux, think about case-sensitivity.
It might be common knowledge to most of us that Linux is case-sensitive and Windows is not, but actively remembering this while developing and specifically naming/ refactoring package names is something different.
Example:
I had a custom data control based on a webservice called DataListService.
I generated a web service proxy in a package called “dataList.proxy” and placed custom entity classes in “dataList.entities”. On a custom proxy client with method getCompany() I generated a data control to use on a page in a selectOnChoice.
- com
- client
- app
- model
- dataList
+ proxy
- entities
Company.java
Company.xml
DLDataControl.java
DLDataControl.xml
In the page definition I had a method iterator
<methodIterator Binds="Company.result" DataControl="DLDataControl"
BeanClass="com.client.app.model.datalist.entities.Company"
id="CompanyIterator"/>
It involved a lot of staring at every part of the application before realizing why the selectOnChoice did not get filled with values on the Linux VM.
Even if you always use lowercase package names (like a true java developer), remember this:
JDeveloper generates page definitions automatically in a package called pageDef. If the reference to a pagedefinition in the DataBindings.cpx is done with “pagedef.
PageDef.xml” you have the same problem:
<pageDefinitionUsages>
<page id="com_client_app_view_testPageDef"
path="com.client.app.view.pagedefs.testPageDef"/>
<page id="com_client_app_view_secondtestPageDef"
path="com.client.app.view.pageDefs.secondtestPageDef"/>
When trying to run/debug an application in JDeveloper and getting the error
The domain edit lock is owned by another session in exclusive mode
go to
http://127.0.0.1:7101/console
This is the administration console of your local Weblogic server you’re running when running/debugging an application in JDeveloper.
username and password are usually
weblogic/weblogic
First time you’ve tried to start the weblogic server with JDeveloper you’ve entered this information. If you really don’t know no more you can always remove the \jdeveloper\system\system11.1.1.0.31.51.88 folder of your JDeveloper installation.
This removes ALL settings, not just of the weblogic server.
When the administration console is started there is a block in the left upper corner called ‘Change Center’. Click on the button to activate changes and the lock will be gone.
just enter the following:
sqlplus username/password@//hostname:1521/sidname
(It can be placed in field “User Name” if working with the SQL*plus interface.)
When it is the second time you have a “HUH am I crazy or what?” moment when dealing with an environment with a oracle 10g product talking to an 11g product, and you’re really glad you finally remember the reason of the first ‘HUH’ time, it’s time to write it down.
In the latest situation we had an oracle 10g database and an oracle 10 application server with a webservice deployed on it using a data source pointing to that 10g DB. No problem in this configuration yet.
The 10g DB was then migrated to 11g without any problems and only step left was switching the data source on the AS.
We were notified that the password was uppercase now as 11g has case-sensitive passwords.
So we changed the connection string of the data source, entered the password uppercase and applied changes. Testing the connection we got a ‘invalid password’ error though.
Probably we made a typo, so we retype the password. Still the error and while getting a bit unsure of our own typing skills we make sure caps lock is off and retype. Still..
To be sure, we restart the container and then test. Still.. We start and stop the container but still.. Totally confused we go to pl/sql developer, double-check tnsnames and try to connect: no problems.
I remembered then a situation of a couple of months a go where I had been going bonkers over a database link I had to make from a 10g to 11g DB.
I kept entering an uppercase password in the ‘edit database link’ screen of pl/sql developer checking different stuff and kept getting an invalid password when testing the altered db link.
As it turned out pl/sql developer actually creates this statement
ALTER DATABASE LINK databaselinkto11g
CONNECT TO schema11g IDENTIFIED BY SCHEMA11G;
But because this was executed on a 10g database the password got saved in lower case, but obviously you can’t see or check that..
Manually altering with quotes around the password did the trick in this situation.
Following this reasoning I expected the 10g AS to also use the lower case version of my upper case entered password.
Lower casing the password of the user on the 11g DB indeed solved the problem.
(Getting the AS or webservice to actually go to the changed connection in the data source also gave unexpected problematic behavior but that’s a different story..)
Say you have a user DBAUSER with DBA rights. As DBAUSER you need to create a trigger in a different schema.
As DBAUSER you simply enter
CREATE OR REPLACE TRIGGER otherschema.my_trigger ..
without any problems.
You need to create the same trigger in a couple of different schema’s though so you decide to make a procedure to make the triggers without duplicating code
CREATE OR REPLACE PROCEDURE DBAUSER.create_trigger( schema IN VARCHAR2 )
IS
BEGIN
EXECUTE IMMEDIATE 'CREATE OR REPLACE TRIGGER ' || schema || '.my_trigger............'
Looking at it, executing the following code as DBAUSER
BEGIN
DBAUSER.create_trigger(schema => 'otherschema')
END;
/
shouldn’t give any problems either, right?
This is actually a situation a colleage handed me asking me to help him figure out why o why the last statement DID give an error being:
ORA-01031: insufficient privileges
He had been staring at it all afternoon trying to understand and I just stared some more.
Apparently Oracle didn’t get that the caller of the procedure also needed to be the executer of the command inside the procedure.
Solution:
CREATE OR REPLACE PROCEDURE DBAUSER.create_trigger( schema IN VARCHAR2 )
AUTHID CURRENT_USER
IS
BEGIN
EXECUTE IMMEDIATE 'CREATE OR REPLACE TRIGGER ' || schema || '.my_trigger............'
This forces the DDL to be excuted ‘in’ the schema calling it.
So say you have a procedure in schema X to execute a DDL statement like creating a table (without schema prefix in the DDL command), you grant execute to public and execute it as schema Y. Without AUTHID the table is created in schema X, with AUTHID it is created in schema Y.
With thanks to my colleage T. Aalsma
Today I was reminded of a mistake I so often make:
OPEN c_somecursor;
FETCH c_somecursor BULK COLLECT INTO t_somecursor;
l_found := c_somecursor%FOUND;
CLOSE c_somecursor;
IF l_found
THEN
dbms_output.put_line('Jup, found something');
The title of this post should give anough hints where this goes wrong. Even if there are records fetched %FOUND does not give back TRUE.
This does work:
OPEN c_somecursor;
FETCH c_somecursor BULK COLLECT INTO t_somecursor;
CLOSE c_somecursor;
IF t_somecursor.count > 0
THEN
dbms_output.put_line('Jup, found something');
Thanks to a colleague of mine, Erik:
%FOUND only works with a BULK COLLECT if this BULK COLLECT is limited:
OPEN c_somecursor;
FETCH c_somecursor BULK COLLECT INTO t_somecursor LIMIT 2;
l_found := c_somecursor%FOUND;
CLOSE c_somecursor;
IF l_found
THEN
dbms_output.put_line('Jup, found something');
Probably not shocking to experienced Apex developers but this is a nice piece of code to discover:
onUnload="javascript:window.opener.doSubmit();"
in the On Load of a pop-up page will refresh the window that opened the pop-up.
Take a good look at the branches of the window that called the pop-up though to make sure the submit does what you want.
To make a specific branch to do something when the pop-up requests a submit of the caller window use
onUnload="javascript:window.opener.doSubmit('<SUBMITSTRING>');"
In the caller window make a branch with a condition ‘Request = Expression 1′ with <SUBMITSTRING> as Expression 1.
Thanks to a colleague, a very interesting article on Partial Page Rendering using javascript at
http://www.oracle-and-apex.com/question-how-to-refresh-an-apex-sql-report-from-javascript/:
A very nice parameter to put in the web.xml of your ADF (trinidad) application when using custom style sheets:
<context-param>
<description>Compression for CSS Class Names</description>
<param-name>org.apache.myfaces.trinidad.DISABLE_CONTENT_COMPRESSION</param-name>
<param-value>true</param-value>
</context-param>
If you don’t put this parameter at ‘true’ ADf will turn your clear style sheet elements into classes like ‘xy1′ and ‘xxb’.
Terrible to work with if you’re developing a custom style sheet and have to figure out which class you see in firebug represents your style sheet element.
Now that we’re talking about nice parameters to turn on during development of your ADF application en style sheets anyway: this is another good one
<context-param>
<description>If this parameter is true, there will be an automatic check of the modification date of your JSPs, and saved state will be discarded when JSP's change. It will also automatically check if your skinning css files have changed without you having to restart the server. This makes development easier, but adds overhead. For this reason this parameter should be set to false when your application is deployed.</description>
<param-name>org.apache.myfaces.trinidad.CHECK_FILE_MODIFICATION</param-name>
<param-value>true</param-value>
</context-param>
This script might come in handy if you also didn’t want the free double quoted upper-case object names in the object scripts on the DB, which you get importing and exporting a schema.
The script goes trough the user_source view and reconstructs a file with scripts to create or replace your current objects (packages, types, functions, procedures and triggers).
While constructing the file the first line of each script is altered to the way I wanted it in this case:
CREATE OR REPLACE <TYPE> <objectname>
The script assumes that the objects all have a certain prefix.
SET heading OFF
SET feedback OFF
SET VERIFY OFF
SET echo OFF
SET termout OFF
SET pages 0
SET linesize 225
SET define ON
COLUMN sort1 noprint
COLUMN sort2 noprint
COLUMN sort3 noprint
-->> ADJUST PREFIX
define schema_pfx="'UBS'"
spool old_sources.sql
prompt SET termout ON
prompt SET heading ON
prompt SET verify ON
prompt SET feedback ON
prompt SET trimspool ON
prompt SET define OFF
prompt
prompt spool old_sources.log
prompt
SELECT name sort1
, type sort2
, line sort3
, CASE WHEN line = 1
THEN 'PROMPT' || CHR (13)
|| 'PROMPT Create/alter ' || TYPE || ' ' || NAME || ' ...' || CHR (13)
|| 'CREATE OR REPLACE ' || text
--
WHEN line = last_line
THEN CHR (13) || '/' || CHR (13)
--
ELSE text
END new_text
FROM (
SELECT t.*
, max(line) over(PARTITION BY name, type) last_line
FROM user_source t
WHERE NAME LIKE &schema_pfx || '_%'
AND TYPE IN ('TYPE', 'TYPE BODY', 'PROCEDURE', 'FUNCTION','PACKAGE', 'PACKAGE BODY')
)
ORDER BY sort1
, sort2
, sort3
/
prompt spool off
spool off
spool new_sources.sql
prompt SET termout ON
prompt SET heading ON
prompt SET verify ON
prompt SET feedback ON
prompt SET trimspool ON
prompt SET define OFF
prompt
prompt spool new_sources.log
prompt
SELECT NAME sort1
, TYPE sort2
, line sort3
, CASE WHEN line = 1
THEN 'PROMPT' || CHR (13)
|| 'PROMPT Create/alter ' || TYPE || ' ' || NAME || ' ...' || CHR (13)
|| 'CREATE OR REPLACE '
|| CASE WHEN quote1 > 0 -- in case of "SCHEMA"."OBJECTNAME"
AND quote4 > 0
THEN REPLACE( text
, SUBSTR( text, quote1, (quote4-quote1)+1 )
, LOWER( NAME ) )
--
WHEN quote1 > 0 -- in case of "OBJECTNAME"
AND quote2 > 0
THEN REPLACE( text, SUBSTR( text, quote1, (quote2-quote1)+1 ), LOWER( name ) )
--
ELSE -- no quotes, objectname maybe uppercase
REPLACE( text, name, LOWER( name ) )
END
--
WHEN line = last_line -- last line contains code
AND LENGTH( TRIM( replace( replace( text, CHR (13), ''), CHR (10), '') )) > 0
THEN ltrim(text) || CHR (13) || '/' || CHR (13)
--
WHEN line = last_line -- last line contains no actual code
THEN '/' || CHR (13)
--
ELSE text
END new_text
FROM (
SELECT r.*
, max(line) over(PARTITION BY name, type) last_line
FROM (
SELECT t.*
, INSTR( text, CHR (34),1, 1 ) quote1
, INSTR( text, CHR (34),1, 2 ) quote2
, INSTR( text, CHR (34),1, 4 ) quote4
FROM user_source t
WHERE NAME LIKE &schema_pfx || '_%'
AND TYPE IN ('TYPE', 'TYPE BODY', 'PROCEDURE', 'FUNCTION','PACKAGE', 'PACKAGE BODY')
) r
)
ORDER BY sort1
, sort2
, sort3
/
prompt spool off
spool off
undefine schema_pfx
|
|