Getting Started with Oracle WebLogic Server 12c: Developer’s Guide


Getting_Started_with_Oracle_WebLogic_Server_12c-_Developer’s_Guide

Getting Started with Oracle WebLogic Server 12c: Developer’s Guide

It took me a while to update the blog and get back on writing again due to the elaboration of this new material which became the Getting Started withx Oracle WebLogic Server 12c: Developer’s Guide book.  We started to write the book about 12c (12.0.0) which ended up being an not so stable  OK version and had to rapidly update to 12.0.1.

But then, when we’re about to finish the book the 12.0.2 release came out with a lot of improvements and we again updated all the material and included the revisions for the new installer, new type of WebLogic clusters and new JMS resources targeting, among other changes that this version had.

The book follows a tutorial approach, with step-by-step instructions and a lot of screenshots to make it very easy for new users and people that are really starting with the product.

Hopefully I’m going to get back on publishing more frequently on the blog, but now “It’s all about GemFire“! ;)

Java EE 6 Tutorial: Updates and book release

Hey! In the first post of 2013, I would like to share some work we’ve been doing on the Java EE 6 Tutorial team.

This month we released an updated version (6.0.8) that is now available from the Java EE SDK Update Center and here. This update has the following enhancements:

  • New information on securing web applications
  • Revised material on using Contexts and Dependency Injection for Java (CDI)
  • Updated database schema diagrams for the Java Persistence API example applications
  • New features in the customer JAX-RS example
  • Internationalization support in the Duke’s Forest and Duke’s Bookstore case-study example applications
  • Minor bug fixes and improvements

Book release

The Java EE 6 Tutorial book coverThe Java EE 6 Tutorial: Advanced Topics book is now available in paperback, Kindle and Nook versions.This book is the second volume, building on the concepts introduced in The Java EE 6 Tutorial: Basic Concepts. It introduces the Java Message Service (JMS) and Java EE Interceptors, and documents advanced features of JavaServer Faces, Servlets, JAX-RS, Enterprise JavaBeans, the Java Persistence API, Bean Validation, CDI, and enterprise application security. The book culminates with three new case-study applications that illustrate the use of multiple Java EE 6 APIs in common application use cases.

Links

How to add third-party JDBC drivers on WebLogic

Oracle WebLogic data sources supports many databases types by default and also comes with some JDBC drivers for most of them.

But, not very often, you are working with third-party databases (non-Oracle) and endup needing to download the JDBC drivers from the database provider and doing the setup on WebLogic by yourself. The steps are pretty simple, but some still have questions on how to do it and I will try to create a step-by-step guide on this post.

In this example, the environment is Oracle WebLogic 12c running on a Mac OS X and doing the simulation of a Microsoft SQL Server JDBC Driver installation.

To simulate the issue of a missing driver, try to create a new Data Source selecting the following parameters on a default installation:

  • Database Type: MS SQL Server
  • Database Driver: Microsoft’s SQL Server Driver (Type 4) Version: 2005 and later

Complete the wizard with your database access information (host, port, username, password) and try to Test the Connection before saving. You should see the error below stating that you don’t have the driver classes on the classpath.

Image

Ok, let’s setup the JDBC driver:

      1. Download the JDBC Driver – MS SQL Server JDBC drivers are currently hosted on this link: http://msdn.microsoft.com/en-us/sqlserver/aa937724.aspx
      2. Unpack the zip or tarball with the JDBC driver jar file and copy the specified file to the WebLogic installation directory, under the ${WL_HOME}/server/lib folder.
        (markito@luke)$ tar -xzvpf sqljdbc_4.0.2206.100_enu.tar.gz
        (markito@luke)$ cd sqljdbc_4.0/enu/
        (markito@luke)$ cp sqljdbc.jar ${WL_HOME}/server/lib/
        
      3. Now, modify the commEnv.sh script. This script sets common environment variables for WebLogic and set the WebLogic classpath with some base libraries from the WebLogic installation directory.
        The file is located under: ${WL_HOME}/common/bin/commEnv.shBefore:

        # set up WebLogic Server's class path
        WEBLOGIC_CLASSPATH="${JAVA_HOME}/lib/tools.
        jar${CLASSPATHSEP}${WL_HOME}/server/lib/weblogic_sp.
        jar${CLASSPATHSEP}${WL_HOME}/server/lib/weblogic.
        jar${CLASSPATHSEP}${FEATURES_DIR}/weblogic.server.modules_13.1.1.0.
        jar${CLASSPATHSEP}${WL_HOME}/server/lib/webservices.
        jar${CLASSPATHSEP}${ANT_HOME}/lib/ant-all.
        jar${CLASSPATHSEP}${ANT_CONTRIB}/lib/ant-contrib.jar"
        export WEBLOGIC_CLASSPATH
        

        After:

        # set up WebLogic Server's class path
        WEBLOGIC_CLASSPATH="${JAVA_HOME}/lib/tools.
        jar${CLASSPATHSEP}${WL_HOME}/server/lib/weblogic_sp.
        jar${CLASSPATHSEP}${WL_HOME}/server/lib/weblogic.
        jar${CLASSPATHSEP}${FEATURES_DIR}/weblogic.server.modules_13.1.1.0.
        jar${CLASSPATHSEP}${WL_HOME}/server/lib/webservices.
        jar${CLASSPATHSEP}${ANT_HOME}/lib/ant-all.
        jar${CLASSPATHSEP}${ANT_CONTRIB}/lib/ant-contrib.jar
        <strong>jar${CLASSPATHSEP}${WL_HOME}/server/lib/sqljdbc4.jar"
        export WEBLOGIC_CLASSPATH
        
      4. Now restart the WebLogic server and repeat the process to create a new MS SQL Server data source.

There is a bonus step which is not always required – Since you’re using a new JDBC driver, sometimes you don’t have the entry under WebLogic database drivers list. To update this list modify the ${WL_HOME}/server/lib/jdbcdrivers.xml file accordingly, the description of the file is very explanatory:

<!-- This xml file contains meta information regarding JDBC Driver's and making connections to the DBMS.
It is designed to hold information so that UI can gather information from a user and configure
The Driver classname, The Driver URL and the driver Properties to make a connection to the DBMS

This XML entry is a required peice of data that could be required in the URL or in the properties object

       There are 5 well known property names:
       DbmsHost
       DbmsPort
       DbmsName
       DbmsUsername
       DbmsPassword

       Properties that don't match the well know ones above, will be passed as name=value pairs to either
       the URL or the properties object (based on InURL=false or true.

       Then the UI would prompt:
       Please Enter
       Database Type : normal
       This is required to Indicate your DB type.
       And after the user providing it the UI would stuff it into the JDBCDriverInfo object and the JDBCURLHelper would do the right thing with it
       stick it in the URL or in the properties object
--!>

Remember that although you can add or update third-party drivers, you should still follow the supported database list provided by the WebLogic Certification Matrix in order to keep with a supported installation.

References:

http://docs.oracle.com/cd/E24329_01/web.1211/e24367/third_party_drivers.htm

CDI Events – Synchronous x Asynchronous

Context Dependency Injection or CDI (JSR-220 / JSR-330) is one of the greatest features of Java EE 6.  It brings simplicity to a lot of areas where previous version of Java EE required tons of Interfaces, XML’s and a lot of boilerplate code to create simple things.

This post is going to show some simple examples on how to use Java EE 6 and CDI Events with synchronous and asynchronous patterns, which is also part of the new specifications.

First, let’s define what synchronous and asynchronous means in this context:

Synchronous – Execution or processing that happens on the same thread and need immediate response or process completion to continue. It also means that a call to a synchronous method will block (wait) the caller until it’s completion. Example: A traditional HTTP Request.

Asynchronous – Execution or processing that doesn’t need immediate or any response and will be processed on a different thread than the caller’s thread. This means that an asynchronous caller doesn’t need to be waiting for the process to complete and may receive a callback when the work is done. Example: Sending a JMS message, Performing an AJAX call on a web page.

Thread Pools

Thread Pools are one of the most efficient patterns when dealing with Threads. Conceptually it works as a pool of workers and a queue of tasks which get’s executed by different threads. When those threads finishes processing the task, it will automatically get the next one on the queue to process until the queue is empty. The thread lifecycle is also managed by the pool, so a well managed pool can save a lot of resources keeping the number of threads to a good level maintaining the balance between number of threads and tasks on the queue.

Application Servers have to deal with several (thousands, millions..) of requests and different services like JDBC, JMS, EJB and JCA, each of theses tasks consumes threads to complete their work. So, internally most application servers create thread pools to isolate the resource consumption of these tasks and make a better usage of hardware threads according to the applications needs.

Synchronous Events

The default strategy for CDI events is synchronous, which is very simple to implement.

// imports omitted for brevity
@Named
public ShoppingCart {

  @Inject
  Event<String> eventService;

  public void checkout(OrderEvent event) {
      eventService.fire(event);
  }
}

And to receive/observe the event:

// imports omitted for brevity
@Named
public PaymentHandler {

 public void onNewOrder(@Observers OrderEvent event) {

     Log.info("Event captured - " + event)
  }
}

It’s also possible to use Qualifiers and perform kind of “selector” (for reference check this) and filter the events based on the qualifiers.

When you deploy an application with these beans and consume them from a JSF page or a Servlet, the request will be processed consuming a Thread from the HTTP Thread Pool that will stay in use until the response is committed.  Let’s assume you have multiple @Observers for the same event. In this case, all the work done by the @Observers will occur on the same Thread as the request, which is in this case the HTTP request.

Depending on the scenario, this behavior is acceptable, but if your @Observers are performing long-running tasks and you have users waiting for their request to complete on a web application, it may not be the case.

This can be easily addressed with a real Asynchronous processing for events and observers.

Asynchronous Events

Asynchronous events can be implemented using CDI and EJB with the help of @Asynchronous annotation.

First, let’s write a Stateless EJB that will be responsible for dispatching the events:

// imports omitted for brevity
@Named("EventDisptacherBean")
@Stateless
public class EventDispatcherBean {

     private static final Logger logger = Logger.getLogger(EventDispatcherBean.class.getCanonicalName());

    @Inject
    Event<OrderEvent> eventManager;

    @Asynchronous
    public void publish(OrderEvent event) {
        logger.log(Level.FINEST, "{0} Sending event from EJB", Thread.currentThread().getName());
        eventManager.fire(event);
    }
}

Please note the usage of the @Asynchronous annotation on the publish method, this will decouple the Thread from the HTTP request and pass the processing context to the EJB Thread pool and since the return is set as void, this will be processed as a fire-and-forget call, where no return is expected. (off-topic: I do appreciate the reference to fire-n-forget missiles)

// imports omitted for brevity
@Stateless
public class DeliveryHandler implements Serializable {

    private static final Logger logger = Logger.getLogger(DeliveryHandler.class.getCanonicalName());

    @EJB
    OrderBean orderBean;

    @Override
    @Asynchronous
    public void onNewOrder(@Observes OrderEvent event) {

        logger.log(Level.FINEST, "{0} Event being processed by DeliveryHandler", Thread.currentThread().getName());

        try {
            logger.log(Level.INFO, "Order #{0} has been paid amount of {1}. Order ready to delivery!", new Object[]{event.getOrderID(), event.getAmount()});

            orderBean.setOrderStatus(event.getOrderID(), OrderBean.Status.READY_TO_SHIP);

        } catch (Exception jex) {
            logger.log(Level.SEVERE, null, jex);
        }
    }
}

Then, there is the event observer and as you can see it also uses the @Asynchronous annotation, which will decouple the event processing from the event publisher as this bean is also an EJB, so it will only consume Threads from the EJB Thread pool.

With this modification, we should be able to get a higher throughput on the web application since we’re not sharing threads to process HTTP requests and CDI events, each of them with it’s own Thread Pool.

For more details, check the complete implementation of this application available as part of the Java EE 6 Tutorial case study – Duke’s Forest.

Adding global exception handling using JSF 2.x ExceptionHandler

This a great feature of JSF 2.x: A generic API to manipulate application exception in a global manner. In order to implement this you must implement (extend) two different classes:

ExceptionHandlerWrapper – Provides a simple implementation of ExceptionHandler that can be subclassed by developers wishing to provide specialized behavior to an existing ExceptionHandler instance. The default implementation of all methods is to call through to the wrapped ExceptionHandler instance.

ExceptionHandlerFactory – A factory object that creates (if needed) and returns a new ExceptionHandler instance.

On Duke’s Forest this is the implementation:

CustomExceptionHandlerFactory.java:

package com.forest.exception;

public class CustomExceptionHandlerFactory extends ExceptionHandlerFactory {
   private ExceptionHandlerFactory parent;

   // this injection handles jsf
   public CustomExceptionHandlerFactory(ExceptionHandlerFactory parent) {
    this.parent = parent;
   }

    @Override
    public ExceptionHandler getExceptionHandler() {

        ExceptionHandler handler = new            CustomExceptionHandler(parent.getExceptionHandler());

        return handler;
    }

}

CustomExceptionHandlerFactory.java:

package com.forest.exception;

public class CustomExceptionHandler extends ExceptionHandlerWrapper {
    private static final Logger log = Logger.getLogger(CustomExceptionHandler.class.getCanonicalName());
    private ExceptionHandler wrapped;

    CustomExceptionHandler(ExceptionHandler exception) {
        this.wrapped = exception;
    }

    @Override
    public ExceptionHandler getWrapped() {
        return wrapped;
    }

    @Override
    public void handle() throws FacesException {

        final Iterator<ExceptionQueuedEvent> i = getUnhandledExceptionQueuedEvents().iterator();
        while (i.hasNext()) {
            ExceptionQueuedEvent event = i.next();
            ExceptionQueuedEventContext context =
                    (ExceptionQueuedEventContext) event.getSource();

            // get the exception from context
            Throwable t = context.getException();

            final FacesContext fc = FacesContext.getCurrentInstance();
            final Map<String, Object> requestMap = fc.getExternalContext().getRequestMap();
            final NavigationHandler nav = fc.getApplication().getNavigationHandler();

            //here you do what ever you want with exception
            try {

                //log error ?
                log.log(Level.SEVERE, "Critical Exception!", t);

                //redirect error page
                requestMap.put("exceptionMessage", t.getMessage());
                nav.handleNavigation(fc, null, "/error");
                fc.renderResponse();

                // remove the comment below if you want to report the error in a jsf error message
                //JsfUtil.addErrorMessage(t.getMessage());

            } finally {
                //remove it from queue
                i.remove();
            }
        }
        //parent hanle
        getWrapped().handle();
    }
}

And add the following lines to your faces-config.xml:

<factory>
        <exception-handler-factory>
            com.forest.exception.CustomExceptionHandlerFactory
        </exception-handler-factory>
</factory>

In the try-finally block you can cast the Throwable to any specific exception and do  any special treatment that you want. For example: ViewExpiredException can be redirected to a “Session Expired” page and on the other hand, NullPointerException can use the common generic page just saying that “An unexpected situation occurred, please try again later.”

In line 40 I’m redirecting to a common error page (/error) which can read error information from the request map.

Please note that when dealing with exceptions and web development, you must ensure that you are not sharing any unwanted sensitive information when returning the error to the web page.

To see the complete running example please check The Java EE 6 Tutorial and check Duke’s Forest case study.

References:

My Article at OTN: Oracle Service Bus and Coherence caching example

Today I’ve published an article at Oracle Technology Network (OTN) about Oracle Service Bus and Oracle Coherence integration. It shows a case study example and how you can use caching strategies for  Web Services.

It’s a step-by-step tutorial on how to setup a Coherence Server with Weblogic, how to access this server with Coherence console and how to use out-of-process caching strategy to scale your caching with no impact on the Enterprise Service Bus.

To read the full article click here.

References:

JAVA Standards in Weblogic 10.3.4

 

Standard Version
JAAS 1.0 Full
Java API for XML-Based Web Services (JAX-WS) 2.1, 2.0
Java Authorization Contract for Containers (JACC) 1.1
Java EE 5.0
Java EE Application Deployment 1.2
Java EE CA 1.5, 1.0
Java EE EJB 3.0, 2.1, 2.0, and 1.1
Java EE Enterprise Web Services 1.2, 1.1
Java EE JDBC 4.0, 3.0
Java EE JMS 1.1, 1.0.2b
Java EE JNDI 1.2
Java EE JSF 2.0, 1.2, 1.1
Java EE JSP 2.1, 2.0, 1.2, and 1.1
Java EE Servlet 2.5, 2.4, 2.3, and 2.2
Java RMI 1.0
JavaMail 1.4
JAX-B 2.1, 2.0
JAX-P 1.2, 1.1
JAX-R 1.0
JAX-RPC 1.1, 1.0 (deprecated)
JCE 1.4
JDKs 6.0 (aka 1.6), 5.0 (aka 1.5, clients only)
JMX 1.2, 1.0
JPA 1.0, 2.0

For information on JPA 2.0 support, see Support for JPA 2.0 Providers.

JSR 77: Java EE Management 1.1
JSTL 1.2
OTS/JTA 1.2 and 1.1
RMI/IIOP 1.0
SOAP Attachments for Java (SAAJ) 1.3, 1.2
Streaming API for XML (StAX) 1.0
Web Services Metadata for the Java Platform 2.0, 1.1

Source: http://download.oracle.com/docs/cd/E17904_01/web.1111/e13852/toc.htm