tag:blogger.com,1999:blog-48904110743481896612024-03-10T20:22:39.221-07:00Mukul's Oracle Technology BlogTechnical articles and help related to Oracle OCI(JCS/DBAAS/ATP/OIC/DEVCS) , HCM and Oracle Fusion Middleware Techstack(ADF 12c,Webcenter,Weblogic,JET)based on my technical experience. Mukul Guptahttp://www.blogger.com/profile/05550600691296960397noreply@blogger.comBlogger44125tag:blogger.com,1999:blog-4890411074348189661.post-24666672449581566372022-05-05T04:28:00.014-07:002022-05-05T04:34:22.698-07:00Setup X11 forwarding on Oracle OCI (or Oracle JCS VM) - Oracle Linux 7<p class="MsoNormal" style="line-height: normal; mso-margin-bottom-alt: auto; mso-margin-top-alt: auto;"><span face=""Tahoma",sans-serif" style="font-size: 10pt; mso-fareast-font-family: "Times New Roman";">In general, there are a variety of
tools, that can be selected for using X11 forwarding from a Linux machine, in
this article I am using <b>MobaXterm</b>, as this tool have some very good features
on top of a standard putty and related utilities.<o:p></o:p></span></p>
<p class="MsoNormal" style="line-height: normal; mso-margin-bottom-alt: auto; mso-margin-top-alt: auto;"><span face=""Tahoma",sans-serif" style="font-size: 10pt; mso-fareast-font-family: "Times New Roman";"><o:p> </o:p></span><span style="font-size: 10pt;">Connect to OCI VM via MobaXterm,
most likely you will see X11 forwarding disabled by default.</span></p>
<p align="center" class="MsoNormal" style="line-height: normal; margin-bottom: 0in; text-align: center;"></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEjbXKXUa1wKYMtnbVHnRN2jZdK7fbCGSGOJPNKhWtMSdJG6ElJx9UOU6Qi_D8SVWw-ZlmVl3NScoc5duUf0OKim2406VC2vw9xnrfIq-Zxye01DUfXr99TqPHsvnqJ17JOTua6SqjoPYEfsQ9DULceCRIaTc9kNUrm2O_zHzyHNzSMb8Zfv53_CJRzKbA" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="209" data-original-width="677" height="174" src="https://blogger.googleusercontent.com/img/a/AVvXsEjbXKXUa1wKYMtnbVHnRN2jZdK7fbCGSGOJPNKhWtMSdJG6ElJx9UOU6Qi_D8SVWw-ZlmVl3NScoc5duUf0OKim2406VC2vw9xnrfIq-Zxye01DUfXr99TqPHsvnqJ17JOTua6SqjoPYEfsQ9DULceCRIaTc9kNUrm2O_zHzyHNzSMb8Zfv53_CJRzKbA=w563-h174" width="563" /></a></div>
<p class="MsoNormal" style="line-height: normal; mso-margin-bottom-alt: auto; mso-margin-top-alt: auto;"><b><u><span style="font-family: "Times New Roman",serif; font-size: 12pt; mso-fareast-font-family: "Times New Roman";">Steps to be taken to make sure X11
forwarding is enabled on the OCI VM :</span></u></b><span style="font-family: "Times New Roman",serif; font-size: 12pt; mso-fareast-font-family: "Times New Roman";"><o:p></o:p></span></p>
<ol start="1" type="1">
<li class="MsoNormal" style="background: white; line-height: normal; mso-list: l0 level1 lfo1; mso-margin-bottom-alt: auto; mso-margin-top-alt: auto; tab-stops: list .5in;"><span face=""Tahoma",sans-serif" style="color: black; font-size: 10pt; mso-color-alt: windowtext; mso-fareast-font-family: "Times New Roman";">Log
into the VM and <b>sudo -s root</b>, if you are not root.</span><span face=""Tahoma",sans-serif" style="font-size: 10pt; mso-fareast-font-family: "Times New Roman";"><o:p></o:p></span></li>
<li class="MsoNormal" style="background: white; line-height: normal; mso-list: l0 level1 lfo1; mso-margin-bottom-alt: auto; mso-margin-top-alt: auto; tab-stops: list .5in;"><span face=""Tahoma",sans-serif" style="color: black; font-size: 10pt; mso-color-alt: windowtext; mso-fareast-font-family: "Times New Roman";">Configure
SSHD to <b>not </b>to check if X11 forwarding is enabled:</span><span face=""Tahoma",sans-serif" style="font-size: 10pt; mso-fareast-font-family: "Times New Roman";"><o:p></o:p></span></li>
<ol start="1" type="1">
<li class="MsoNormal" style="background: white; line-height: normal; mso-list: l0 level2 lfo1; mso-margin-bottom-alt: auto; mso-margin-top-alt: auto; tab-stops: list 1.0in;"><b><span face=""Tahoma",sans-serif" style="color: black; font-size: 10pt; mso-color-alt: windowtext; mso-fareast-font-family: "Times New Roman";">cd </span></b><b><span style="color: black; font-family: "Courier New"; font-size: 10pt; mso-color-alt: windowtext; mso-fareast-font-family: "Times New Roman";">/etc/ssh</span></b><span style="font-family: "Times New Roman",serif; font-size: 10pt; mso-fareast-font-family: "Times New Roman";"><o:p></o:p></span></li>
<li class="MsoNormal" style="background: white; line-height: normal; mso-list: l0 level2 lfo1; mso-margin-bottom-alt: auto; mso-margin-top-alt: auto; tab-stops: list 1.0in;"><b><span style="color: black; font-family: "Courier New"; font-size: 10pt; mso-color-alt: windowtext; mso-fareast-font-family: "Times New Roman";">vi
sshd_config</span></b><span style="font-family: "Times New Roman",serif; font-size: 10pt; mso-fareast-font-family: "Times New Roman";"><o:p></o:p></span></li>
<li class="MsoNormal" style="background: white; line-height: normal; mso-list: l0 level2 lfo1; mso-margin-bottom-alt: auto; mso-margin-top-alt: auto; tab-stops: list 1.0in;"><span face=""Tahoma",sans-serif" style="color: black; font-size: 10pt; mso-color-alt: windowtext; mso-fareast-font-family: "Times New Roman";">Check
if the property </span><b><span style="color: black; font-family: "Courier New"; font-size: 10pt; mso-color-alt: windowtext; mso-fareast-font-family: "Times New Roman";">X11Forwarding</span></b><span style="color: black; font-family: "Courier New"; font-size: 10pt; mso-color-alt: windowtext; mso-fareast-font-family: "Times New Roman";"> </span><span face=""Tahoma",sans-serif" style="color: black; font-size: 10pt; mso-color-alt: windowtext; mso-fareast-font-family: "Times New Roman";">is set to </span><b><i><span style="color: black; font-family: "Courier New"; font-size: 10pt; mso-color-alt: windowtext; mso-fareast-font-family: "Times New Roman";">yes</span></i></b><span face=""Tahoma",sans-serif" style="color: black; font-size: 10pt; mso-color-alt: windowtext; mso-fareast-font-family: "Times New Roman";">.</span><span face=""Tahoma",sans-serif" style="font-size: 10pt; mso-fareast-font-family: "Times New Roman";"><o:p></o:p></span></li>
<li class="MsoNormal" style="background: white; line-height: normal; mso-list: l0 level2 lfo1; mso-margin-bottom-alt: auto; mso-margin-top-alt: auto; tab-stops: list 1.0in;"><span face=""Tahoma",sans-serif" style="color: black; font-size: 10pt; mso-color-alt: windowtext; mso-fareast-font-family: "Times New Roman";">Add <b>AddressFamily
inet </b>in the list</span></li><li class="MsoNormal" style="background: white; line-height: normal; mso-list: l0 level2 lfo1; mso-margin-bottom-alt: auto; mso-margin-top-alt: auto; tab-stops: list 1.0in;"><span face=""Tahoma",sans-serif" style="color: black; font-size: 10pt; mso-color-alt: windowtext; mso-fareast-font-family: "Times New Roman";"><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEgCisf6E_tDWzzWTfXoDmKmGt-pY6lw_DTafeRZrvEXdPeCxWebKuS26rqcMdrL5Ay8Tdqt-tb4CixU5WFsSfor7331s2UVAxZ9TFj6nw9zsQ_ZoEcxl4II2CM0OmzLOmCHQ8Kx7JhQXIJuCE1EMvis-bm8K3F39sXq25WxC3ym2nMA4ZRvEHynGYDyUQ" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="323" data-original-width="792" height="169" src="https://blogger.googleusercontent.com/img/a/AVvXsEgCisf6E_tDWzzWTfXoDmKmGt-pY6lw_DTafeRZrvEXdPeCxWebKuS26rqcMdrL5Ay8Tdqt-tb4CixU5WFsSfor7331s2UVAxZ9TFj6nw9zsQ_ZoEcxl4II2CM0OmzLOmCHQ8Kx7JhQXIJuCE1EMvis-bm8K3F39sXq25WxC3ym2nMA4ZRvEHynGYDyUQ=w475-h169" width="475" /></a></div><br /><br /></span></li>
<li class="MsoNormal" style="background: white; line-height: normal; mso-list: l0 level2 lfo1; mso-margin-bottom-alt: auto; mso-margin-top-alt: auto; tab-stops: list 1.0in;"><span face=""Tahoma",sans-serif" style="color: black; font-size: 10pt; mso-color-alt: windowtext; mso-fareast-font-family: "Times New Roman";">Save
the file</span><span face=""Tahoma",sans-serif" style="font-size: 10pt; mso-fareast-font-family: "Times New Roman";"><o:p></o:p></span></li>
<li class="MsoNormal" style="background: white; line-height: normal; mso-list: l0 level2 lfo1; mso-margin-bottom-alt: auto; mso-margin-top-alt: auto; tab-stops: list 1.0in;"><span face=""Tahoma",sans-serif" style="color: black; font-size: 10pt; mso-color-alt: windowtext; mso-fareast-font-family: "Times New Roman";">Restart
the ssh daemon by executing: </span><b><span style="color: black; font-family: "Courier New"; font-size: 10pt; mso-color-alt: windowtext; mso-fareast-font-family: "Times New Roman";">systemctl restart sshd</span></b><span face=""Tahoma",sans-serif" style="font-size: 10pt; mso-fareast-font-family: "Times New Roman";"><o:p></o:p></span></li>
</ol>
<li class="MsoNormal" style="background: white; line-height: normal; mso-list: l0 level1 lfo1; mso-margin-bottom-alt: auto; mso-margin-top-alt: auto; tab-stops: list .5in;"><span face=""Tahoma",sans-serif" style="color: black; font-size: 10pt; mso-color-alt: windowtext; mso-fareast-font-family: "Times New Roman";">Install
xauth by executing: </span><b><span style="color: black; font-family: "Courier New"; font-size: 10pt; mso-color-alt: windowtext; mso-fareast-font-family: "Times New Roman";">yum -y install xauth</span></b><span face=""Tahoma",sans-serif" style="font-size: 10pt; mso-fareast-font-family: "Times New Roman";"><o:p></o:p></span></li>
<li class="MsoNormal" style="background: white; line-height: normal; mso-list: l0 level1 lfo1; mso-margin-bottom-alt: auto; mso-margin-top-alt: auto; tab-stops: list .5in;"><span face=""Tahoma",sans-serif" style="color: black; font-size: 10pt; mso-color-alt: windowtext; mso-fareast-font-family: "Times New Roman";">Install
xterm (used to verify X configuration) by executing </span><b><span style="color: black; font-family: "Courier New"; font-size: 10pt; mso-color-alt: windowtext; mso-fareast-font-family: "Times New Roman";">yum -y install
xterm</span></b><span face=""Tahoma",sans-serif" style="font-size: 10pt; mso-fareast-font-family: "Times New Roman";"><o:p></o:p></span></li>
<li class="MsoNormal" style="background: white; line-height: normal; mso-list: l0 level1 lfo1; mso-margin-bottom-alt: auto; mso-margin-top-alt: auto; tab-stops: list .5in;"><span face=""Tahoma",sans-serif" style="color: black; font-size: 10pt; mso-color-alt: windowtext; mso-fareast-font-family: "Times New Roman";">Also
install xclock for simple testing of the X Forwarding: </span><b><span style="color: black; font-family: "Courier New"; font-size: 10pt; mso-color-alt: windowtext; mso-fareast-font-family: "Times New Roman";">yum -y install
xclock</span></b><span face=""Tahoma",sans-serif" style="font-size: 10pt; mso-fareast-font-family: "Times New Roman";"><o:p></o:p></span></li>
</ol>
<p class="MsoNormal" style="line-height: normal; margin-bottom: 0in;"><span style="font-family: "Times New Roman",serif; font-size: 12pt; mso-fareast-font-family: "Times New Roman";"><o:p> </o:p></span><span style="font-size: 10pt;">Once the above activities are </span><b style="font-size: 10pt;">completed</b><span style="font-size: 10pt;"> close the
session and open a new session in MobaXterm, this time you should see
xauth error by default as the folder doesn't exists, you can ignore that and
run xclock(It is automatically created behind the scenes).</span></p>
<p align="center" class="MsoNormal" style="line-height: normal; margin-bottom: 0in; text-align: center;"></p><p class="MsoNormal" style="line-height: normal; margin-bottom: 12pt;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEgvWJzNAuN5Ibimb3xmkCvtrOQo6oc4ruMQww5jZUTr5hmjXBzTK5yy-iIRwcdtO4imR0k1TqPTxf2AqZrRR4BkC_CJcPGM5sYp1jgR0jlRTB9lIVRQ_2cRW96pBH9rQQCmCmMYKvZcY4jqRfPnVbKxL0bXrRtUrj3iBUZQwiSM56k1wJhd04hrSP4kBw" style="margin-left: 1em; margin-right: 1em; text-align: center;"><img alt="" data-original-height="202" data-original-width="586" height="179" src="https://blogger.googleusercontent.com/img/a/AVvXsEgvWJzNAuN5Ibimb3xmkCvtrOQo6oc4ruMQww5jZUTr5hmjXBzTK5yy-iIRwcdtO4imR0k1TqPTxf2AqZrRR4BkC_CJcPGM5sYp1jgR0jlRTB9lIVRQ_2cRW96pBH9rQQCmCmMYKvZcY4jqRfPnVbKxL0bXrRtUrj3iBUZQwiSM56k1wJhd04hrSP4kBw=w519-h179" width="519" /></a></p>
<p class="MsoNormal" style="line-height: normal; margin-bottom: 0in;"><span style="font-family: "Times New Roman",serif; font-size: 12pt; mso-fareast-font-family: "Times New Roman";"><o:p> </o:p></span></p><p class="MsoNormal" style="line-height: normal; margin-bottom: 0in;"><i> But what if I want to run x11 forwarding as <b>oracle</b>
user?</i> Lets’ see what happens</p><p class="MsoNormal"><o:p></o:p></p>
<div class="separator" style="clear: both; text-align: center;"><div class="separator" style="clear: both; text-align: center;"><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEi2b-Noic0SmoInxsC8bbeXeIbexRPEyItUp3AQUJvCH7JtHlOzV8E4as2fLbHwj8EmhN8mKbPu5GhoR4zzB1sPrBmpGJgOPzz9OSf8VAR8KanI5h2vbkLesmAPJsZV-8jx41pyR9fTeT2usaArUBwjJwcC-Y9vIfV4cc48dsRh04YYo2tcTXXbFdJpcQ" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="91" data-original-width="491" height="100" src="https://blogger.googleusercontent.com/img/a/AVvXsEi2b-Noic0SmoInxsC8bbeXeIbexRPEyItUp3AQUJvCH7JtHlOzV8E4as2fLbHwj8EmhN8mKbPu5GhoR4zzB1sPrBmpGJgOPzz9OSf8VAR8KanI5h2vbkLesmAPJsZV-8jx41pyR9fTeT2usaArUBwjJwcC-Y9vIfV4cc48dsRh04YYo2tcTXXbFdJpcQ=w543-h100" width="543" /></a></div><br /></div></div>
<p class="MsoNormal">Now, we focus on <b>second </b>problem:<span style="mso-spacerun: yes;"> </span>the reason for <span style="mso-spacerun: yes;"> </span>not setting DISPLAY , because display was only
set for the original user which was used to connect session with <b><span face=""Tahoma",sans-serif" style="font-size: 10pt; line-height: 115%; mso-fareast-font-family: "Times New Roman";">MobaXterm.</span><span face=""Tahoma",sans-serif" style="line-height: 115%; mso-fareast-font-family: "Times New Roman";"> </span></b><span face=""Tahoma",sans-serif" style="line-height: 115%; mso-fareast-font-family: "Times New Roman";">Do, these steps in order to set X11
forwarding for any user you switched after connecting to <b>MobaXterm initially
:</b></span></p><p class="MsoNormal" style="line-height: normal; margin-left: 0.5in; mso-list: l0 level1 lfo1; mso-margin-bottom-alt: auto; mso-margin-top-alt: auto; text-indent: -0.25in;"><!--[if !supportLists]--><span style="font-family: "Times New Roman", serif; font-size: 13.5pt;">1.<span style="font-family: "Times New Roman"; font-size: 7pt; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;"> </span></span><!--[endif]--><span style="font-family: "Times New Roman", serif; font-size: 13.5pt;">Connect with default user, say opc.<o:p></o:p></span></p><p class="MsoNormal" style="line-height: normal; margin-left: 0.5in; mso-list: l0 level1 lfo1; mso-margin-bottom-alt: auto; mso-margin-top-alt: auto; text-indent: -0.25in;"><!--[if !supportLists]--><span style="font-family: "Times New Roman", serif; font-size: 13.5pt;">2.<span style="font-family: "Times New Roman"; font-size: 7pt; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;"> </span></span><!--[endif]--><span style="font-family: "Times New Roman", serif; font-size: 13.5pt;">Type <b>xclock </b>, to check if
display is working fine for the opc user.<o:p></o:p></span></p><p class="MsoNormal" style="line-height: normal; margin-left: 0.5in; mso-list: l0 level1 lfo1; mso-margin-bottom-alt: auto; mso-margin-top-alt: auto; text-indent: -0.25in;"><!--[if !supportLists]--><span style="font-family: "Times New Roman", serif; font-size: 13.5pt;">3.<span style="font-family: "Times New Roman"; font-size: 7pt; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;"> </span></span><!--[endif]--><span style="font-family: "Times New Roman", serif; font-size: 7pt;"> </span><span style="font-family: "Times New Roman", serif; font-size: 13.5pt;">Type echo $DISPLAY<o:p></o:p></span></p><p class="MsoNormal" style="line-height: normal; margin-left: 0.5in; mso-margin-bottom-alt: auto; mso-margin-top-alt: auto;"></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEgWmGkL3zfUROmlzSWL8iwDye_G_7DtVLXkPxVr4tX8npm9XzNFCAPuGDWHOZC2ksCqbPnWTi9BU_4iTneB6JKW4_ZB7Urlbl_bF-eVzbn4C5ZsbeV8eFW5Z-g32lgxML6WmfG2lok8aMf68CUpXxqyNLuGzRH0PxIy8127asqe6TunL1ouURPumhX6dw" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="127" data-original-width="903" height="75" src="https://blogger.googleusercontent.com/img/a/AVvXsEgWmGkL3zfUROmlzSWL8iwDye_G_7DtVLXkPxVr4tX8npm9XzNFCAPuGDWHOZC2ksCqbPnWTi9BU_4iTneB6JKW4_ZB7Urlbl_bF-eVzbn4C5ZsbeV8eFW5Z-g32lgxML6WmfG2lok8aMf68CUpXxqyNLuGzRH0PxIy8127asqe6TunL1ouURPumhX6dw=w533-h75" width="533" /></a></div><br /><br /><p></p><p class="MsoNormal" style="line-height: normal; margin-left: 0.5in; mso-list: l0 level1 lfo1; mso-margin-bottom-alt: auto; mso-margin-top-alt: auto; text-indent: -0.25in;"><!--[if !supportLists]--><span style="font-family: "Times New Roman", serif; font-size: 13.5pt;">4.<span style="font-family: "Times New Roman"; font-size: 7pt; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;"> </span></span><!--[endif]--><span style="font-family: "Times New Roman", serif; font-size: 13.5pt;">Type <b>xauth list $DISPLAY</b><o:p></o:p></span></p><p class="MsoListParagraph" style="margin-left: 0.5in;"></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEg1j64ggaczmPcNesR2qnxAfOSyJiUgjfVU-FJZzA2RPYY0WK9nfIoa0oyoca3z0fKzYXpM2kK9R2sqxYEelAZdjeFbkC-Y3QCZcEVITJrYtTjjt-WFesksEbyQFMo8AiUznNR96jyIOY4lGAXw8SzIPW-pKvq79hrHjnshaaKN6pDMDpU3Mo2PC9buvw" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="53" data-original-width="827" height="37" src="https://blogger.googleusercontent.com/img/a/AVvXsEg1j64ggaczmPcNesR2qnxAfOSyJiUgjfVU-FJZzA2RPYY0WK9nfIoa0oyoca3z0fKzYXpM2kK9R2sqxYEelAZdjeFbkC-Y3QCZcEVITJrYtTjjt-WFesksEbyQFMo8AiUznNR96jyIOY4lGAXw8SzIPW-pKvq79hrHjnshaaKN6pDMDpU3Mo2PC9buvw=w566-h37" width="566" /></a></div><br /><p></p><p class="MsoNormal" style="line-height: normal; margin-left: 0.5in; mso-list: l0 level1 lfo1; mso-margin-bottom-alt: auto; mso-margin-top-alt: auto; text-indent: -0.25in;"><!--[if !supportLists]--><span style="font-family: "Times New Roman", serif; font-size: 13.5pt;">5.<span style="font-family: "Times New Roman"; font-size: 7pt; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;"> </span></span><!--[endif]--><span style="font-family: "Times New Roman", serif; font-size: 7.5pt;"> </span><span style="font-family: "Times New Roman", serif; font-size: 13.5pt;">Now, switch to a different user , say oracle <b>sudo su –
oracle</b><o:p></o:p></span></p><p class="MsoListParagraph" style="margin-left: 0.5in; mso-list: l0 level1 lfo1; text-indent: -0.25in;"><!--[if !supportLists]--><span style="font-size: 13.5pt;">6.<span style="font-size: 7pt; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
</span></span><!--[endif]--><span style="font-size: 7pt;"> </span><span style="font-size: 13.5pt;">Upload export variable: <b>export
DISPLAY=localhost:11.0</b><o:p></o:p></span></p><p class="MsoListParagraph" style="margin-left: 0.5in; mso-list: l0 level1 lfo1; text-indent: -0.25in;"><!--[if !supportLists]--><span style="font-size: 13.5pt;">7.<span style="font-size: 7pt; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: normal;">
</span></span><!--[endif]--><span style="font-size: 13.5pt;">Add
the cookie session reference to current user:<o:p></o:p></span></p><p class="MsoNormal" style="line-height: normal; margin-left: 0.5in; mso-margin-bottom-alt: auto; mso-margin-top-alt: auto;"><span style="font-family: "Times New Roman", serif; font-size: 13.5pt;">xauth
add <output of step #4><o:p></o:p></span></p><p class="MsoNormal" style="line-height: normal; margin-left: 0.5in; mso-margin-bottom-alt: auto; mso-margin-top-alt: auto;"><span style="font-family: "Times New Roman", serif; font-size: 13.5pt;">xauth
add xxxx-wls-1/unix:10 MIT-MAGIC-COOKIE-1 dd413b3fb2aea0e4cd60f504c2893fcf<o:p></o:p></span></p><p class="MsoNormal"><span face=""Tahoma",sans-serif" style="font-size: 10pt; line-height: 115%; mso-fareast-font-family: "Times New Roman";">
</span></p><p class="MsoNormal" style="line-height: normal; mso-margin-bottom-alt: auto; mso-margin-top-alt: auto;"><span style="font-family: "Times New Roman", serif; font-size: 13.5pt;"> and that’s it after this you will be
able to run xclock.<o:p></o:p></span></p><p></p>Mukul Guptahttp://www.blogger.com/profile/05550600691296960397noreply@blogger.com0tag:blogger.com,1999:blog-4890411074348189661.post-50836985604387778102022-05-05T04:06:00.001-07:002022-05-05T04:07:26.805-07:00Getting back to Blogging on OCI and HCM<p> I took a break from blogging after I moved to US back in 2012 , I guess life had had a lot of other things to keep me busy on my journey of technical learning and a lot of video gaming :) . Over last couple of years have worked extensively on different Oracle OCI cloud(s) like ATP, JCS, DBCS, OIC etc. along with Hcm. So, starting back on blogging on issues that touch everyday of our lives on Oracle PaaS and SaaS.</p>Mukul Guptahttp://www.blogger.com/profile/05550600691296960397noreply@blogger.com1tag:blogger.com,1999:blog-4890411074348189661.post-39820741421413674372013-05-24T21:46:00.003-07:002013-05-24T22:00:01.643-07:00New page template for custom webcenter project : Not able to add as portal resource<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
<span style="font-family: tahoma, verdana, sans-serif;">I recently faced a strange issue while creating a new template for webcenter project in Jdeveloper. I created a custom page template for my portal application based on a quick start layout and added some custom code that displays content for header and footer region . Now when I tried to add this page template as a new page template in resource catalog by right clicking the PageTemplate.jspx and selecting create as portal resource. It gives me notification, that "<b>the jspx document is not a valid page template or content presenter template. Recognizing the resource type as Page Style</b>".</span><br />
<span style="font-family: tahoma, verdana, sans-serif;"><br /></span>
<span style="font-family: tahoma, verdana, sans-serif;">In <af:xmlContent> tag you should add:</span><br />
<span style="font-family: tahoma, verdana, sans-serif;"><br /></span>
<span style="font-family: tahoma, verdana, sans-serif;"><facet></span><br />
<span style="font-family: tahoma, verdana, sans-serif;"><description>Facet for content</description></span><br />
<span style="font-family: tahoma, verdana, sans-serif;"><facet-name>content</facet-name></span><br />
<span style="font-family: tahoma, verdana, sans-serif;"></facet></span><br />
<span style="font-family: tahoma, verdana, sans-serif;">And in some parte of your code you need add this:</span><br />
<span style="font-family: tahoma, verdana, sans-serif;"><af:facetRef facetName="content"/></span><br />
<br />
<br /></div>
</div>
</div>
<span style="font-family: tahoma, verdana, sans-serif;"><br /></span>
<span style="font-family: tahoma, verdana, sans-serif;">After this change if you will try to add the template in resource catalog,it should work fine.Hope this helps.</span></div>
Mukul Guptahttp://www.blogger.com/profile/05550600691296960397noreply@blogger.com20tag:blogger.com,1999:blog-4890411074348189661.post-55674072206356896482013-04-19T14:31:00.001-07:002013-04-19T14:31:07.502-07:00ADF 11g Skinning<div dir="ltr" style="text-align: left;" trbidi="on">
An excellent article by Frank on how to approach skinning in ADF , helps to understand how to approach skinning in ADF. Also with latest release of Jdeveloper you have a skin designer as part of Jdeveloper itself , which makes skinning a lot easier.Here is the link to the article : <a href="http://download.oracle.com/otn_hosted_doc/jdeveloper/11gdemos/adf-insider-skinning/adf-insider-skinning.html">http://download.oracle.com/otn_hosted_doc/jdeveloper/11gdemos/adf-insider-skinning/adf-insider-skinning.html</a> . </div>
Mukul Guptahttp://www.blogger.com/profile/05550600691296960397noreply@blogger.com15tag:blogger.com,1999:blog-4890411074348189661.post-69648581827607807802013-04-19T12:51:00.000-07:002013-04-19T12:51:29.126-07:00ADF 11g .... now Free !<div dir="ltr" style="text-align: left;" trbidi="on">
I was not aware that Oracle has now made ADF free, that is a great news for entire J2EE community, now you can quickly develop rich web applications on ADF 11g and deploy on any open source free server like Glassfish, etc. Here is the link for the declaration : <a href="http://www.oracle.com/us/corporate/press/1851249">http://www.oracle.com/us/corporate/press/1851249</a><br />
<br /></div>
Mukul Guptahttp://www.blogger.com/profile/05550600691296960397noreply@blogger.com4tag:blogger.com,1999:blog-4890411074348189661.post-40235842581133876792013-04-16T16:02:00.000-07:002013-04-16T16:05:06.567-07:00Webcentre Discussions Dissection<div dir="ltr" style="text-align: left;" trbidi="on">
<br />
Hi All , after sleeping for quite some time, thought to start blogging back. This time I thought to start with ADF/Webcentre. Webcentre , as we all are seeing is gaining quite a momentum in consulting market now and I can see numerous projects being done some standard spaces implementation , but most projects are custom Webcentre portal as its gives you the liquidity to build any to integrate or build standard ADF application and use lot many features of Webcentre.<br />
<br />
An essential part of Webcentre is Webcentre Discussions(Jive Forums) server and its service. Recently I worked on a custom webcentre project where I integrated the discussion service of webcentre. My idea of writing this article is to explain the discussion service terminology and details and then programmatic API(s) which might help you to do something creative in your project with discussion service.<br />
<br />
<br />
<b><u>About Jive Forums</u></b><br />
Jive forums is the software which runs on discussion server and is a self sufficient forums portal/website. In fact Oracle forums are built on the same platform. Its quite stable, robust and fast.There are currently two editions of Jive Forums: Silver Edition (for small to midsize deployments) and Gold Edition (for large deployments). Some Features unique to the Gold edition include:<br />
<br />
• Question/answer workflow, through which users can mark a post as a question then designate<br />
responses as helpful or correct (scoring points for the users who posted them).<br />
• Expert email notification, in which email notifications are sent for unanswered questions.<br />
• Multiple theme configurations to customize look and feel.<br />
• Reward point system, where points are awarded for responses based on how useful the response<br />
turns out to be.<br />
• Community everywhere, through which users embed discussion threads into other web pages.<br />
• Web services for programmatic access to Jive Forums data.<br />
<br />
<br />
<b><u>Discussion Forums basics</u></b><br />
a) Community : A community typically corresponds to a group of people with a common set of interests and it usually has a single overall purpose.<br />
b) Category : A category is the broadest classification of content in a community. Categories may contain other categories, forums, threads, and messages.<br />
c)Forum: A forum generally focuses on a single thread or a small group of associated threads, and is narrower in scope than a category.<br />
d)Thread : Threads are the individual questions or subjects discussed within the scope of a single forum.A thread is defined as an original message and all of its replies. Threads may run only a few messageslong, or may include hundreds of messages.<br />
e)Message : A message refers to a single question, discussion point or reply that is posted to a forum.Messages comprise a subject header, a message body, and sometimes a file attachment or attachments.<br />
<br />
<b><u>Discussion Forums database details</u></b><br />
Sometimes, its essential to look into the database of discussion forums, for a requirement like grooup update of something. For this reason, it is absolutely necessary for you to have the understanding of some of the main tables, used in Forums are :<br />
<br />
<b>Category :</b> select * from jivecategory where name like ('<b><category name=""></category></b>')<br />
<br />
<b>Forums: </b>select * from jiveForum where categoryid=<<b>category id which you can get from jivecategory</b>><br />
<br />
<b>Thread :</b> Thread is created in the forum where root message id is the starting message of the thread.<br />
select * from jivethread where forumid=92 order by modificationdate desc <br />
You can get root messageid and thread id from the above query. Root message id is the starting message of the thread.<br />
<br />
<b><u>Message :</u> A</b>ll messages of a thread are stored in the table jivemessage with parent child relationship also maintaining the sequence of replies.If parentmessageid is null then root message, else child message.<br />
<br />
select * from jivemessage where forumid=<forum id=""> and threadid=<thread id=""> and messageid=<root id="" message=""></root></thread></forum><br />
<br />
--the direct child of this message can be found by quering with parent<br />
--message id as message id<br />
select * from jivemessage where forumid=<forum id=""> and threadid=<thread id=""> and parentmessageid=<message id="" message="" of="" parent=""></message></thread></forum><br />
<br />
-- using connect by prior getting entire message stack of a thread<br />
--starting from root node<br />
SELECT LEVEL,jv.*<br />
FROM jivemessage jv<br />
where jv.forumid=<forum id=""> and jv.threadid=<thread id=""></thread></forum><br />
START WITH jv.messageid = <root id="" message=""></root><br />
CONNECT BY PRIOR jv.messageid = jv.parentmessageid<br />
ORDER by creationdate<br />
<br />
-- Pls note that each message 's user id<br />
-- is jive user id which is based on LDAP username configured in weblogic security realm<br />
-- and the relationship is stored in jiveuser table <br />
SELECT * FROM JIVEUSER<br />
<br />
<b><u>Webcentre Discussion Services Available Taskflows:</u></b><br />
With the discussion services, you have the following taskflows:<br />
<br />
<ol style="text-align: left;">
<li>Discussion Forums: Taskflow that integrates the basic functionality to allow discussions on a page</li>
<li>Discussions - Popular topics: Taskflow that shows the popular topics</li>
<li>Discussions - Quick view: A smaller view to list the topics</li>
<li>Discussions - Recent topics: Taskflow that shows a list of the recent topics</li>
<li>Discussions - Watched topics: Taskflow that shows the list of the watched topics from the current user</li>
<li>Discussions - Watched forums: Taskflow that shows the list of the watched forums from the current user</li>
</ol>
<br />
<br />
<br />
<b><u>Webcenter Discussion Forum Programmatic APIs:</u></b><br />
Sometimes, you might get a requirement, where you have requirement to play with code on creating category/discussions/forums. programatically, so giving common APIs used for the same:<br />
<br />
<b>Common code for all:</b><br />
<b><br /></b>
import oracle.webcenter.collab.announcement.AnnouncementFilter;<br />
import oracle.webcenter.collab.announcement.AnnouncementService;<br />
import oracle.webcenter.collab.announcement.AnnouncementSession;<br />
import oracle.webcenter.collab.forum.Category;<br />
import oracle.webcenter.collab.forum.CategoryService;<br />
import oracle.webcenter.collab.forum.Forum;<br />
import oracle.webcenter.collab.forum.ForumService;<br />
import oracle.webcenter.collab.forum.ForumSession;<br />
import oracle.webcenter.collab.forum.MyDiscussionsService;<br />
<br />
<br />
public ForumSession session = null;<br />
public CategoryService catService = null;<br />
public ForumService forumService = null;<br />
<br />
<br />
<b>Category</b><br />
catService = (CategoryService)session.getService(CategoryService.class); <br />
Category newCreatedCategory = catService.createCategory(null, new Long(parentCategoryId).toString(),categoryName, categoryName, categoryName);<br />
categoryId = Long.parseLong(newCreatedCategory.getId());<br />
<br />
catService = (CategoryService)session.getService(CategoryService.class);<br />
long rootCategoryId = Long.parseLong(catService.getRootCategoryId());<br />
<br />
<br />
<b>Forum</b><br />
List<forum> forums = catService.getForums(new Long(categoryId).toString(), null,true);</forum><br />
forumService = (ForumService)session.getService(ForumService.class);<br />
Forum newCreatedForum = forumService.createForum(null,new Long(RootCategoryId).toString(),TopicName, TopicName, TopicName);<br />
forumId = Long.parseLong(newCreatedForum.getId());<br />
Forum forum = forumService.getForum(new Long(forumId).toString());<br />
long topicCount = forum.getTopicCount();<br />
<br />
<br />
I hope this article gives you a clear picture of discussion forums service in webcentre.<br />
<br /></div>
Mukul Guptahttp://www.blogger.com/profile/05550600691296960397noreply@blogger.com44tag:blogger.com,1999:blog-4890411074348189661.post-13498325077886861042012-07-07T00:43:00.001-07:002012-07-07T00:43:49.813-07:00Proxy or DataControl with webservices in ADF<div dir="ltr" style="text-align: left;" trbidi="on">
A recent article by Frank in Oracle Magzine issue July/August 2012 , provides a clear insight and guidelines, about which approach one should take while interacting with web services in an ADF application : <br />
<a href="http://www.oracle.com/technetwork/issue-archive/2012/12-jul/o42adf-1653060.html" target="_blank">Frank's Article.</a><br />
<br />
<br />
</div>Mukul Guptahttp://www.blogger.com/profile/05550600691296960397noreply@blogger.com6tag:blogger.com,1999:blog-4890411074348189661.post-35775230117799069752012-06-19T08:22:00.000-07:002012-06-19T08:23:31.122-07:00ExecuteWithParams in ADF 11g<div dir="ltr" style="text-align: left;" trbidi="on">
A small post after a long time regarding "ExecuteWithParams" operation with VO. Most of the time, since coming from OAF background I usually write small methods in AM implementation class and expose it to view controller layer using interface and then drag and drop it as a binding layer in my ADF page.<br />
<br />
But recently was struck, when tried to ease my work using ExecuteWithParams drag and drop directly and assign the bind variable value from pageFlowScope.I worked for almost 4 hours tried all sorts of debugging but everytime when my bounded taskflow reaches executewithparams activity , i use to get error code like :<br />
JBO 27122 error and the exception message like "Missing IN or OUT parameter at index:: 1 " error. <br />
<br />
Generally happens with me :) , whenever try to ease my work , some innovative error comes in... ! But anyways after a careful review of the VO xml files and comparing with old code where I have used this operation many times I came to the conclusion : There are two kinds of bind variables: "where" and "viewcriteria". While editing my viewobjects I accidentally created a variable of the kind "viewcriteria", which means that it cannot be used in the where clause of the sqlquery, but only in a viewcriteria. When you create a "where" variable, you are allowed to use it in the where clause of your query.This all makes sense, but the GUI for editing the variables does NOT show the difference. <br />
<br />
So if you run into the error above, look inside the XML of your viewobject for your variable and if you see Kind="viewcriteria", then change it to Kind="where" and try again and your code should work fine.</div>Mukul Guptahttp://www.blogger.com/profile/05550600691296960397noreply@blogger.com3tag:blogger.com,1999:blog-4890411074348189661.post-44836401611059252162012-04-23T03:40:00.001-07:002012-05-18T12:29:57.241-07:00Weblogic Vs Jdeveloper 11g<div dir="ltr" style="text-align: left;" trbidi="on">
An interesting post on Timo Hohn's blog , which helps to avoid different version(s) of ADF Jdeveloper and Weblogic server :<br />
<br />
<a href="http://tompeez.wordpress.com/2011/09/14/jdeveloper-versions-vs-weblogic-server-versions/">http://tompeez.wordpress.com/2011/09/14/jdeveloper-versions-vs-weblogic-server-versions/</a></div>Mukul Guptahttp://www.blogger.com/profile/05550600691296960397noreply@blogger.com85tag:blogger.com,1999:blog-4890411074348189661.post-66183468994016569652010-07-06T23:04:00.000-07:002010-07-20T20:56:09.875-07:00JDBC Connections leakage and optimization in Oracle Apps R12.Identifying issues with JDBC connections in Apps can sometimes be a frustrating process, as the investigations may need to consider multiple failure points and complex architectures. I hope this article will give you a better understanding of JDBC Pooling and where to start looking for issues. Hopefully this article should help system and technical architects in Apps to resolve connection leak problems.<br /><br /> Recently while working with Oracle MEA in world's first major implementation of CMRO module in Apps, we faced some critical performance issues, initially. One of the major performance issue was <span style="font-weight:bold;">"JDBC connections leakage"</span>. Over a period the <span style="font-weight:bold;">"INACTIVE"</span> jdbc connections rise and finally they cross the maximum jdbc connections figure set in database and server goes down. The immediate solution was bouncing OC4J Core and HTTP containers of Oracle Apps application server 10g, but off-course this is something you can not do daily in a production environment.<br /><br /> Since our implementation layer has a strong layer of custom code and standard code , done by various teams and you don't have control on coding of individual new developers. I thought it is next to impossible to identify root cause and fix it ,but thanks to Oracle... in Apps there are some standard ways to fix this problem. <br /><br /> Ok to start with lets start with some basic definitions and facts to understand the problem , I am talking about here :<br /><br /><br /><span style="font-weight:bold;">What is JDBC ?</span><br />The Java Database Connectivity (JDBC) API is the industry standard for database-independent connectivity between the Java programming language and a wide range of databases – SQL databases(Oracle,mysql etc) and other tabular data sources, such as spreadsheets or flat files. The JDBC API provides a call-level API for SQL-based database access.<br /> <br /><span style="font-weight:bold;">What is JDBC Connection ?</span><br />Java JDBC APIs uses connection (session) instance in which SQL statements are executed and results are returned within the context of a connection.<br /><br /><span style="font-weight:bold;">What is JDBC Connection pool?</span><br />If you have used a SQL or other similar tool to connect to a database and act on the data, you probably know that getting the connection and logging in is the part that takes the most time. An application can easily spend several seconds every time it needs to establish a connection.<br /><br />In releases prior to JDBC 2.0 every database session requires a new connection and login even if the previous connection and login used the same table and user account. If you are using a JDBC release prior to 2.0 and want to improve performance, you can cache JDBC connections instead.<br /><br />Cached connections are kept in a runtime object pool and can be used and reused as needed by the application. One way to implement the object pool is to make a simple hashtable of connection objects. <br /><br /><span style="font-weight:bold;">What is Connection leakage ?</span><br />An application(basically application server) is said to be leaking connection, if it acquires a connection and does not close it within specified time period. If this feature is enabled, the application server detects these potential connection leaks and dumps the leak tracing logs to server logs. Looking at the logs the user can figure out which application is leaking connection and fix the issues with application, if exists.<br /><br /><span style="font-weight:bold;">What is Connection locks ?</span><br />If your are doing multiple DML jdbc transactions in your code with autocommit flag as false on the connection object,the jdbc connection remains locked till the time commit is issued specifically.(By default in OAF/JTF the autocommit flag is false.)<br /><br /><br /><span style="font-weight:bold;">How to identify that Apps instance has connection leakage problem ?</span><br /><br />You can run the following sql statement occasionaly to monitor jdbc connections<br />behaviour :<br /><span style="font-weight:bold;"><br />select s.machine, s.username, s.module, s.inst_id, count(*) how_many<br />from (select distinct PROGRAM, PADDR, machine, username, module, inst_id from gV$SESSION) s,<br /> gv$process p<br />where s.paddr = p.addr<br />and p.inst_id = s.inst_id<br />group by s.machine,s.username, s.module, s.inst_id<br /></span><br /><br />This will list down number of jdbc connections in each module. For OAF, the module is shown as page AM and for JTF/JTT/JSP, the JDBC connections are listed in "JDBC Thin Client". You can keep of track of connections in each module mainly ("JDBC Thin Client"), if this is growing each day. You can also check the status of these connections in v$session if its "INACTIVE" and these connections are persisting for more than 24-48 hours, means these sum up to connection leakage. <br /><br /> For OA Framework calls AOL/J when it needs a database connection, and it is up to OAF to release any such connection when it has finished with it. There is an added complexity, in that OAF also has its own pooling mechanism for the OAF Pages, which is the "Application Module pool" (AM pool). This means that although a user may have finished with a page, the page and its associated database connection are retained for a period of time.<span style="font-weight:bold;">So, generally this layer would not have problem, because developer does not have to release/close connection in his code, that is automatically taken care by framework depending upon AM instance pooling and Database Connection Pooling enabled on the instance.</span><br /> <br /> AOL/J JDBC code is the code that handles JDBC connection, it is often the first area to be blamed, but the JDBC connection pool can only drop database connections where the calling application has released the JDBC connection it holds in the pool, so it often turns out to be an issue higher up the code stack.<span style="font-weight:bold;">This layer covers all yours JSP/JTT/JTF layer and 99% of the cases is responsible for connections leaks.</span><br /><br /><span style="font-weight:bold;">How to track leaked and locked connections?</span><br />Once you see that your instance has a problem of growing jdbc connections over a period of time all with inactive status for more than 24-48 hours, you will now start to debug and find the exact leaked and locked connections.To gather JDBC Connection statics , do following steps :<br />1) We need to first identify number of OACORE processes running on apps application server, then on each OACORE process we will check number of leaked locked jdbc connections in Apps instance.To note the number of OACORE processes , we need to do following in Unix box of each application server node :<br /><br /> (i) Login to Apps Application server unix box using ftp tool like putty.<br /> (ii) cd $ADMIN_SCRIPTS_HOME<br /> (iii) adoacorectl.sh status <br /> <br /> The output will look like :<br /><br />Processes in Instance: <instance name><br />---------------------------------+--------------------+---------+---------<br />ias-component | process-type | pid | status<br />---------------------------------+--------------------+---------+---------<br />OC4JGroup:default_group | OC4J:oafm | 21894 | Alive<br />OC4JGroup:default_group | OC4J:forms | 21861 | Alive<br />OC4JGroup:default_group | OC4J:oacore | 21775 | Alive<br />OC4JGroup:default_group | OC4J:oacore | 21776 | Alive<br />HTTP_Server | HTTP_Server | 21699 | Alive<br /><br /> From this we can analyse that there are two OCCore processes running with process id<br />21775 and 21776 .<br /><br /><span style="font-weight:bold;">Please note in case of multi-node enviorment i.e. Application server with multiple nodes,you will have to run this command individually on each node to get the OACORE process id(s) for that node.</span><br /><br />2) Enable FND Diagnostics profile at your user level.<br /><br />3) Login into Apps instance, on home page click "About This Page" link.<br /><br />4)Go to subtab "Java System Properties" and note "CLIENT_PROCESSID" from the<br /> table, this will be one of what you got in step 1.<br /><br />5) Now in the url type : http://< host >:< port >/OA_HTML/jsp/fnd/AoljDbcPoolStatus.jsp<br /><br />6) This will display you the list of leaked and locked connections for the process id you got in step 3. For leaked connections if you will click the hyperlink, you will also get detailed stack for each leaked connection , which can furthur help you<br />in identifying the code layer where connection leak is happening.<br /><br /><br /> <span style="font-weight:bold;"> You need to repeat step (3) and (4) again and again each time logging out and closing the browser to track all the CLIENT_PROCESSID locked and leaked connections.<br /></span><br /><br /> <span style="font-weight:bold;">How to get the root cause/code that is causing this connection leak ?</span><br /> Actually AoljDbcPoolStatus.jsp is the key to resolve this problem and leaked connection stack will help us to figure out our problem.We can make following conclusions from the stack :<br /><br />1) The first obvious thing you will want to look at is that whether or not your custom code is causing this problem. Thats easy just search the stack with ur custom top name eg- all your extensions lie in lets say xxabc folder under $JAVA_TOP, then you can search xxabc in leak connection stack, that will give you pointers of class and code where this connection is instantiated and later not released/closed.<br /><br />2) For custom and standard jsp(s), search the stack with "_" as all jsp classes in apps are compiled as "_" pre-fixed to the jsp name. So this can give you idea where and which jsp are leaking connections.<span style="font-weight:bold;"> In my experience, this is the layer where most developers make mistakes.</span><br /><br />3) Lastly if not custom class then standard classes are doing this (This is a rare case), and for this you anyways just have to raise an SR with Oracle to fix this. To identify search stacks and see its coming from which module i.e., the stack will we like oracle.apps.<span style="font-weight:bold;">per</span>.xxx.yyy or oracle.apps.<span style="font-weight:bold;">icx</span>.yyy.zzzz , this simple points you that per=> HRMS or ICX=> I-procurement module standard class is causing this problem. <span style="font-weight:bold;">Its always good to decompile and look at the code of these classes because often developers do invaisive customization to Oracle code, directly changing the seeded Oracle file to take easy way to their customizations , without realising that this can later cause bigger problems.</span><br /><br /><span style="font-weight:bold;"><span style="font-style:italic;">Hopefully these analysis will help you to fix root cause of connection leakage problem.</span> </span>Mukul Guptahttp://www.blogger.com/profile/05550600691296960397noreply@blogger.com10tag:blogger.com,1999:blog-4890411074348189661.post-31524322620496751452010-04-07T02:37:00.000-07:002010-06-09T01:18:22.903-07:00Adding programmatic fire Action to UIX beans which dont support itRecently, a friend had a requirement of a customization in a seeded page where he needs to put some validation on a table column which was actually OAMessageDateFieldBean.<br /><br /> This is quite simple and generic requirement , when he called me ...I told him that since , this has to be done in seeded Oracle page and fire action elements can't be added by personalization,he just needs to extend the CO and attach fire action programatically to the OAMessageDateFieldBean in process request and then can handle his logic of validation in process form request.<span style="font-weight:bold;">But the tricky part came when he told me his code is not compiling since setFireActionForSubmit API is absent in OAMessageDateFieldBean class.</span><br /><br /> I just wondered how is it possible since this bean allows me to configure fireaction decalaratively, then there should be an API of doing it programatically too in the bean. <span style="font-weight:bold;">Then I remebered with each UIX bean Oracle also gives a helper class, which can usually be instantiated by using getHelper(), on the bean instance.</span><br /><br /> Whenever you are in such situations , its worth while to look into bean helper classes. Ok.. so here is the code how you can configure firection on OAMessageDateFieldBean programatically :<br /><br />//In process request.<br /><br />//getting table bean instance<br />OATableBean t=(OATableBean)webBean.findChildRecursive("< table bean id >");<br /><br />//getting OAMessageDateFieldBean inside <br />//table bean<br />OAMessageDateFieldBean expDate = (OAMessageDateFieldBean)t.findChildRecursive("< OAMessageDateFieldBean id >");<br /><br />//hard-parameters for fire action<br />//it will help us to identify if action<br />//has occured or not<br /> Hashtable params = new Hashtable (1);<br /> params.put ("XX_ACTION","XXX");<br /><br />//bound value parameters for fire action<br />// basically the primary key attribute of<br />//VO to get the row from which action has occured <br />//eg, lets say the VO attribute is Visit id AND<br />//that is primary key <br />Hashtable paramsWithBinds = new Hashtable(1);<br />paramsWithBinds.put ("XX_PRIMARY",new OADataBoundValueFireActionURL((OAWebBeanData) expDate, "{$VisitId}"));<br /> <br />//Most important---<br />//taking helper class instance<br />// there we get the API to attach fire action.<br />expDate.getHelper().setFireActionForSubmit(expDate,"delete",params, paramsWithBinds,false,false);<br /> <br />//In Process form request<br /><br />if(pageContext.getParameter("XX_ACTION")!=null)<br /> {<br /> //by this primary key we can retrieve the VO row at which<br /> // action occured and utilise the other column data<br /> // for validations.<br /> String primary_key=pageContext.getParameter("XX_PRIMARY");<br /><br /> .......<br /><br /> //finally releasing the parameters from<br /> //current pagecontext requesr<br /> pagecontext.removeParameter("XX_ACTION");<br /> pagecontext.removeParameter("XX_PRIMARY");<br /> }<br /><br /><br /><br /><span style="font-weight:bold;">Alternative : There is a alternate way to attach PPR/Fireaction to any bean.Use static methods in class OAWebBeanUtils, like <br /> OAWebBeanUtils.getFirePartialActionForSubmit()<br /> OAWebBeanUtils.getFireActionForSubmit()<br />and then use <br /></span><br />// finally set it on your bean<br />bean.setAttributeValue<br />(PRIMARY_CLIENT_ACTION_ATTR, fireAction);<br /> <br />Happy coding....!Mukul Guptahttp://www.blogger.com/profile/05550600691296960397noreply@blogger.com10tag:blogger.com,1999:blog-4890411074348189661.post-64517837564699757012010-03-17T02:41:00.000-07:002010-06-09T01:18:22.903-07:00Concept of Nested AM.Hi All,<br /> Writing a theoretical article after a long time. What inspired me to write.... hmm... lot of questioning developers :) . Ok, my target with this article is to make an OA Framework developer understand what is nested AM? and how can u find a nested AM instance from master/root AM instance? What we should know about it while developing extensions or new pages.<br /><br /><strong>What is a Nested AM?</strong><br />--------------------------------------<br />An application module may be a root application module or a nested application module. A root application module is not contained in another applicatin module. It provides transaction context for all objects contained in it. It may optionally contain nested application modules. A root application module is created through JNDI calls. <br /><br /><strong>A nested application module is contained in another application module.</strong> The containing application module is referred to as the parent application module. If one traverses this containership ancestry, one will eventually find the root application module (which does not have a parent application module). A nested application module uses the transaction context provided by the root application module. Thus, data modifications performed in application modules parented by one root application module will commit or rollback together.<br /><br /><strong>Transaction</strong><br />-----------------------------<br />Associated with the root application module is the Transaction object, which provides this transaction context. From any (root or nested) application module, the user can retrieve the transaction object through a call to getOADBTransaction(). In reality, getOADBTransaction() first locates the root application module and then returns the transaction object from it.<br /><br />The transaction object manages connection to database and entity caches. Thus, changes made through one view object are visible to other view objects as long as these view objects all parented by the one root application module. In contrast, if two view objects are parented by two separate root application modules, then changes made through the view object will not be seen by the second view object until the changes are committed to database through the first root application module and the second VO executes query (to retrieve the most up-to-date data from database).<br /><br /><strong>Creating Application Module</strong><br />--------------------------------------------------------------------<br />A root application module is created by:<br /><br />Finding the application module home through JNDI. <br />Calling create() on the application module home. <br />Here is a sample code to create a root application module:<br /><br /> java.util.Hashtable env = new java.util.Hashtable();<br /><br /> // Add environment entries into env...<br /><br /> javax.naming.Context ic = new InitialContext(env);<br /><br /> // 'defName' is the JNDI name for the application module<br /> // definition from which the root application module is to<br /> // be created<br /> String defName = ...;<br /><br /> oracle.jbo.ApplicationModuleHome home = ic.lookup(defName);<br /> oracle.jbo.ApplicationModule am = home.create();<br /> <br /><br />One creates a nested application module by calling createApplicationModule on the parent Application module.<br /><br /><strong>How nested AM concept works in OAF :</strong><br />---------------------------------------------------------------------------<br /> Now to associate a nested application module with a region,<br />specify either of the following properties:<br />1) AM Instance -- The application module instance name as specified in the application module's data<br />model. For example, PoSummaryAM1.<br />2) AM Definition -- The fully qualified name of the application module instance. For example,<br />oracle.apps.fnd.framework.toolbox.tutorial.server.PoSummaryAM.<br /><br /> <strong>If you specify the AM Instance property, OA Framework attempts to find and return the AM instance with the given name. It searches the application module associated with the parent web bean.</strong><br /> If you specify the AM Definition property, OA Framework assigns a generated AM instance name to the nested region. This name is comprised of the following values:<br />a) Region code of the associated nested region (if the region was originally created in AK)<br />b) Nested region application ID<br />c) Nested region ID<br />d) AM definition name.<br /><br /><strong>OA Framework checks to see if the nested AM with the system-generated name has been already created under the application module of the parent web bean. If the instance is not found, OA Framework creates and uses a nested AM with the system-generated name. Otherwise, it reuses the pre-existing AM with the system generated<br />name.</strong><br /><br /> <strong>When specifying both the AM Instance and AM Definition properties<br />if a matching AM instance is found, OA Framework compares its definition with the AM Definition property value. If there is a mismatch, OA Framework throws an exception.<br />If a matching AM instance is not found, OA Framework creates and returns a nested application module instance with the given AM instance name and the definition.</strong><br /><br /><strong>Code for finding nested AM instance in root AM :</strong><br />-----------------------------------------------------------------------------------<br /> Hence, whenever you are trying to find an nested AM instance linked to a OA region under pagelayout region, please check the am defination and am instance property of that region, because only then you would be able to have a idea of name of nested AM instance. It can be system generated AM instance or name given by developer for AM instance.So, you need to confirm this from the three cases mentioned in the previous article.<strong>For debugging purposes, you can get the list if Application modules in root AM and print there names ,too :<br /><br /> String[] nestedAMNames = parentAM.getApplicationModuleNames();<br /><br /> // If you want to retrieve all currently loaded nested Application Modules<br /> ApplicationModule[] nestedAMs = new ApplicationModule[nestedAMNames.length];<br /><br /> for (int i = 0; i < nestedAMNames.length; i++)<br /> {<br /> nestedAM[i] = parentAM.findApplicationModule(nestedAMNames[i]);<br /> }<br /> </strong><br /><br /><br /> Otherwise for finding nested AM instance by :<br />ApplicationModule nestedAM = parentAM.findApplicationModule("MyNestedAM");<br /><br />This concept is really helpful while doing extensions in OAF, as you may have to find a nested AM in a CO of particular OAF region.You can always find root AM of the page in any controller using pagecontext.getRootApplicationModule().<br /><br /> I hope after reading this article nested AM conecept becomes crystal clear in your mind :), if not raise queries, and I will try to answer you.Mukul Guptahttp://www.blogger.com/profile/05550600691296960397noreply@blogger.com2tag:blogger.com,1999:blog-4890411074348189661.post-49166962976029731522010-02-03T23:51:00.000-08:002010-06-09T01:18:22.904-07:00Attaching AutoSubmit Property to a OA page.Hi All,<br /> I recently received couple of mails where people more or less have the requirement like :<br />1) Data of the page gets refresh every 10 sec automatically.<br />2) Data of the page should be autosaved every 10 seconds etc.<br /><br /> This is very similar to <span style="font-weight:bold;">autosave feature</span> of microsoft word or popular email websites like yahoo and google. A small javascript function can do this for you.Here are the steps how, you can achieve this functionality in an OAF page :<br /><br /> /**<br /> * @param pageContext -current page context in CO<br /> * @param evt_name - javascript event will be registered with this name.<br /> * @param time_in_milli_sec - time in milli sec after which page will refresh<br /> * e.g if you wanna submit page every 10 sec , enter 10000<br /> * This api should be used in process request and not process form request. <br /> */<br /> public void attachAutoSubmitPropertyToPage(OAPageContext pageContext, <br /> String evt_name, <br /> String time_in_milli_sec)<br /> {<br /> OABodyBean bodyBean = (OABodyBean) pageContext.getRootWebBean();<br /> String javaS = <br /> "javascript:setTimeout(\"submitForm('DefaultFormName',0,{'" + <br /> evt_name + "':'Y'});\"," + time_in_milli_sec + ");";<br /> bodyBean.setOnLoad(javaS);<br /> }<br /><br /> /**<br /> * @param pageContext -current page context in CO<br /> * @param event_name - pass javascript event name that you registered<br /> * in process request.<br /> * @return return true/false accordinging whether the event has occured or not.<br /> * This api call should be there in process form request.<br /> */<br /> public boolean isAutoSubmitEvent(OAPageContext pageContext, <br /> String event_name)<br /> {<br /> boolean b = false;<br /> String s = <br /> pageContext.getRenderingContext().getServletRequest().getParameter(event_name);<br /> if (!((s == null) || ("".equals(s.trim()))))<br /> {<br /> if("Y".equals(s))<br /> {<br /> b = true;<br /> pageContext.removeParameter(event_name);<br /> } <br /> }<br /> return b;<br /> }<br /><br />Then , in process request add the api call<br /><br />public void processRequest(OAPageContext pageContext, OAWebBean webBean)<br />{<br />super.processRequest(pageContext, webBean);<br />// see javadocs for parameter description<br />//10000 for 10 sec as we are paaing in millsec<br />attachAutoSubmitPropertyToPage(pageContext,"XX_EVT","10000");<br /><br />.<br />.<br />.<br />}<br /><br /><br /><br />In process form request... you can catch this event in every 10 sec:<br />public void processFormRequest(OAPageContext pageContext,<br />OAWebBean webBean)<br />{<br />super.processFormRequest(pageContext, webBean);<br />.<br />.<br /><br />if(isAutoSubmitEvent(pageContext,"XX_EVT"))<br />{<br />// YOUR LOGIC TO SAVE THE PAGE CONTENTS.<br />//or to refresh the data... etc<br />}<br /><br />I hope this is interesting and will help developers of such kind of requirement.<br /> Happy Coding..!Mukul Guptahttp://www.blogger.com/profile/05550600691296960397noreply@blogger.com9tag:blogger.com,1999:blog-4890411074348189661.post-14323608058962609902010-01-12T22:12:00.000-08:002010-06-09T01:18:22.904-07:00Upload file to Application server using OAFileUploadBean instead of DatabaseSometimes, there can be requirement , where you need to upload a file on unix server, instead of database.You can use OAMessageFileUploadBean for this. Add the upload bean in your OAF UIX page. Add an additional submit button bean which will be responsible for file Upload.<br /> On click on this button in process form request call the following method with parameters as described in CO. So, copy this method in CO and then call it in process form request on this submit button click like<br /> <br />uploadFileToServer(pageContext, "item3", <br /> "/xx/app/sss/x");<br /> <br /><br />Here is the method for upload:<br /> /**<br /> * @param pageContext is current pagecontext in CO<br /> * @param fileuploadBeanId is item id of file upload bean<br /> * @param server_dir_path is abslute path on unix server<br /> * where file needs to be written.eg "/xx/xxx/xxx"<br /> */<br /> public void uploadFileToServer(OAPageContext pageContext, <br /> String fileuploadBeanId, <br /> String server_dir_path)<br /> {<br /> DataObject fileUploadData = <br /> (DataObject) pageContext.getNamedDataObject(fileuploadBeanId);<br /> if(fileUploadData!=null)<br /> {<br /> String uFileName = <br /> (String) fileUploadData.selectValue(null, "UPLOAD_FILE_NAME");<br /> String contentType = <br /> (String) fileUploadData.selectValue(null, "UPLOAD_FILE_MIME_TYPE");<br /><br /> File file = new File(server_dir_path, uFileName);<br /> FileOutputStream output = null;<br /> InputStream input = null;<br /> try<br /> {<br /> output = new FileOutputStream(file);<br /> BlobDomain uploadedByteStream = <br /> (BlobDomain) fileUploadData.selectValue(null, uFileName);<br /> input = uploadedByteStream.getInputStream();<br /> for (int bytes = 0; bytes < uploadedByteStream.getLength(); bytes++)<br /> {<br /> output.write(input.read());<br /> }<br /> }<br /> catch (Exception e)<br /> {<br /> e.printStackTrace();<br /> }<br /> finally<br /> {<br /> try<br /> {<br /> if (input != null)<br /> {<br /> input.close();<br /> }<br /> if (output != null)<br /> {<br /> output.close();<br /> output.flush();<br /> }<br /> }<br /> catch (Exception ez)<br /> {<br /> ez.printStackTrace();<br /> }<br /> }<br /> <br /> }<br /> }<br /><br /><strong>Please understand when you run a page from jdeveloper, you are running page on local oc4j server of jdeveloper and not the actual application server of Oracle Apps, hence if this code is run from jdeveloper then you need to give path of your local desktop folder and file will be uploaded in it and not the actual application server.<br />To test this code actually you should deploy your page onto Oracle apps application server and access the page from a responsibility by registering it as a function , because then it will use Oracle Apps Application Unix server and upload file there. </strong><br />Happy coding ...!<strong></strong>Mukul Guptahttp://www.blogger.com/profile/05550600691296960397noreply@blogger.com36tag:blogger.com,1999:blog-4890411074348189661.post-37966469758902257942010-01-05T23:06:00.000-08:002010-06-09T01:18:22.904-07:00Giving download option to user for a file at a particular location on Application ServerHi All,<br /> This is a very generic scenario where a user wants to download a particular file from application server. eg- We are storing some report output or some pdf documents in particular location in unix application server. Now in a OAF page on press of a button/link I wanna give user download option for this file. <br /><br /> For this requirement you can use following method, from process form request, u need to pass pagecontext and other parameters as described in method.<br /><br />//on button click in process form request<br />//call this method<br />downloadFileFromServer(<br /> pageContext,--pagecontext <br /> "/xx/xxx/ssss/120devg.pdf",--full file path with file name and ext <br /> "120devg.pdf" --file name with extension<br /> ); <br /><br /><span style="font-weight:bold;">Make sure that the folder/files you are giving user option to download through this method, have 777 rights in UNIX server.</span><br /><br />Copy these two methods in your CO for the above API to work:<br /> /**<br /> * @param pageContext the current OA page context<br /> * @param file_name_with_path - this is fully qualified file name with its path on unix application<br /> * server. eg "/xxcrp/xxapplcrp/mukul/abc.pdf"<br /> * @param file_name_with_ext - this is file name with extension, you wanna display user<br /> * for download. eg- i wanna display the abc.pdf file download with name five_point_someone.pdf<br /> * then I can pass this as "five_point_someone.pdf"<br /> */<br /> public void downloadFileFromServer(OAPageContext pageContext, <br /> String file_name_with_path, <br /> String file_name_with_ext)<br /> {<br /> HttpServletResponse response = <br /> (HttpServletResponse) pageContext.getRenderingContext().getServletResponse();<br /> if (((file_name_with_path == null) || <br /> ("".equals(file_name_with_path))))<br /> {<br /> throw new OAException("File path is invalid.");<br /> }<br /><br /> File fileToDownload = null;<br /> try<br /> {<br /> fileToDownload = new File(file_name_with_path);<br /> }<br /> catch (Exception e)<br /> {<br /> throw new OAException("Invalid File Path or file does not exist.");<br /> }<br /><br /> if (!fileToDownload.exists())<br /> {<br /> throw new OAException("File does not exist.");<br /> }<br /><br /> if (!fileToDownload.canRead())<br /> {<br /> throw new OAException("Not Able to read the file.");<br /> }<br /><br /> String fileType = getMimeType(file_name_with_ext);<br /> response.setContentType(fileType);<br /> response.setContentLength((int)fileToDownload.length()); <br /> response.setHeader("Content-Disposition", <br /> "attachment; filename=\"" + file_name_with_ext + <br /> "\"");<br /><br /> InputStream in = null;<br /> ServletOutputStream outs = null;<br /><br /> try<br /> {<br /> outs = response.getOutputStream();<br /> in = new BufferedInputStream(new FileInputStream(fileToDownload));<br /> int ch;<br /> while ((ch = in.read()) != -1)<br /> {<br /> outs.write(ch);<br /> }<br /><br /> }<br /> catch (IOException e)<br /> {<br /> // TODO<br /> e.printStackTrace();<br /> }<br /> finally<br /> {<br /> try<br /> {<br /> outs.flush();<br /> outs.close();<br /> if (in != null)<br /> {<br /> in.close();<br /> }<br /> }<br /> catch (Exception e)<br /> {<br /> e.printStackTrace();<br /> }<br /> }<br /> }<br /><br /> /**<br /> * @param s<br /> * @return file mime type from its name<br /> */<br /> public String getMimeType(String s)<br /> {<br /> int i = s.lastIndexOf(".");<br /> if (i > 0 && i < s.length() - 1)<br /> {<br /> String s1 = s.substring(i + 1);<br /> if (s1.equalsIgnoreCase("amr"))<br /> {<br /> return "audio/amr";<br /> }<br /> if (s1.equalsIgnoreCase("mid"))<br /> {<br /> return "audio/midi";<br /> }<br /> if (s1.equalsIgnoreCase("mmf"))<br /> {<br /> return "application/vnd.smaf";<br /> }<br /> if (s1.equalsIgnoreCase("qcp"))<br /> {<br /> return "audio/vnd.qcelp";<br /> }<br /> if (s1.equalsIgnoreCase("hqx"))<br /> {<br /> return "application/mac-binhex40";<br /> }<br /> if (s1.equalsIgnoreCase("cpt"))<br /> {<br /> return "application/mac-compactpro";<br /> }<br /> if (s1.equalsIgnoreCase("doc"))<br /> {<br /> return "application/msword";<br /> }<br /> if (s1.equalsIgnoreCase("jsp"))<br /> {<br /> return "application/jsp";<br /> }<br /> if (s1.equalsIgnoreCase("oda"))<br /> {<br /> return "application/oda";<br /> }<br /> if (s1.equalsIgnoreCase("pdf"))<br /> {<br /> return "application/pdf";<br /> }<br /> if (s1.equalsIgnoreCase("ai"))<br /> {<br /> return "application/postscript";<br /> }<br /> if (s1.equalsIgnoreCase("eps"))<br /> {<br /> return "application/postscript";<br /> }<br /> if (s1.equalsIgnoreCase("ps"))<br /> {<br /> return "application/postscript";<br /> }<br /> if (s1.equalsIgnoreCase("ppt"))<br /> {<br /> return "application/powerpoint";<br /> }<br /> if (s1.equalsIgnoreCase("rtf"))<br /> {<br /> return "application/rtf";<br /> }<br /> if (s1.equalsIgnoreCase("bcpio"))<br /> {<br /> return "application/x-bcpio";<br /> }<br /> if (s1.equalsIgnoreCase("vcd"))<br /> {<br /> return "application/x-cdlink";<br /> }<br /> if (s1.equalsIgnoreCase("Z"))<br /> {<br /> return "application/x-compress";<br /> }<br /> if (s1.equalsIgnoreCase("cpio"))<br /> {<br /> return "application/x-cpio";<br /> }<br /> if (s1.equalsIgnoreCase("csh"))<br /> {<br /> return "application/x-csh";<br /> }<br /> if (s1.equalsIgnoreCase("dcr"))<br /> {<br /> return "application/x-director";<br /> }<br /> if (s1.equalsIgnoreCase("dir"))<br /> {<br /> return "application/x-director";<br /> }<br /> if (s1.equalsIgnoreCase("dxr"))<br /> {<br /> return "application/x-director";<br /> }<br /> if (s1.equalsIgnoreCase("dvi"))<br /> {<br /> return "application/x-dvi";<br /> }<br /> if (s1.equalsIgnoreCase("gtar"))<br /> {<br /> return "application/x-gtar";<br /> }<br /> if (s1.equalsIgnoreCase("gz"))<br /> {<br /> return "application/x-gzip";<br /> }<br /> if (s1.equalsIgnoreCase("hdf"))<br /> {<br /> return "application/x-hdf";<br /> }<br /> if (s1.equalsIgnoreCase("cgi"))<br /> {<br /> return "application/x-httpd-cgi";<br /> }<br /> if (s1.equalsIgnoreCase("jnlp"))<br /> {<br /> return "application/x-java-jnlp-file";<br /> }<br /> if (s1.equalsIgnoreCase("skp"))<br /> {<br /> return "application/x-koan";<br /> }<br /> if (s1.equalsIgnoreCase("skd"))<br /> {<br /> return "application/x-koan";<br /> }<br /> if (s1.equalsIgnoreCase("skt"))<br /> {<br /> return "application/x-koan";<br /> }<br /> if (s1.equalsIgnoreCase("skm"))<br /> {<br /> return "application/x-koan";<br /> }<br /> if (s1.equalsIgnoreCase("latex"))<br /> {<br /> return "application/x-latex";<br /> }<br /> if (s1.equalsIgnoreCase("mif"))<br /> {<br /> return "application/x-mif";<br /> }<br /> if (s1.equalsIgnoreCase("nc"))<br /> {<br /> return "application/x-netcdf";<br /> }<br /> if (s1.equalsIgnoreCase("cdf"))<br /> {<br /> return "application/x-netcdf";<br /> }<br /> if (s1.equalsIgnoreCase("sh"))<br /> {<br /> return "application/x-sh";<br /> }<br /> if (s1.equalsIgnoreCase("shar"))<br /> {<br /> return "application/x-shar";<br /> }<br /> if (s1.equalsIgnoreCase("sit"))<br /> {<br /> return "application/x-stuffit";<br /> }<br /> if (s1.equalsIgnoreCase("sv4cpio"))<br /> {<br /> return "application/x-sv4cpio";<br /> }<br /> if (s1.equalsIgnoreCase("sv4crc"))<br /> {<br /> return "application/x-sv4crc";<br /> }<br /> if (s1.equalsIgnoreCase("tar"))<br /> {<br /> return "application/x-tar";<br /> }<br /> if (s1.equalsIgnoreCase("tcl"))<br /> {<br /> return "application/x-tcl";<br /> }<br /> if (s1.equalsIgnoreCase("tex"))<br /> {<br /> return "application/x-tex";<br /> }<br /> if (s1.equalsIgnoreCase("textinfo"))<br /> {<br /> return "application/x-texinfo";<br /> }<br /> if (s1.equalsIgnoreCase("texi"))<br /> {<br /> return "application/x-texinfo";<br /> }<br /> if (s1.equalsIgnoreCase("t"))<br /> {<br /> return "application/x-troff";<br /> }<br /> if (s1.equalsIgnoreCase("tr"))<br /> {<br /> return "application/x-troff";<br /> }<br /> if (s1.equalsIgnoreCase("roff"))<br /> {<br /> return "application/x-troff";<br /> }<br /> if (s1.equalsIgnoreCase("man"))<br /> {<br /> return "application/x-troff-man";<br /> }<br /> if (s1.equalsIgnoreCase("me"))<br /> {<br /> return "application/x-troff-me";<br /> }<br /> if (s1.equalsIgnoreCase("ms"))<br /> {<br /> return "application/x-troff-ms";<br /> }<br /> if (s1.equalsIgnoreCase("ustar"))<br /> {<br /> return "application/x-ustar";<br /> }<br /> if (s1.equalsIgnoreCase("src"))<br /> {<br /> return "application/x-wais-source";<br /> }<br /> if (s1.equalsIgnoreCase("xml"))<br /> {<br /> return "text/xml";<br /> }<br /> if (s1.equalsIgnoreCase("ent"))<br /> {<br /> return "text/xml";<br /> }<br /> if (s1.equalsIgnoreCase("cat"))<br /> {<br /> return "text/xml";<br /> }<br /> if (s1.equalsIgnoreCase("sty"))<br /> {<br /> return "text/xml";<br /> }<br /> if (s1.equalsIgnoreCase("dtd"))<br /> {<br /> return "text/dtd";<br /> }<br /> if (s1.equalsIgnoreCase("xsl"))<br /> {<br /> return "text/xsl";<br /> }<br /> if (s1.equalsIgnoreCase("zip"))<br /> {<br /> return "application/zip";<br /> }<br /> if (s1.equalsIgnoreCase("au"))<br /> {<br /> return "audio/basic";<br /> }<br /> if (s1.equalsIgnoreCase("snd"))<br /> {<br /> return "audio/basic";<br /> }<br /> if (s1.equalsIgnoreCase("mpga"))<br /> {<br /> return "audio/mpeg";<br /> }<br /> if (s1.equalsIgnoreCase("mp2"))<br /> {<br /> return "audio/mpeg";<br /> }<br /> if (s1.equalsIgnoreCase("mp3"))<br /> {<br /> return "audio/mpeg";<br /> }<br /> if (s1.equalsIgnoreCase("aif"))<br /> {<br /> return "audio/x-aiff";<br /> }<br /> if (s1.equalsIgnoreCase("aiff"))<br /> {<br /> return "audio/x-aiff";<br /> }<br /> if (s1.equalsIgnoreCase("aifc"))<br /> {<br /> return "audio/x-aiff";<br /> }<br /> if (s1.equalsIgnoreCase("ram"))<br /> {<br /> return "audio/x-pn-realaudio";<br /> }<br /> if (s1.equalsIgnoreCase("rpm"))<br /> {<br /> return "audio/x-pn-realaudio-plugin";<br /> }<br /> if (s1.equalsIgnoreCase("ra"))<br /> {<br /> return "audio/x-realaudio";<br /> }<br /> if (s1.equalsIgnoreCase("wav"))<br /> {<br /> return "audio/x-wav";<br /> }<br /> if (s1.equalsIgnoreCase("pdb"))<br /> {<br /> return "chemical/x-pdb";<br /> }<br /> if (s1.equalsIgnoreCase("xyz"))<br /> {<br /> return "chemical/x-pdb";<br /> }<br /> if (s1.equalsIgnoreCase("gif"))<br /> {<br /> return "image/gif";<br /> }<br /> if (s1.equalsIgnoreCase("ief"))<br /> {<br /> return "image/ief";<br /> }<br /> if (s1.equalsIgnoreCase("jpeg"))<br /> {<br /> return "image/jpeg";<br /> }<br /> if (s1.equalsIgnoreCase("jpg"))<br /> {<br /> return "image/jpeg";<br /> }<br /> if (s1.equalsIgnoreCase("jpe"))<br /> {<br /> return "image/jpeg";<br /> }<br /> if (s1.equalsIgnoreCase("png"))<br /> {<br /> return "image/png";<br /> }<br /> if (s1.equalsIgnoreCase("tiff"))<br /> {<br /> return "image/tiff";<br /> }<br /> if (s1.equalsIgnoreCase("tif"))<br /> {<br /> return "image/tiff";<br /> }<br /> if (s1.equalsIgnoreCase("ras"))<br /> {<br /> return "image/x-cmu-raster";<br /> }<br /> if (s1.equalsIgnoreCase("pnm"))<br /> {<br /> return "image/x-portable-anymap";<br /> }<br /> if (s1.equalsIgnoreCase("pbm"))<br /> {<br /> return "image/x-portable-bitmap";<br /> }<br /> if (s1.equalsIgnoreCase("pgm"))<br /> {<br /> return "image/x-portable-graymap";<br /> }<br /> if (s1.equalsIgnoreCase("ppm"))<br /> {<br /> return "image/x-portable-pixmap";<br /> }<br /> if (s1.equalsIgnoreCase("rgb"))<br /> {<br /> return "image/x-rgb";<br /> }<br /> if (s1.equalsIgnoreCase("xbm"))<br /> {<br /> return "image/x-xbitmap";<br /> }<br /> if (s1.equalsIgnoreCase("xpm"))<br /> {<br /> return "image/x-xpixmap";<br /> }<br /> if (s1.equalsIgnoreCase("xwd"))<br /> {<br /> return "image/x-xwindowdump";<br /> }<br /> if (s1.equalsIgnoreCase("html"))<br /> {<br /> return "text/html";<br /> }<br /> if (s1.equalsIgnoreCase("htm"))<br /> {<br /> return "text/html";<br /> }<br /> if (s1.equalsIgnoreCase("txt"))<br /> {<br /> return "text/plain";<br /> }<br /> if (s1.equalsIgnoreCase("rtx"))<br /> {<br /> return "text/richtext";<br /> }<br /> if (s1.equalsIgnoreCase("tsv"))<br /> {<br /> return "text/tab-separated-values";<br /> }<br /> if (s1.equalsIgnoreCase("etx"))<br /> {<br /> return "text/x-setext";<br /> }<br /> if (s1.equalsIgnoreCase("sgml"))<br /> {<br /> return "text/x-sgml";<br /> }<br /> if (s1.equalsIgnoreCase("sgm"))<br /> {<br /> return "text/x-sgml";<br /> }<br /> if (s1.equalsIgnoreCase("mpeg"))<br /> {<br /> return "video/mpeg";<br /> }<br /> if (s1.equalsIgnoreCase("mpg"))<br /> {<br /> return "video/mpeg";<br /> }<br /> if (s1.equalsIgnoreCase("mpe"))<br /> {<br /> return "video/mpeg";<br /> }<br /> if (s1.equalsIgnoreCase("qt"))<br /> {<br /> return "video/quicktime";<br /> }<br /> if (s1.equalsIgnoreCase("mov"))<br /> {<br /> return "video/quicktime";<br /> }<br /> if (s1.equalsIgnoreCase("avi"))<br /> {<br /> return "video/x-msvideo";<br /> }<br /> if (s1.equalsIgnoreCase("movie"))<br /> {<br /> return "video/x-sgi-movie";<br /> }<br /> if (s1.equalsIgnoreCase("ice"))<br /> {<br /> return "x-conference/x-cooltalk";<br /> }<br /> if (s1.equalsIgnoreCase("wrl"))<br /> {<br /> return "x-world/x-vrml";<br /> }<br /> if (s1.equalsIgnoreCase("vrml"))<br /> {<br /> return "x-world/x-vrml";<br /> }<br /> if (s1.equalsIgnoreCase("wml"))<br /> {<br /> return "text/vnd.wap.wml";<br /> }<br /> if (s1.equalsIgnoreCase("wmlc"))<br /> {<br /> return "application/vnd.wap.wmlc";<br /> }<br /> if (s1.equalsIgnoreCase("wmls"))<br /> {<br /> return "text/vnd.wap.wmlscript";<br /> }<br /> if (s1.equalsIgnoreCase("wmlsc"))<br /> {<br /> return "application/vnd.wap.wmlscriptc";<br /> }<br /> if (s1.equalsIgnoreCase("wbmp"))<br /> {<br /> return "image/vnd.wap.wbmp";<br /> }<br /> if (s1.equalsIgnoreCase("css"))<br /> {<br /> return "text/css";<br /> }<br /> if (s1.equalsIgnoreCase("jad"))<br /> {<br /> return "text/vnd.sun.j2me.app-descriptor";<br /> }<br /> if (s1.equalsIgnoreCase("jar"))<br /> {<br /> return "application/java-archive";<br /> }<br /> if (s1.equalsIgnoreCase("3gp"))<br /> {<br /> return "video/3gp";<br /> }<br /> if (s1.equalsIgnoreCase("3g2"))<br /> {<br /> return "video/3gpp2";<br /> }<br /> if (s1.equalsIgnoreCase("mp4"))<br /> {<br /> return "video/3gpp";<br /> }<br /> }<br /> return "application/octet-stream";<br /> }<br /><br />Happy coding...! I hope this helps! :)Mukul Guptahttp://www.blogger.com/profile/05550600691296960397noreply@blogger.com13tag:blogger.com,1999:blog-4890411074348189661.post-5222455246222263612010-01-05T22:46:00.000-08:002010-06-09T01:18:22.904-07:00Implementing Export Button Functionality ProgramaticallyHi All,<br /> There is often a requirement to export a VO data or a UI table data into a CSV file. OA Framework provides export button bean for the this functionality, which works fine in almost 99% of the cases. But sometimes, you might face a scenario when ur table u have complex UIs like switcher/hide show columns etc, where the standard export functionality doesn't work or you want some columns not to come in export, or you wanna change some data on export.<br /><br />In such cases, you can implement the export functionality programatically by yourself.Copy paste the following method in the page CO and pass appropriate parameters to get exported data.You can change this method, as per your requirement, to get data/format data or change data.<br /><br /> By default this method will bring all columns of fetch rows of VO instance,although you can use <strong>param hidden_attrib_list</strong> to pass attributes which you don't want to be included in csv file.You can call this method in the submit button event that you have made in process form request like :<br /><br />//see api parameter details in the method below.<br />//array of Vo attr names which need not be written in csv file<br />String ss[]={xID,xName};<br />downloadCsvFile(pageContext, "XxAdatVisSearchVO",null, "MAX",ss); <br /><br /> /**<br /> * @param pageContext <br /> * @param view_inst_name is the view object instance name like VO1 etc in root AM.<br /> * Make sure the VO instance name you have passed should be same as in Root AM.<br /> * @param file_name_without_ext - pass for eg for abc.csv , u should pass "abc".If no<br /> * name is passed then by default it will pick "Export.csv".<br /> * @param max_size -pass "MAX", if u want all rows, pass null to get fetch row count<br /> * else pass integer number like 10,20 etc , the number of rows you want to fetch.<br /> * @param hidden_attrib_list -Array of VO attribute names which doesn't need to be shown/written in<br /> * csv file.<br /> */<br /> public void downloadCsvFile(OAPageContext pageContext, <br /> String view_inst_name, <br /> String file_name_without_ext, <br /> String max_size, String[] hidden_attrib_list)<br /> {<br /> OAViewObject v = <br /> (OAViewObject) pageContext.getRootApplicationModule().findViewObject(view_inst_name);<br /><br /> if (v == null)<br /> {<br /> throw new OAException("Could not find View object instance " + <br /> view_inst_name + " in root AM.");<br /> }<br /> if (v.getFetchedRowCount() == 0)<br /> {<br /> throw new OAException("There is no data to export.");<br /> }<br /> String file_name = "Export";<br /> if (!((file_name_without_ext == null) || <br /> ("".equals(file_name_without_ext))))<br /> {<br /> file_name = file_name_without_ext;<br /> }<br /> HttpServletResponse response = <br /> (HttpServletResponse) pageContext.getRenderingContext().getServletResponse();<br /> response.setContentType("application/text");<br /> response.setHeader("Content-Disposition", <br /> "attachment; filename=" + file_name + ".csv");<br /> PrintWriter pw = null;<br /><br /> try<br /> {<br /> pw = response.getWriter();<br /> int j = 0;<br /> int k = 0;<br /> boolean bb = true;<br /> if ((max_size == null) || ("".equals(max_size)))<br /> {<br /> k = Integer.parseInt(pageContext.getProfile("VO_MAX_FETCH_SIZE"));<br /> bb = false;<br /> }<br /> else if ("MAX".equals(max_size))<br /> {<br /> bb = true;<br /> }<br /> else<br /> {<br /> k = Integer.parseInt(max_size);<br /> bb = false;<br /> }<br /><br /> //Making header<br /> AttributeDef[] a = v.getAttributeDefs();<br /> StringBuffer cc = new StringBuffer();<br /> ArrayList exist_list = new ArrayList();<br /> for (int l = 0; l < a.length; l++)<br /> {<br /> boolean zx = true;<br /> if (hidden_attrib_list != null)<br /> {<br /> for (int z = 0; z < hidden_attrib_list.length; z++)<br /> {<br /> if (a[l].getName().equals(hidden_attrib_list[z]))<br /> {<br /> zx = false;<br /> exist_list.add(String.valueOf(a[l].getIndex()));<br /> }<br /> }<br /> }<br /> if (zx)<br /> {<br /> cc.append("\"" + a[l].getName() + "\"");<br /> cc.append(",");<br /> }<br /> }<br /> String header_row = cc.toString() + "\n";<br /> pw.write(header_row);<br /><br /> for (OAViewRowImpl row = (OAViewRowImpl) v.first(); row != null; <br /> row = (OAViewRowImpl) v.next())<br /> {<br /> j++;<br /> StringBuffer b = new StringBuffer();<br /> for (int i = 0; i < v.getAttributeCount(); i++)<br /> {<br /> boolean cv = true;<br /> for (int u = 0; u < exist_list.size(); u++)<br /> {<br /> if (String.valueOf(i).equals(exist_list.get(u).toString()))<br /> {<br /> cv = false;<br /> }<br /> }<br /><br /> if (cv)<br /> {<br /> Object o = row.getAttribute(i);<br /><br /> if (!(o == null))<br /> {<br /> if (o.getClass().equals(Class.forName("oracle.jbo.domain.Date")))<br /> {<br /> //formatting of date<br /> oracle.jbo.domain.Date dt = (oracle.jbo.domain.Date) o;<br /> java.sql.Date ts = (java.sql.Date) dt.dateValue();<br /> java.text.SimpleDateFormat displayDateFormat = <br /> new java.text.SimpleDateFormat("dd-MMM-yyyy");<br /> String convertedDateString = displayDateFormat.format(ts);<br /> b.append("\"" + convertedDateString + "\"");<br /> }<br /> else<br /> {<br /> b.append("\"" + o.toString() + "\"");<br /> }<br /> }<br /> else<br /> {<br /> b.append("\"\"");<br /> }<br /> b.append(",");<br /> }<br /> }<br /> String final_row = b.toString() + "\n";<br /> pw.write(final_row);<br /> if (!bb)<br /> {<br /> if (j == k)<br /> {<br /> break;<br /> }<br /> }<br /> }<br /> }<br /> catch (Exception e)<br /> {<br /> // TODO<br /> e.printStackTrace();<br /> throw new OAException("Unexpected Exception occured.Exception Details :" + <br /> e.toString());<br /> }<br /> finally<br /> {<br /> pw.flush();<br /> pw.close();<br /> }<br /> }<br /><br /> Happy coding!Mukul Guptahttp://www.blogger.com/profile/05550600691296960397noreply@blogger.com30tag:blogger.com,1999:blog-4890411074348189661.post-39748629444709560322009-12-28T23:26:00.000-08:002010-06-09T01:18:22.905-07:00Scrolling Table :Table with horizontal Scrollbars and vertical scrollbarsHi All,<br /> I hope this is quite an interesting reading for most developers and they will try to put this feature in OAF tables.This is a very essential requirement in any of the custom OAF pages, where you show data in OATableBean and table has lot of columns, so, user has to scroll the entire page from scroll bar which is automatically rendered by browser if table width is more than page width.This is very painful for user as everytime, he scrolls the scroll-bar to see extra table columns,entire page is scrolled and he has to scroll back to the page to see other data.Similary, if you are displaying more than 10-20 rows in the table , user needs to scroll the entire page to see all the rendered rows of table.<br /><br /> In order to lessen the pain of the user and to have better UI design, we will render scroll bars both horizontal and vertical just surrounding the table<br />as , shown in the image below :<br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvq0aBmQf-c8k4__6O1BBwKdlmNgq3k7_4zv1HKuvcsNWnUitGN0wFIDAyRgUjdAZ7fOEFYJmhslugHutiAHu4NC_IwwMn_bdtyv8Qa0rcUhvy-eYqMQ-CPGX-k_Ljc7y5Q1VymmsFHW7C/s1600-h/TABLS.JPG"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 208px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvq0aBmQf-c8k4__6O1BBwKdlmNgq3k7_4zv1HKuvcsNWnUitGN0wFIDAyRgUjdAZ7fOEFYJmhslugHutiAHu4NC_IwwMn_bdtyv8Qa0rcUhvy-eYqMQ-CPGX-k_Ljc7y5Q1VymmsFHW7C/s400/TABLS.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5429993857043137266" /></a><br /> <br /> So, now lets focus how can we bring these scroll bars. In that case you can use the DIV tag to do the job for you.Put 2 RawText Bean(named DivStart, DivEnd), before and after the Table Bean in the JRAD page as shown in the image below IN JDEVELOPER:<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhkAiglgiVvWW5Go1ilUjHLpjVEsvizC6o66jirUUrvlNyr4HmgS_6qEcmVvycad2-BCDadRvk05BmW1GN-1DImHCh2YV2GxAs4KsAQGMG4pLSvuBFj5INlWC2ICr9OlblvCREmbNh0pOLX/s1600-h/TB.JPG"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 145px; height: 59px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhkAiglgiVvWW5Go1ilUjHLpjVEsvizC6o66jirUUrvlNyr4HmgS_6qEcmVvycad2-BCDadRvk05BmW1GN-1DImHCh2YV2GxAs4KsAQGMG4pLSvuBFj5INlWC2ICr9OlblvCREmbNh0pOLX/s400/TB.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5429991491404863922" /></a><br /><br />You can use following API in process request :<br /> public void processRequest(OAPageContext pageContext, OAWebBean webBean)<br /> {<br /> super.processRequest(pageContext, webBean);<br />//SEE ALL PARAMETER values you need to pass in the java comments of the method<br />addScrollBarsToTable(pageContext, webBean,"DivStart","DivEnd",true,"400",true,"400");<br /> .<br /> .<br />}<br /><br /><br />/**<br /> * @param pageContext the current OA page context.<br /> * @param webBean the web bean corresponding to the region.Pass the webBean of pagelayout.<br /> * @param preRawTextBean is name of the Rawtext bean just above the table bean.<br /> * @param postRawTextBean is name of the Rawtext bean just below the table bean.<br /> * @param horizontal_scroll is boolean value if horizontal scrollbar is required/not required.<br /> * @param width is the minimum width of table beyond which horizontal scrollbar is displayed.i.e<br /> * if width is greater than this horizontal scrollbar is displayed.If this is passed as null, defalt value<br /> * is considered which is 400.<br /> * @param vertical_scroll is boolean value if vertical scrollbar is required/not required.<br /> * @param height is the minimum height of table beyond which horizontal scrollbar is displayed .i.e<br /> * if width is greater than this horizontal scrollbar is displayed.If this is passed as null, defalt value<br /> * is considered which is 400.<br /> */<br /> public void addScrollBarsToTable(OAPageContext pageContext, <br /> OAWebBean webBean, <br /> String preRawTextBean, <br /> String postRawTextBean, <br /> boolean horizontal_scroll, String width, <br /> boolean vertical_scroll, String height)<br /> {<br /> String l_height = "400";<br /> String l_width = "400";<br /> pageContext.putMetaTag("toHeight", <br /> "<style type=\"text/css\">.toHeight {height:24px; color:black;}</style>");<br /><br /> OARawTextBean startDIVTagRawBean = <br /> (OARawTextBean) webBean.findChildRecursive(preRawTextBean);<br /> if (startDIVTagRawBean == null)<br /> {<br /> throw new OAException("Not able to retrieve raw text bean just above the table bean. Please verify the id of pre raw text bean.");<br /> }<br /><br /> OARawTextBean endDIVTagRawBean = <br /> (OARawTextBean) webBean.findChildRecursive(postRawTextBean);<br /> if (endDIVTagRawBean == null)<br /> {<br /> throw new OAException("Not able to retrieve raw text bean just below the table bean. Please verify the id of post raw text bean.");<br /> }<br /><br /> if (!((height == null) || ("".equals(height))))<br /> {<br /> try<br /> {<br /> Integer.parseInt(height);<br /> l_height = height;<br /> }<br /> catch (Exception e)<br /> {<br /> throw new OAException("Height should be an integer value.");<br /> }<br /> }<br /><br /><br /> if (!((width == null) || ("".equals(width))))<br /> {<br /> try<br /> {<br /> Integer.parseInt(width);<br /> l_width = width;<br /> }<br /> catch (Exception e)<br /> {<br /> throw new OAException("Width should be an integer value.");<br /> }<br /> }<br /><br /> String divtext = "";<br /> if ((horizontal_scroll) && (vertical_scroll))<br /> {<br /> divtext = <br /> "<DIV style='width:" + l_width + ";height:" + l_height + ";overflow:auto;padding-bottom:20px;border:0'>";<br /> }<br /> else if (horizontal_scroll)<br /> {<br /> divtext = <br /> "<DIV style='width:" + l_width + ";overflow-x:auto;padding-bottom:20px;border:0'>";<br /> }<br /> else if (vertical_scroll)<br /> {<br /> divtext = <br /> "<DIV style='height:" + l_height + ";overflow-y:auto;padding-bottom:20px;border:0'>";<br /> }<br /> else<br /> {<br /> throw new OAException("Both vertical and horizintal scrollbars are passed as false,hence, no scrollbars will be rendered.");<br /> }<br /> startDIVTagRawBean.setText(divtext);<br /> endDIVTagRawBean.setText("</DIV>");<br /> }<br /><span style="font-weight:bold;">Please Note : Height and Width passed in addScrollBarsToTable API are the minimum<br />height and width of the table respectively which will be displayed on the page. Hence if this display resolution is available on page the scrollbars will not be displayed or corresponding one scrollbar or both scrollbars will be displayed.If you are not able see both scrollbars, even if you pass true for both in this method, try to put less resolution like 150 and 150 etc.<br /></span> <br /> Happy coding..!Mukul Guptahttp://www.blogger.com/profile/05550600691296960397noreply@blogger.com22tag:blogger.com,1999:blog-4890411074348189661.post-87161839700889043842009-12-18T00:54:00.000-08:002010-06-09T01:18:22.905-07:00Blocking User on submit Action in a OAF pageThis is one of the most frequently required feature in OAF page, in certain conditions. Basically our requirement is to block user from pressing a button twice, i.e.,if a button is pressed for the first time,till the time request processing is going on for the first request on server either the button should be disabled on page or an hourglass should be shown on the page, so that user should not be able to press it again to start another request, before this request's response has been received from server. This is very essential feature where<br /><br />1) You are lets say creating a account.<br />2) Doing a transaction.<br />3) Generating a report.<br />4) Doing a transaction which takes significant amount of time which can make user impatient and press the button again.<br /><br /> The standard solution for this provided by OAF is setBlockOnEverySubmit API.Whenever a submit action takes place on a page, subsequent submits can be blocked. <br /> When using a blocking on submit technique, when the submit action takes place, the cursor becomes busy and prevents any other submit action until the current submit event has been handled. <br /> The block on submit behavior is not enabled by default on a page. However, For Partial Page Refresh (PPR) events alone, it is enabled by default.<br /> To implement the block on submit behavior on a specfic page, add the following code to the processRequest() of that page CO:<br /><br />import oracle.apps.fnd.framework.webui.beans.OABodyBean;<br /><br />public void processRequest(OAPageContext pageContext, OAWebBean webBean)<br />{<br />super.processRequest(pageContext, webBean);<br />OAWebBean body = pageContext.getRootWebBean();<br />if (body instanceof OABodyBean)<br />{<br />((OABodyBean)body).setBlockOnEverySubmit(true);<br />}<br />...<br />...<br />}<br /><br /> But there are exceptions to this API functionality, what if my page has multiple buttons and I want this nature only on press of one of the button.Situations like this the standard solution is using OAProcessing page(See dev guide for OAProcessing page implementation, its explained well!), which is typically used in long running processed.But what if user is not ready to leave the page at all and asks you to block the navigation somehow? What if you are mobile browser, where OAProcessing page does not work fine. Situations like this can be taken care through javascript. <br /> I must repeat again, use this javascript solution only when your requirement is not fulfilled by standard setBlockOnEverySubmit API provided by framework.Ok here are the steps for the javascript solution, which will block the action by making the button disabled as soon as it is pressed and releasing it as soon as your action is finished :<br /><br />1) Add a button bean , instead of submit button bean. Lets say its id is "item1" in property inspector. Set destination uri property in property inspector as :<br />javascript:document.getElementById('item1').disabled=true;submitForm('DefaultFormName',0,{'XXX':'Y'});<br /><br />2) In process form request, you can catch the event as :<br /><br /> public void processFormRequest(OAPageContext pageContext,<br /> OAWebBean webBean)<br /> {<br /> super.processFormRequest(pageContext, webBean);<br /> <br /> .// the js button click event<br /> // don't use pageContext.getParameter() API to get parameter values<br /> // in R12 because its doing validation on JS paremeters.<br /> // so,instead of getting parameter value from pagecontext<br /> //getting directly from http request. <br /> if(pageContext.getRenderingContext()<br /> .getServletRequest().getParameter("XXX")!=null)<br /> {<br /> // ur button event logic in process form request<br /> ......<br /><br /> //remove this parameter from http request<br /> pageContext.removeParameter("XXX");<br /> }<br />}<br /><br /> I hope this helps to people which are facing such situations. Happy coding..!Mukul Guptahttp://www.blogger.com/profile/05550600691296960397noreply@blogger.com13tag:blogger.com,1999:blog-4890411074348189661.post-83480460377685564162009-12-15T23:10:00.000-08:002010-06-09T01:21:23.577-07:00Migration of AOL setups from one instance to Another.Hi All,<br /> Typically this is the requirement of every Apps project whether its a upgrade/implementation/support. You might create AOL objects like profiles,alerts,AK regions etc. , here I am listing all the LDT commands which will help you in migration.LDT download command extract the AOL object in a .ldt file and then u can put that in target instance and call upload LDT command to upload it in target instance.<br /> I think there are numerous websites where this is listed, but still commands like ldt of alert, ak region is still hard to find. Hence, I am consolidating all of them at one place :<br /><br />function scripts<br />------------------<br />$FND_TOP/bin/FNDLOAD apps/apps 0 Y DOWNLOAD $FND_TOP/patch/115/import/afsload.lct XXADAT_MAT_REQ_HIST.ldt FUNCTION FUNCTION_NAME=XXADAT_MAT_REQ_HIST<br /><br />$FND_TOP/bin/FNDLOAD apps/apps 0 Y UPLOAD $FND_TOP/patch/115/import/afsload.lct XXADAT_MAT_REQ_HIST.ldt<br /><br /><br />responsibility scripts<br />------------------------<br />FNDLOAD apps/apps O Y DOWNLOAD $FND_TOP/patch/115/import/afscursp.lct XXADAT_PROD_TIME_BOOKING.ldt FND_RESPONSIBILITY RESP_KEY="XXADAT_PROD_TIME_BOOKING"<br /><br />$FNDLOAD apps/apps O Y UPLOAD $FND_TOP/patch/115/import/afscursp.lct file_name.ldt<br /><br /><br />menu scripts<br />-------------<br />FNDLOAD apps/apps O Y DOWNLOAD $FND_TOP/patch/115/import/afsload.lct AHL_PRD_MBENCH_USER_SUB_MENU.ldt MENU MENU_NAME="AHL_PRD_MBENCH_USER_SUB_MENU"<br /><br />$FNDLOAD apps/apps O Y UPLOAD $FND_TOP/patch/115/import/afsload.lct file_name.ldt<br /><br />lookup scripts<br />--------------<br />FNDLOAD apps/apps 0 Y DOWNLOAD $FND_TOP/patch/115/import/aflvmlu.lct AHL_PRD_DEFERRAL_TYPE.ldt FND_LOOKUP_TYPE APPLICATION_SHORT_NAME ="XXADAT" LOOKUP_TYPE="AHL_PRD_DEFERRAL_TYPE"<br /><br />FNDLOAD apps/apps 0 Y UPLOAD $FND_TOP/patch/115/import/aflvmlu.lct XXADAT_NO_CONCURRENT_LOGIN_WOS.ldt<br /><br />ak region download script<br />-------------------------------<br />java oracle.apps.ak.akload apps apps THIN "(DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(Host = < instance IP > )(Port = 1541)) (CONNECT_DATA = (SID=DEV)))" DOWNLOAD XXADAT_EM_LOV.ldt GET CUSTOM_REGION AHL XXADAT_EM_LOV<br /><br />ak region upload script<br />------------------------<br />java oracle.apps.ak.akload apps apps THIN "(DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(Host = < instance IP > )(Port = 1620)) (CONNECT_DATA = (SID=RTST)))" UPLOAD XXADAT_EM_LOV.ldt UPDATE CUSTOM_REGION<br /><br />profile scripts<br />---------------<br />FNDLOAD apps/apps O Y DOWNLOAD $FND_TOP/patch/115/import/afscprof.lct XXADAT_BUDGET_MANHOURS_NROUTINE.ldt PROFILE PROFILE_NAME="XXADAT_BUDGET_MANHOURS_NROUTINE" APPLICATION_SHORT_NAME="XXADAT"<br /><br />FNDLOAD apps/apps O Y UPLOAD $FND_TOP/patch/115/import/afscprof.lct XXADAT_BUDGET_MANHOURS_ROUTINE.ldt<br /><br />message scripts<br />----------------<br />FNDLOAD apps/apps 0 Y DOWNLOAD $FND_TOP/patch/115/import/afmdmsg.lct XXADAT_MIN_EXP_MSG.ldt FND_NEW_MESSAGES APPLICATION_SHORT_NAME="XXADAT" MESSAGE_NAME="XXADAT_MIN_EXP_MSG"<br /><br />FNDLOAD apps/apps 0 Y UPLOAD $FND_TOP/patch/115/import/afmdmsg.lct XXADAT_MIN_EXP_MSG.ldt <br /><br />CONCURRENT PROGRAM<br />--------------------<br />FNDLOAD apps/appsrtst O Y DOWNLOAD $FND_TOP/patch/115/import/afcpprog.lct XXADAT_CL_COMP_WO_F_VISIT.ldt PROGRAM APPLICATION_SHORT_NAME="XXADAT" CONCURRENT_PROGRAM_NAME="XXADAT_CL_COMP_WO_F_VISIT"<br /><br />FNDLOAD apps/apps O Y UPLOAD $FND_TOP/patch/115/import/afcpprog.lct XXADAT_CL_COMP_WO_F_VISIT.ldt<br /><br />alert<br />------------<br />FNDLOAD apps/apps 0 Y DOWNLOAD $ALR_TOP/patch/115/import/alr.lct XXADAT_INST_LOC_UPDATE.ldt ALR_ALERTS APPLICATION_SHORT_NAME='XXADAT' ALERT_NAME= 'XXADAT_INST_LOC_UPDATE'<br /><br />PS:This ldt command brings all alerts in the instance in the ldt file, so u need to remove all except the one u want to move.<br /><br /><br />FNDLOAD apps/apps 0 Y UPLOAD $ALR_TOP/patch/115/import/alr.lct XXADAT_RESET_NR_TRACKING_NO_WHN_DEF.ldt<br /><br />Workflow Upload<br />-----------------<br />WFLOAD apps/apps 0 Y UPLOAD XXCLOSNR.wft<br /><br /> In all these commands apps/apps is username/password of apps database user. Also, in all upload commands you can give full location from where your ldt/wft file should be picked to upload. I hope this helps.Mukul Guptahttp://www.blogger.com/profile/05550600691296960397noreply@blogger.com9tag:blogger.com,1999:blog-4890411074348189661.post-90779471135716540492009-12-07T01:43:00.000-08:002010-06-09T01:18:22.905-07:00Programatic PPR in OAF.I was recently helping a friend in a customization in OAF, where through personalization, he wanted to put a ppr action in a seeded page in a seeded item. He was trying to do that customization using fire action, which was not acceptable by customer due to obvious reasons. Since, I think this section is missing in developers' guide, and is quite simple to approach, here is code you can write in process request of CO to attach programmatic PPR. lets take a simple example of attaching PPR to a message choice bean :<br /><br />//In Process Request() <br />{<br /> //Please attach PPR only to those UIX beans which support it<br /> //otherwise it may not work<br /> OAMessageChoiceBean mcb=(OAMessageChoiceBean)webBean.findChildRecursive("<id of bean>");<br /> FireAction firePartialAction = new FirePartialAction("empPositionChange");<br /> mcb.setAttributeValue(PRIMARY_CLIENT_ACTION_ATTR,firePartialAction);<br />}<br /><br />//In process form request <br />if ("empPositionChange".equals(pageContext.getParameter(OAWebBeanConstants.EVENT_PARAM))) <br /> {<br /> //ur logic on PPR<br /><br /> //if PPR is attached in a table/hgrid child then we can find the row <br /> //reference by<br /> String rowReference =pageContext.getParameter(OAWebBeanConstants.EVENT_SOURCE_ROW_REFERENCE); <br /> }<br /><br />I hope this helps. Happy oaf extensions :)!Mukul Guptahttp://www.blogger.com/profile/05550600691296960397noreply@blogger.com13tag:blogger.com,1999:blog-4890411074348189661.post-17412107808288755532009-11-30T00:02:00.000-08:002010-06-09T01:18:22.906-07:00Setting Query Dynamically in View Object. (Why in some cases even after using setQuery(), VO picks default query.)Couple of time while making view object in OAF pages, you have conditions where instead of where clause or order by clause, you need to change the entire source of sql query of View Object. <br /> There can be n number of such scenarios, for example you are using a querybean in a search page, and in a certain condition, you have to change your query, your VO is attached to a LOV and in certain condition you need the query to change in order to optimize the VO sql query etc. Following points always keep in mind while using setQuery():<br /><br />1) The new query you want to set in the view object should have same column name and types as the original VO query.<br /><br />2)As per OAF coding standards all coding related to setting where clause, order by clause or setQuery should be written in ViewObjectImpl class, so in such case, you should generate ViewObjectImpl class.<br /><br />3)<span style="font-weight:bold;">Most Important :</span>Always call <span style="font-weight:bold;">vo.setFullSqlMode(FULLSQL_MODE_AUGMENTATION)</span> before calling setquery() on the view object.This ensures that the order by or the WHERE clause, that is generated by OA Framework, can be correctly<br />appended to your VO. The behavior with FULLSQL_MODE_AUGMENTATION is as follows:<br /><br />a) The new query that you have programmatically set takes effect when you call setQuery and execute the query.<br />b) If you call setWhereClause or if a customer personalizes the criteria for your query region, BC4J augments the whereClause on the programmatic query that you set. <br /><br />For example:<br />select * from (your programmatic query set through setQuery)<br />where (your programmatic where clause set through setWhereClause)<br />order by (your programmatic order set through setOrderBy)<br />The same query is changed as follows if a customer adds a criteria using personalization:<br />select * from (your programmatic query set through setQuery)<br />where (your programmatic where clause set through setWhereClause) AND<br />(additional personalization where clause)<br />order by (your programmatic order set through setOrderBy)_<br /><br /><span style="font-weight:bold;">Warning: If you do not set FULLSQL_MODE_AUGMENTATION, the whereClause and/or the<br />orderBy, which was set programmatically, will not augment on the new query that you set using setQuery. It will instead augment on your design time VO query.<br /></span><br /><br />Due to timing issues, always use the controller on the query region/LOV region while using setQuery().Mukul Guptahttp://www.blogger.com/profile/05550600691296960397noreply@blogger.com21tag:blogger.com,1999:blog-4890411074348189661.post-17004413709096335802009-09-25T00:09:00.000-07:002010-06-09T01:18:22.906-07:00Dynamically changing multiselect to single select in Table in OAFI would like to share a small piece of code, which recently a friend shared with me, this is a typical requirement, which might look too trivial at first shot, but is quite easy to implement. Suppose you have a table where in you have a requirement to have single or multi selection based on a dynamic conditon eg, some selection or press of a button you wanna change the <strong>multiselection to single selection and vice versa</strong>. <br /><br /> In such scenario, in the action of the event you redirect to same page and use following code in <strong>process request</strong> on the base of parameter you set in session/pagecontext :<br />// Hiding the Multiple Select Table Action and add single selection<br />OAAdvancedTableBean tabBean = (OAAdvancedTableBean)webBean.<br />findIndexedChildRecursive("[table item id]");<br /><br />//Since the multiselect is at the end, get the total count -1 for removing<br />int count = tabBean.getIndexedChildCount(pageContext.getRenderingContext());<br />System.out.println("Child Count "+count);<br />tabBean.removeIndexedChild(count-1);<br /><br />OAMultipleSelectionBean sel = (OAMultipleSelectionBean)tabBean.getTableSelection(); <br />OASingleSelectionBean singleSelection = new OASingleSelectionBean() ;<br />singleSelection.setText("Select");<br /><br />//Set the attribute for the single select<br />singleSelection.setViewAttributeName("SelectFlag");<br />tabBean.setTableSelection(singleSelection);<br /><br /> I hope this helps anybody who tries to implement such scenario!Mukul Guptahttp://www.blogger.com/profile/05550600691296960397noreply@blogger.com5tag:blogger.com,1999:blog-4890411074348189661.post-481814204317063352009-06-06T01:44:00.000-07:002010-06-09T01:18:22.906-07:00Error while running a OAF page with 12.1.1 (jdeveloper patch 8431482We recetly migrated to newly released on Oracle apps R12.1.1.We tried using jdeveloper with patch 8431482 which is mentioned in metalink Doc Id 416708.1.We got following error stack:<br />Error Page <br />Exception Details. <br />oracle.apps.fnd.framework.OAException: Application: FND, Message Name: FND_GENERIC_MESSAGE. Tokens: MESSAGE = java.lang.NullPointerException; <br />at oracle.apps.fnd.framework.OAException.wrapperException(Unknown Source)<br />at oracle.apps.fnd.framework.CreateIcxSession.getEncryptedSessId(Unknown Source)<br />at oracle.apps.fnd.framework.CreateIcxSession.createSession(Unknown Source)<br />at _runregion._jspService(_runregion.java:132)<br />at com.orionserver.http.OrionHttpJspPage.service(OrionHttpJspPage.java:59)<br />at oracle.jsp.runtimev2.JspPageTable.service(JspPageTable.java:462)<br />at oracle.jsp.runtimev2.JspServlet.internalService(JspServlet.java:594)<br />at oracle.jsp.runtimev2.JspServlet.service(JspServlet.java:518)<br />at javax.servlet.http.HttpServlet.service(HttpServlet.java:856)<br />at com.evermind.server.http.ServletRequestDispatcher.invoke(ServletRequestDispatcher.java:713)<br />at com.evermind.server.http.ServletRequestDispatcher.forwardInternal(ServletRequestDispatcher.java:370)<br />at com.evermind.server.http.HttpRequestHandler.doProcessRequest(HttpRequestHandler.java:871)<br />at com.evermind.server.http.HttpRequestHandler.processRequest(HttpRequestHandler.java:453)<br />at com.evermind.server.http.HttpRequestHandler.serveOneRequest(HttpRequestHandler.java:221)<br />at com.evermind.server.http.HttpRequestHandler.run(HttpRequestHandler.java:122)<br />at com.evermind.server.http.HttpRequestHandler.run(HttpRequestHandler.java:111)<br />at oracle.oc4j.network.ServerSocketReadHandler$SafeRunnable.run(ServerSocketReadHandler.java:260)<br />at oracle.oc4j.network.ServerSocketAcceptHandler.procClientSocket(ServerSocketAcceptHandler.java:239)<br />at oracle.oc4j.network.ServerSocketAcceptHandler.access$700(ServerSocketAcceptHandler.java:34)<br />at oracle.oc4j.network.ServerSocketAcceptHandler$AcceptHandlerHorse.run(ServerSocketAcceptHandler.java:880)<br />at com.evermind.util.ReleasableResourcePooledExecutor$MyWorker.run(ReleasableResourcePooledExecutor.java:298)<br />at java.lang.Thread.run(Thread.java:595)<br />## Detail 0 ##<br />java.lang.NullPointerException<br />at oracle.apps.fnd.security.SessionManager.recordSuccess(SessionManager.java:3820)<br />at oracle.apps.fnd.security.SessionManager.validateLogin(SessionManager.java:2082)<br />at oracle.apps.fnd.security.SessionManager.validateLogin(SessionManager.java:1946)<br />at oracle.apps.fnd.framework.CreateIcxSession.getEncryptedSessId(Unknown Source)<br />at oracle.apps.fnd.framework.CreateIcxSession.createSession(Unknown Source)<br />at _runregion._jspService(_runregion.java:132)<br />at com.orionserver.http.OrionHttpJspPage.service(OrionHttpJspPage.java:59)<br />at oracle.jsp.runtimev2.JspPageTable.service(JspPageTable.java:462)<br />at oracle.jsp.runtimev2.JspServlet.internalService(JspServlet.java:594)<br />at oracle.jsp.runtimev2.JspServlet.service(JspServlet.java:518)<br />at javax.servlet.http.HttpServlet.service(HttpServlet.java:856)<br />at com.evermind.server.http.ServletRequestDispatcher.invoke(ServletRequestDispatcher.java:713)<br />at com.evermind.server.http.ServletRequestDispatcher.forwardInternal(ServletRequestDispatcher.java:370)<br />at com.evermind.server.http.HttpRequestHandler.doProcessRequest(HttpRequestHandler.java:871)<br />at com.evermind.server.http.HttpRequestHandler.processRequest(HttpRequestHandler.java:453)<br />at com.evermind.server.http.HttpRequestHandler.serveOneRequest(HttpRequestHandler.java:221)<br />at com.evermind.server.http.HttpRequestHandler.run(HttpRequestHandler.java:122)<br />at com.evermind.server.http.HttpRequestHandler.run(HttpRequestHandler.java:111)<br />at oracle.oc4j.network.ServerSocketReadHandler$SafeRunnable.run(ServerSocketReadHandler.java:260)<br />at oracle.oc4j.network.ServerSocketAcceptHandler.procClientSocket(ServerSocketAcceptHandler.java:239)<br />at oracle.oc4j.network.ServerSocketAcceptHandler.access$700(ServerSocketAcceptHandler.java:34)<br />at oracle.oc4j.network.ServerSocketAcceptHandler$AcceptHandlerHorse.run(ServerSocketAcceptHandler.java:880)<br />at com.evermind.util.ReleasableResourcePooledExecutor$MyWorker.run(ReleasableResourcePooledExecutor.java:298)<br />at java.lang.Thread.run(Thread.java:595)<br />java.lang.NullPointerException<br />at oracle.apps.fnd.security.SessionManager.recordSuccess(SessionManager.java:3820)<br />at oracle.apps.fnd.security.SessionManager.validateLogin(SessionManager.java:2082)<br />at oracle.apps.fnd.security.SessionManager.validateLogin(SessionManager.java:1946)<br />at oracle.apps.fnd.framework.CreateIcxSession.getEncryptedSessId(Unknown Source)<br />at oracle.apps.fnd.framework.CreateIcxSession.createSession(Unknown Source)<br />at _runregion._jspService(_runregion.java:132)<br />at com.orionserver.http.OrionHttpJspPage.service(OrionHttpJspPage.java:59)<br />at oracle.jsp.runtimev2.JspPageTable.service(JspPageTable.java:462)<br />at oracle.jsp.runtimev2.JspServlet.internalService(JspServlet.java:594)<br />at oracle.jsp.runtimev2.JspServlet.service(JspServlet.java:518)<br />at javax.servlet.http.HttpServlet.service(HttpServlet.java:856)<br />at com.evermind.server.http.ServletRequestDispatcher.invoke(ServletRequestDispatcher.java:713)<br />at com.evermind.server.http.ServletRequestDispatcher.forwardInternal(ServletRequestDispatcher.java:370)<br />at com.evermind.server.http.HttpRequestHandler.doProcessRequest(HttpRequestHandler.java:871)<br />at com.evermind.server.http.HttpRequestHandler.processRequest(HttpRequestHandler.java:453)<br />at com.evermind.server.http.HttpRequestHandler.serveOneRequest(HttpRequestHandler.java:221)<br />at com.evermind.server.http.HttpRequestHandler.run(HttpRequestHandler.java:122)<br />at com.evermind.server.http.HttpRequestHandler.run(HttpRequestHandler.java:111)<br />at oracle.oc4j.network.ServerSocketReadHandler$SafeRunnable.run(ServerSocketReadHandler.java:260)<br />at oracle.oc4j.network.ServerSocketAcceptHandler.procClientSocket(ServerSocketAcceptHandler.java:239)<br />at oracle.oc4j.network.ServerSocketAcceptHandler.access$700(ServerSocketAcceptHandler.java:34)<br />at oracle.oc4j.network.ServerSocketAcceptHandler$AcceptHandlerHorse.run(ServerSocketAcceptHandler.java:880)<br />at com.evermind.util.ReleasableResourcePooledExecutor$MyWorker.run(ReleasableResourcePooledExecutor.java:298)<br />at java.lang.Thread.run(Thread.java:595)<br /><br />We raised an SR with Oracle and they have responded back saying : Set profile "Sign-On:Notification" to "No" at site level, which resloves the issue and jdev works fine.<br />Hope this helps all, which are trying to use patch 8431482 for Apps 12.1.1.Mukul Guptahttp://www.blogger.com/profile/05550600691296960397noreply@blogger.com12tag:blogger.com,1999:blog-4890411074348189661.post-65788276230257919542009-06-05T13:25:00.000-07:002010-06-09T01:18:22.906-07:00Custom Logging in Java Layer in Oracle Applications R12Hi All,<br /> I have often felt for years simple SOP (System.out.Println) is the best way of debugging in java/j2ee applications. I have the evil habit.. of putting lots of SOPs while writing code for OAF or ADF or simple j2ee applications. I generally create a method with sop in it eg:<br /><br />private void putLog(Object o)<br />{<br /> System.out.println(o);<br />}<br /><br /> and call it with the code wherever required. The benefit is at the point of deployment of code, i just need to change this method from sop to writeDiagnostics().The worst part of diagnostic logging is when you enable logging on the Applications... "Show Log On Screen", it shows so many logs apart from my custom log statements, that its really difficult to debug.<br /><br /> The other standard way of debugging java code on server is using OACore log in OC4J server.In R12,<br />Goto $ORA_CONFIG_HOME/10.1.3/opmn/conf<br />take the backup of opmn.xml<br />edit opmn.xml for data id="java-options" and add the following:<br />-DAFLOG_ENABLED=true -DAFLOG_LEVEL=statement <br />-DAFLOG_MODULE=fnd% <br />-DAFLOG_FILENAME=/tmp/aflog.txt -Djbo.debugoutput=console <br /><br />The log message should get written in,<br />$INST_TOP/logs/ora/10.1.3/opmn/oacore_default_group_1/oacorestd.out <br /><br /> But for this my code should contain SOPs, which is also a problem, because I don't wanna SOPs in my code after deployment on server, as SOPs have huge impact on performance.<br /><br /><strong>So, I need a way (probably a magic .... :) )that my debug statements become SOPs when I run my code in jdeveloper automatically, and when I run the same code in server, these statements should go in a text file if I enable logging on server, lets' say we make it dependent on a profile , so that I can also disable these statements/logging in production just by changing profile value.</strong><br /><br /> Ok so make this magic or logic happen I used a trick and have written a custom logger class with <strong>static methods</strong>, let see how this class works.Ok for making this logging happen follow these steps:<br /><br />STEP1<br />-------------<br /><strong>Copy this class and put in any pkg under custom directory in java top, like I have used <strong>package xx.oracle.apps.ak.logging</strong>. Replace this pkg name with the pkg u want to put this class in.</strong><br /><br />package xx.oracle.apps.ak.logging;<br /><br />import java.awt.Toolkit;<br />import java.io.FileNotFoundException;<br />import java.io.FileOutputStream;<br />import java.io.PrintStream;<br />import oracle.apps.fnd.framework.OAException;<br />import oracle.apps.fnd.framework.server.OADBTransaction;<br />import oracle.apps.fnd.framework.webui.OAPageContext;<br />import java.io.PrintWriter;<br />import oracle.apps.fnd.common.WebAppsContext;<br />public class XxLogger<br />{<br /> public XxLogger()<br /> {<br /> }<br /><br /> public static void putLog(OADBTransaction ot, Object o)<br /> {<br /> printLog(ot, null, null, null, o);<br /> }<br /><br /> public static void putLog(OAPageContext pageContext, Object o)<br /> {<br /> printLog(null, null, pageContext, null, o);<br /><br /> }<br /><br /> public static void putLog(WebAppsContext ctx, Object o)<br /> {<br /> printLog(null, ctx, null, null, o);<br /><br /> }<br /><br /> public static void printLog(OADBTransaction ot, WebAppsContext ctx, <br /> OAPageContext pageContext, Exception exp, <br /> Object o)<br /> {<br /> FileOutputStream outFile = null;<br /> try<br /> {<br /> //this line should throw headless exception on server<br /> //due to opmn.xml configuration for oc4j node.<br /> //and would work fine in local jdev<br /> Toolkit.getDefaultToolkit().getScreenSize();<br /> if (o == null)<br /> {<br /> exp.printStackTrace();<br /> }<br /> else<br /> {<br /> System.out.println(o);<br /> }<br /> }<br /> catch (Exception e)<br /> {<br /> try<br /> {<br /> String profile = null;<br /> if (ot != null)<br /> {<br /> profile = ot.getProfile("XX_LOG");<br /> }<br /> else if (pageContext != null)<br /> {<br /> profile = pageContext.getProfile("XX_LOG");<br /> }<br /> else if (ctx != null)<br /> {<br /> profile = ctx.getProfileStore().getProfile("XX_LOG");<br /> }<br /> if ((profile == null) || ("".equals(profile)))<br /> {<br /> //No logging <br /><br /> }<br /> else<br /> {<br /> outFile = new FileOutputStream(profile + "/xx_log.log", true);<br /> PrintStream ps = new PrintStream(outFile);<br /><br /> if (exp != null)<br /> {<br /> ps.append(new java.util.Date().toString() + " : " + <br /> "*************************************Exception Details*****************************");<br /> ps.append(" \n ");<br /> exp.printStackTrace(ps);<br /> ps.append("*************************************Exception Details End *****************************");<br /><br /> }<br /> else<br /> {<br /> ps.append(new java.util.Date().toString() + " : " + o);<br /> }<br /> ps.append(" \n ");<br /> }<br /> }<br /> catch (FileNotFoundException f)<br /> {<br /> // TODO<br /> e.printStackTrace();<br /> }<br /> }<br /> }<br /><br /><br /> public static void printStack(OADBTransaction ot, Exception e)<br /> {<br /> printLog(ot, null, null, e, null);<br /> }<br /><br /><br /> public static void printStack(WebAppsContext ctx, Exception e)<br /> {<br /> printLog(null, ctx, null, e, null);<br /> }<br /><br /><br /> public static void printStack(OAPageContext pageContext, Exception e)<br /> {<br /> printLog(null, null, pageContext, e, null);<br /> }<br /><br />}<br /><br /><strong>STEP2<br />---------- <br />Now create a custom profile which will store path of log file we want to get generated,please note if this profile value is null then no log will be generated.Replace the profile name with "XX_LOG" in the code at all 3 places.<br /><br />STEP3<br />========<br />set the profile value to the path where you wanna log file to be generated.Also please note you would have to manually create "xx_log.log" file there for the first time(for that just create a simple fie and rename as "xx_log.log"), this I have done purposely in code, so that even if by mistake profile value is not null in production, no log should be generated.<br /><br />STEP 4<br />===========<br />Use this logging in OAF/JTT/JTF/JSP file :<br /><br />In CO<br />========<br />XxLogger.putLog(OAPageContext pageContext, Object o)<br /><br />In AM,VO,EO<br />============<br />XxLogger.putLog(OADBTransaction ot, Object o)<br /><br /><br />In JTT/JTF<br />============<br />import oracle.apps.fnd.common.WebRequestUtil;<br />import oracle.apps.fnd.common.WebAppsContext;<br />WebAppsContext ctx = WebRequestUtil.validateContext(request, response);<br />XxLogger.putLog(WebAppsContext ctx, Object o)<br /><br />STEP 5<br />===========<br />For printing stacktrace of exceptions :<br /><br /><br />In CO<br />========<br />XxLogger.printStack(OAPageContext pageContext, Exception e)<br /><br />In AM,VO,EO<br />============<br />XxLogger.printStack(OADBTransaction ot, Exception e)<br /><br /><br />In JTT/JTF<br />============<br />import oracle.apps.fnd.common.WebRequestUtil;<br />import oracle.apps.fnd.common.WebAppsContext;<br />WebAppsContext ctx = WebRequestUtil.validateContext(request, response);<br />XxLogger.printStack(WebAppsContext ctx, Exception e)</strong><br /><br />We are done the log would now be generated at the position marked in profile and the these messages will automatically converted to SOPs when you run your code in local jdev<br /><br />Advantages of this logging<br />=============================<br />1) You don't need to change your code again and again while working in local or deployed on server.<br />2) If the development is done in a team, everybody in the team can set the profile at his/her user level so that different log is generated for each user.<br />3)This code when run in jdeveloper without any change all putLog() and printStack() statements will convert into System.out.println.<br />4) On server if profile value is set to null , no log is generated, else if some location is set, log is generated there.<br />5) Same class can be used in all OAF AND JSP components.<br />6) All methods putLog and printStack are static, so you need not instanciate the class, direct call of method will work.<br />7) Sometimes while working at offshore, you don't have access to DBA, who can enable log.... :) this is my personal one... u might not face it.<br /><br />Logic of how code works<br />=========================<br />If you have read the code of class , in all the methods code essentially calls printLog method, which has the first line as<br /><br /><strong>Toolkit.getDefaultToolkit().getScreenSize();</strong><br />This line throws headless exception on server mainly because opmn.xml file configuration by default throws headless exception if any JAVA awt api is called, but this line works fine in jdev, so we utilise this logic to identify whether the code is running on server or jdev. Accordingly it writes the statements in a file, if file is enabled or else calls SOP in jdev.Mukul Guptahttp://www.blogger.com/profile/05550600691296960397noreply@blogger.com2tag:blogger.com,1999:blog-4890411074348189661.post-11125948492131664172009-04-06T01:01:00.000-07:002010-06-09T01:18:22.907-07:00MOAC(Multi Org Access Control) in OA FrameworkHi All,<br /> After a long time a small and crisp article of how you can set MOAC in your custom OAF code. With release of R12 Oracle EBS has introduced a security feature in apps for multi -org access. Lets have a quick introduction of what is MOAC all abaout :<br /><br />What is MOAC ?<br />---------------<br />The Access Control feature in Release 12 allows the user to enter or query records in one or more operating units without changing application responsibility. It is the system administrator’s discretion to either implement the feature or use the same multiple organizations profile option setting available before Release 12 by using the single operating unit mode (i.e. one operating unit for a responsibility).<br />In Release 12, the multiple organizations context value is no longer initialized by the FND_GLOBAL.APPS_INITIALIZE routine thereby reducing unnecessary context setting and resource consumption for applications that do not use operating unit context for data security.<br />To use the single operating unit mode, you must set the value for the "Initialization SQL Statement – Custom profile" to "mo_global.init('S',null);". This initializes the operating unit context based on the "MO: Operating Unit" profile option and the "MO: Security Profile" profile option must not be set.<br />Fresh install of Release 12 Application is enabled with multiple organizations, however, the system administrator must create operating units to use multi organizations sensitive application products. The user can create new operating units in the Accounting Setup Manager page in addition to HRMS’s Define Organizations page.<br /><br /><br />MOAC Implementation In Apps<br />-----------------------------<br />A new or fresh installation of an Oracle Applications instance does not automatically enable multiple organizations. Typically, the system administrator defines "MO: Operating Unit" profile at Responsibility and/or User level. The "organization_id" of the "MO: Operating Unit" profile option value filters the transactional data. The CLIENT_INFO application context space stores the multiple organizations context value.<br />Multi-Org views use the following WHERE clause to filter application records:<br />'org_id = substrb(userenv(''CLIENT_INFO''),1,10)' <br /><br />MOAC in terms of OAF:<br />----------------------<br /> Its very natural while developing extension or developing OAF custom pages , you may require quering of views, synonyms which use MOAC via VO.Also, it is possible that you might be calling some standard Oracle PL/SQL APIs which usually need MOAC context to be set.<br /><br /> Every transaction that requires multiple organizations must call the Multiple Organizations initialization in the root Application Module (AM).<br />Use the following declarative mechanism to initialize the multiple organizations settings for application teams to implement multiple organizations:<br />1. To enable multiple organizations for the root application module , go to the BC4J Application Module wizard - Properties section and specify the property as MULTIORG_ENABLED and value as either S (single operating unit mode) or M (Multiple operating unit mode). <br />2. Click Add, then Apply or OK. <br />On specifying this property, the OA Framework automatically initializes the multiple organizations context at the following appropriate program event points:<br />1. When reserving or activating the application module. <br />2. When initializing or validating the Oracle Applications user session. <br />You initialize the context once for each transaction and session and not instantiate for every page. If your transaction retains the root AM, then the above steps are the easiest to initialize multiple organizations.<br /><br />If a transaction has multiple pages and the root AM is not retained, then you must call the method OADBTransaction.setMultiOrgAccess to initialize the multiple organizations context to help the user select an operating unit for a transaction.Here is how u can code in AM<br />OADBTransactionImpl trx = (OADBTransactionImpl)getOADBTransaction(); getOADBTransaction().setMultiOrgAccess(String.valueOf(trx.getOrgId()),String.valueOf(trx.getSecurityProfileId()),trx.getApplicationShortName());<br /> <br /><br /><br /> If the operating unit the user selected must appear in the subsequent pages, then pass the curr_org_id to the page and use OADBTransaction.setMultiOrgPolicyContext method to set the operating unit context for the pages that need multiple organizations.<br />OADBTransactionImpl trx = (OADBTransactionImpl)getOADBTransaction(); <br />getOADBTransaction().setMultiOrgPolicyContext("S",trx.getMultiOrgCurrentOrgId());<br /><br /> There is often a case when you create a custom application in apps under $JAVA_TOP, in order to keep all your customizations, lets say XXABC.When we make a new application in Apps like XXABC, we need to register the application for Multi-Org as single or multiple.<br /> This is important, if we are defining new custom responsibilities on this application and we are planning to have custom, as well as seeded pages attached in this responsibility.If you have this scenario, where you custom responsibility is defined on custom application and it is using seeded pages as well as custom pages, you may face a error in your multi-org enabled seeded AM pages like :<br /><span style="font-weight:bold;">oracle.apps.fnd.framework.OAException: Application: FND, Message Name: FND_GENERIC_MESSAGE. Tokens: MESSAGE = java.sql.SQLException: ORA-20001: SQL_PLSQL_ERROR: N, ROUTINE, MO_GLOBAL.INIT, N, ERRNO, -20001, N, REASON, ORA-20001: SQL_PLSQL_ERROR: N, ROUTINE, MO_GLOBAL.SET_ORG_ACCESS, N, ERRNO, -20001, N, REASON, ORA-20001: APP-FND-02938: Multi-organization routine failed to initialize a session for the product: &PRODUCT. Please inform your support representative.<br />ORA-06512: at "APPS.FND_MESSAGE", line 509<br />ORA-06512: at "APPS.MO_GLOBAL", line 36<br />ORA-06512: at "APPS.MO_GLOBAL", line 757<br />ORA-06512: at "APPS.MO_GLOBAL", line 700<br />ORA-06512: at line 1 </span><br /><br /> The reason for this error is Oracle Apps <span style="font-weight:bold;">seeded</span> pages which have AM with multi-org enabled,if you will check the AM xml file , they use MULTIORG_ENABLED as <span style="font-weight:bold;">Y</span> and not as <span style="font-weight:bold;">S </span>or <span style="font-weight:bold;">M</span> . This is because in Apps, you can directly register an application with multi-org enabled in table fnd_mo_product_init by using API :<br />-- To enable MO access in a custom application:<br />begin <br />FND_MO_PRODUCT_INIT_PKG.register_application('XXABC','SEED','N');<br />end;<br /><br /> Since, seeded applications are already registered here, its not a problem, when you run seeded pages because MULTIORG_ENABLED=Y in AM sets correct multi org access, but in case of custom application/responsibility based on custom application running seeded pages throws error, because the custom application XXABC is not registered in table fnd_mo_product_init. Hence , in order to run both seeded pages and custom pages fine i.e. code work correctly in case of MULTIORG_ENABLED=Y (used by seeded pages) or MULTIORG_ENABLED=S/M (custom pages), register the custom application using the FND_MO_PRODUCT_INIT_PKG.register_application API.Mukul Guptahttp://www.blogger.com/profile/05550600691296960397noreply@blogger.com11