Slides of the ODTUG Webinar: “Oracle ADF Immersion: How an Oracle Forms Developer Immersed Himself in the Oracle ADF World”

A few weeks ago we did an ODTUG Webinar: “Oracle ADF Immersion: How an Oracle Forms Developer Immersed Himself in the Oracle ADF World”.

About 186 followed the seminar online.
Those people received a link to the recorded session and the slides of the presentation.

For those who couldn’t attend, these are the slides of the presentation: ADF Immersion presentation
But the presentation was a lot more than a few slides, there was also a demo(>30 minutes).
So if you want to see the full recording, you can see all past webinars as a full ODTUG member.

If you need more info on ADF methodologies and ADF best practices or want to ask questions about these topics, check out the ADF EMG group.

Starting with ADF 11G Logging

In software development, logging is an indispensible part of the job. When developing  java programs, Log4j (Apache framework) is probably the most commonly used framework.

But when we are writing Java programs, using the Oracle ADF framework, there is another option : ADF Logger. This logger is integrated in the Weblogic enterprise manager, and gives you the flexibility to adjust your log-levels at runtime. This blog post briefly demonstrates how the ADF logging works, using a servlet that logs at all levels.

The first example is run on a remote Weblogic server. At the end of the post the same example is run within the integrated Weblogic server of JDeveloper.

First we start with viewing the loggers defined in Oracle Enterprise Manager (OEM) before our servlet is deployed :

em_go_to_logconfig_2

When we select ‘Log Configuration’ we get the Log Configuration screen, where some loggers are already defined and their loglevels can be configured :

em_initieel_2

We’ll deploy a servlet that uses the ADF Logger, change the loglevels at runtime, and check the logging to see what happens.

So fire up your JDeveloper and select a new Fusion Web Application (ADF) or download the JDeveloper project from  https://www.dropbox.com/s/mwkjdw8k265iadx/LoggerApp.zip

Then create a servlet like the one below, which is a simple servlet called ‘ExecuteLogger’ that logs a message on all loglevels :


package be.iadvise.loggerapp;

 import java.io.IOException;
 import java.io.PrintWriter;

 import java.util.Calendar;

 import javax.servlet.*;
 import javax.servlet.http.*;

 import oracle.adf.share.logging.ADFLogger;

 public class ExecuteLogger extends HttpServlet {
  private static final String CONTENT_TYPE = "text/html; charset=UTF-8";

 private static ADFLogger _log = ADFLogger.createADFLogger(ExecuteLogger.class);

  public void init(ServletConfig config) throws ServletException {
  super.init(config);
  }

 public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  response.setContentType(CONTENT_TYPE);
  PrintWriter out = response.getWriter();
  out.println("<html>");
  out.println("<head><title>Executing logging with ADFLogging and System.out.println</title></head>");

 Calendar cal = Calendar.getInstance();
  String loggingId = Long.toString(cal.getTimeInMillis());
  out.println("<h1>Executing logging with ADFLogging and System.out.println</h1>");
  out.println("<h2>Used Logging id = "+loggingId+"</h2>");
  out.println("<p>The logging id is different for each request.</br>Use the logging id to search the log messages in the logfiles or EM for this request.");
  out.println("<p>Logger Name in EM = "+_log.getName());

  out.println("<p>****************** START LOGGING ******************");

  out.println("<table >");

 // FINEST
  _log.finest("Loglevel finest : This is a logmessage with the ADFLogger. Logging id = "+loggingId);
  System.out.println("Loglevel finest : This is a logmessage with the System.out.println. Logging id = "+loggingId);
  out.println("<tr><td>FINEST</td><td>Loglevel finest : logMessage written to ADFLogger and System.out.println. Logging id = "+loggingId+"</td></tr>");

  // FINER
  _log.finer("Loglevel finer : This is a logmessage with the ADFLogger. Logging id = "+loggingId);
  System.out.println("Loglevel finer : This is a logmessage with the System.out.println. Logging id = "+loggingId);
  out.println("<tr><td>FINER</td><td>Loglevel finer : logMessage written to ADFLogger and System.out.println. Logging id = "+loggingId+"</td></tr>");

  // FINE
  _log.fine("Loglevel fine : This is a logmessage with the ADFLogger. Logging id = "+loggingId);
  System.out.println("Loglevel fine : This is a logmessage with the System.out.println. Logging id = "+loggingId);
  out.println("<tr><td>FINE</td><td>Loglevel fine : logMessage written to ADFLogger and System.out.println. Logging id = "+loggingId+"</td></tr>");

  // CONFIG
  _log.config("Loglevel config : This is a logmessage with the ADFLogger. Logging id = "+loggingId);
  System.out.println("Loglevel config : This is a logmessage with the System.out.println. Logging id = "+loggingId);
  out.println("<tr><td>CONFIG</td><td>Loglevel config : logMessage written to ADFLogger and System.out.println. Logging id = "+loggingId+"</td></tr>");

  // INFO
  _log.info("Loglevel info : This is a logmessage with the ADFLogger. Logging id = "+loggingId);
  System.out.println("Loglevel info : This is a logmessage with the System.out.println. Logging id = "+loggingId);
  out.println("<tr><td>INFO</td><td>Loglevel info : logMessage written to ADFLogger and System.out.println. Logging id = "+loggingId+"</td></tr>");

  // WARNING
  _log.warning("Loglevel warning : This is a logmessage with the ADFLogger. Logging id = "+loggingId);
  System.out.println("Loglevel warning : This is a logmessage with the System.out.println. Logging id = "+loggingId);
  out.println("<tr><td>WARNING</td><td>Loglevel warning : logMessage written to ADFLogger and System.out.println. Logging id = "+loggingId+"</td></tr>");

  // SEVERE
  _log.severe("Loglevel severe : This is a logmessage with the ADFLogger. Logging id = "+loggingId);
  System.out.println("Loglevel severe : This is a logmessage with the System.out.println. Logging id = "+loggingId);
  out.println("<tr><td>SEVERE</td><td>Loglevel severe : logMessage written to ADFLogger and System.out.println. Logging id = "+loggingId+"</td></tr>");

  out.println("</table>");

  out.println("<p>****************** END LOGGING ******************");

  out.println("<body>");
  out.println("</body></html>");
  out.close();
  }
 }
 

Then, map this servlet in your web.xml as follows :

<servlet>
 <servlet-name>ExecuteLogging</servlet-name>
 <servlet-class>be.iadvise.loggerapp.ExecuteLogger</servlet-class>
 </servlet>
 <servlet-mapping>
 <servlet-name>ExecuteLogging</servlet-name>
 <url-pattern>/executeLogging</url-pattern>
 </servlet-mapping>

The line

private static ADFLogger _log = ADFLogger.createADFLogger(ExecuteLogger.class);

will create an entry in the ADF logging panel of OEM  for the class ‘be.iadvise.loggerapp.ExecuteLogger’ during the first execution of our servlet.

So generate the ear file (in JDeveloper : Application -> Deploy -> your application) , and deploy to an ear , and deploy the ear to your remote Weblogic.

Then, execute the servlet by entering following url in a browser http://server:port/appname/executeLogger

We will receive the following output where the logging id is a unique id for every request (this will help us find the log info logged for every run) :

output_servlet_3

and in our log configuration screen, the logger for our servlet is added automatically with level WARNING :

EM_na_uitvoeren_servlet_2

When we look to the logging itself, by selecting the following :

go_to_logmessages

We see that our servlet has logged 2 lines  : level WARNING and ERROR, as the logger was default created with level “warning”.

(We look in the log files for the id generated by the servlet to get our 2 lines)

output_first_log_2

Now let’s update our log level to TRACE (finest), press apply, confirm the update, execute the servlet again , and see what happens to our logging :

trace

confirm the update :

confirm

execute the servlet again (it generates a new logging id)

new_servlet

look for the generated logging :

new_logging

As we have set the loglevel to trace (finest), which is the lowest level, we see all the generated loglines.

Remark : When we undeploy the application, the logger will remain visible in the log configuration screen until the managed server is restarted.

Using the integrated Weblogic server in JDeveloper

This screen shot shows you how get to the log configuration and logging screen in JDeveloper :

1_go_log_screen

After executing the servlet locally, the Oracle Diagnostic Logging will show you the following :

2_log_config

and the analyze log :

3_logging_first_run

then we change the log level :

4_change_log_level

and execute the servlet again and watch the output :

5_output_logging_2

That’s it !!!

The big advantage of ADFLogging is the update of the loglevel at runtime, so whenever something seems to be going wrong, just set the loglevel to e.g. TRACE and check the logfiles. When the problem is solved reset it to WARNING or ERROR. And this without having to restart your application.

Also, being able to view and search the logfiles using the EM increases the userfriendlyness of this system. You don’t have to access the files directly on the system anymore.

ODTUG Webinar: “Oracle ADF Immersion: How an Oracle Forms Developer Immersed Himself in the Oracle ADF World”

On Oracle Open World we had the chance to present our “Oracle ADF Immersion” track thanks to the ADF EMG.
In case you couldn’t attend OOW or missed the session, you’ve got another chance: on january 10, 2013 we will present it as an ODTUG Webinar.

We will show you how you can start with ADF, coming from an Oracle Forms(or non-java) background.
You can register for the webinar here.

If you like to join the ADF EMG, don’t hesitate, it’s a free ADF usergroup!

Generating XML from SQL & PL/SQL and Code Instrumentation

From time to time you’ll have to represent your data stored in a database in an XML format, eg. to exchange it between systems, to send it to external parties, etc.
In an article on All Things Oracle I give an introduction on how you can generate XML documents:

 

Another interesting article from my colleague Jan Leers is about Code Instrumentation.

Whenever we execute a procedure, it’s out of our hands. We expect it to do what it was designed to do, but what if it doesn’t?
What if it takes a lot more time then expected?
All kind of questions start to arise:

  • Is it almost finished, should I wait just a few more minutes?
  • Is it trapped in an infinitive loop? Or are my queries running slow?
  • Can I safely kill it? Or did it already commit some changes and should I reverse them?
  • Which job should I kill, is this mine?

Want to find out how you can answer these questions?  Read his article on All Things Oracle

SQL Developer Dbms Output Pane gone…

I already managed to remove the Dbms Output pane a couple of times from my SQL Developer, probably by doing a keyboard combination by accident.
I am not sure how I did this and I can’t really reproduce this but sometimes I was bugged with this problem.

Problem is that I can’t get this pane back by following the ‘normal’ procedure (going to Menu-> View->Dbms-Output).
Previously I did not found a proper solution for this and I just had to reinstall the sqldeveloper all over again.
Untill now, I found a really easy way to get this pane back.

First of all exit all your sqldevelopers sessions.
Go to the directory where the sqldeveloper is installed (the numbering of the directories could be different from one version to another, but it will look similar to this)
cd /home/vallafr/.sqldeveloper/system3.1.07.42/o.ide.11.1.1.4.37.59.48

there remove the windowinglayout.xml file
rm windowinglayout.xml

This file contains your ‘custom’ sqldeveloper layout. By removing this the sqldeveloper layout will be reset to the original settings.

Then restart your SqlDeveloper
in sqldeveloper go to Menu -> View -> Dbms_Output
And tadaaa  there it is again :)

Seminar: Oracle and Reporting(Mechelen 08/11/2012)

Do you have one or more applications on top of on Oracle Database?

Do you want to show this data in documents and/or reports?

Did you know you don’t have to make a big investment in a BI solution to create attractive letters, orders, invoices or lists?

But which reporting tool, from a long list, is the best solution?

After many years of using and testing different tools, we will show and share our experiences of our preferred reporting tools:

  • Oracle Application Express
  • Oracle Reports
  • Oracle BI Publisher
  • JasperReports
  • SQL Word
  • Eclipse Birt
  • PL/PDF
  • DocuFy

We’re going to demo and compare those tools so you can learn the possibilities, advantages/disadvantages, …
Of course we’re also taking the learning curves and prices in count, so you can find out the best solution for you and your company.

More info and Registration(Dutch)

Apex Extension

About a month ago I saw a mail coming by where a colleague of mine had integrated the jQuery plug-in Codemirror into a text area for the end-user. I hadn’t seen this plug-in before, but I really liked the feel of it.

I’m sure all of us can recognize the fact that we miss tab indentation in  APEX, or that we would like to see key words, numbers and strings in color, or how about some line numbers? Perhaps line numbers that hold into account that the line number of an error in a PL/SQL APEX process is never quite the same as the place of the error. This last one is because APEX places BEGIN and END; automatically around PL/SQL processes. Convenient for the developer so he can develop faster, not so much when it comes down to debugging.

Since we can not change the APEX Application Builder, it would be nice to find another solution? And that solution exists: take a look at the following screenshots:

Image

Image

So how did I do it? A little “thinking outside the box” did the trick. While we might not want to mess with Apex directly, we can use browser Extensions and add-ons, to alter the looks, safely from a distance. So I created a small Chrome Extension that integrates CodeMirror into the APEX Text Areas.

Chrome Extensions are created with HTML5 and JS so once you have the basics of your Extension set up you can convert an Apex Text Area like this:
var vTextArea=document.getElementById(“F4000_P4312_PROCESS_SQL2″);

vMyEditor = CodeMirror.fromTextArea(vTextArea, {

mode: “text/x-plsql”,
tabMode: “indent”,
tabSize : 2,
lineNumbers: true,
firstLineNumber: 2,
lineWrapping: true
});

I wrapped this in a “$(document).ready(function(){});” to make sure it is executed after loading all plug-ins.

I hope I showed you all that you can do allot with a little imagination, and I welcome any questions or suggestions.

Joni Vandenberghe