Showing posts with label Weblogic. Show all posts
Showing posts with label Weblogic. Show all posts

Thursday, October 29, 2015

WLS deployment via Jersey REST client

 

Outline

 

Introduction

For programmatic deployment to Oracle Weblogic Server a very easy approach is to use the Oracle Weblogic Server Management REST API.

 

curl -v \
--user username:password \
-H X-Requested-By:MyClient \
-H Accept:application/json \
-H Content-Type:application/json \
-d "{
name: 'BasicApp',
deploymentPath:
'/deployments/BasicApp/app/BasicApp.ear',
targets: [
'myserver' ]
}
" \
-X POST http://localhost:7001/management/wls/latest/deployments/application

The benefits here are related to:


  • Granular WLS targeting
  • Integration into a CI process via Maven/ANT…

The challenges are related to dealing with SSL connections (importing CA certificates to the REST client). In this initial article we’ll trust all the certificates. Another article will follow that will describe how to import CA certificates to the REST client.


Jersey REST Client


You need to provide the following parameters to your client:


  • WLS username
  • WLS password
  • WLS REST endpoint
  • Deployment path
  • String Model which is a JSON({ name: '${deploymentName}', targets: ['${wls-targets}'] }) containing the:
  • Deployment name
  • Targets

The client code:


 


1 import java.io.File;
2 import java.security.SecureRandom;
3
4 import javax.net.ssl.HostnameVerifier;
5 import javax.net.ssl.HttpsURLConnection;
6 import javax.net.ssl.SSLContext;
7 import javax.net.ssl.SSLSession;
8 import javax.ws.rs.core.MediaType;
9
10 import com.sun.jersey.api.client.Client;
11 import com.sun.jersey.api.client.ClientResponse;
12 import com.sun.jersey.api.client.WebResource;
13 import com.sun.jersey.api.client.config.ClientConfig;
14 import com.sun.jersey.api.client.config.DefaultClientConfig;
15 import com.sun.jersey.api.client.filter.HTTPBasicAuthFilter;
16 import com.sun.jersey.client.urlconnection.HTTPSProperties;
17 import com.sun.jersey.multipart.FormDataMultiPart;
18 import com.sun.jersey.multipart.file.FileDataBodyPart;
19
20 public class JerseyClientPost {
21
22 public static void main(String[] args) {
23 String proxyHost = "";
24 String proxyPort = "";
25 String username = args[0];
26 String password = args[1];
27 String restURL = args[2];
28 String deploymentPath = args[3];
29 String stringModel = args[4];
30
31 try {
32
33 String model = stringModel;
34
35 Client client = Client.create(configureClient());
36
37 WebResource webResource = client.resource(restURL);
38
39 client.addFilter(new HTTPBasicAuthFilter(username, password));
40 webResource.header("x-requested-by", "WLSMavenDeployClient");
41 webResource.header("accept", "application/json");
42 webResource.header("content-type", "multipart/form-data");
43
44 FileDataBodyPart deployment = new FileDataBodyPart("deployment",
45 new File(deploymentPath),
46 MediaType.APPLICATION_OCTET_STREAM_TYPE);
47
48 FormDataMultiPart multiPart = new FormDataMultiPart();
49 multiPart.bodyPart(deployment);
50 multiPart.field("model", model, MediaType.APPLICATION_JSON_TYPE);
51
52 ClientResponse response = webResource.type(
53 MediaType.MULTIPART_FORM_DATA_TYPE).post(
54 ClientResponse.class, multiPart);
55
56 System.out.println("");
57 System.out.println("response2 : " + response.toString());
58 String output = response.getEntity(String.class);
59 System.out.println(output);
60 System.out.println("");
61
62 if (response.getStatus() != 201) {
63 throw new RuntimeException("Failed : HTTP error code : "
64 + response.getStatus());
65 }
66
67 } catch (Exception e) {
68
69 e.printStackTrace();
70
71 }
72
73 }
74
75 public static ClientConfig configureClient() {
76 System.setProperty("jsse.enableSNIExtension", "false");
77 try {
78 trustAllHttpsCertificates();
79 } catch (Exception e1) {
80 // TODO Auto-generated catch block
81 e1.printStackTrace();
82 }
83
84 SSLContext ctx = null;
85 javax.net.ssl.TrustManager[] trustAllCerts =
86
87 new javax.net.ssl.TrustManager[1];
88
89 javax.net.ssl.TrustManager tm = new miTM();
90
91 trustAllCerts[0] = tm;
92
93 javax.net.ssl.SSLContext sc;
94 try {
95 sc = javax.net.ssl.SSLContext.getInstance("SSL");
96 sc.init(null, trustAllCerts, null);
97 javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(
98
99 sc.getSocketFactory());
100 } catch (Exception e2) {
101 // TODO Auto-generated catch block
102 e2.printStackTrace();
103 }
104
105 try {
106 ctx = SSLContext.getInstance("SSL");
107 ctx.init(null, trustAllCerts, new SecureRandom());
108 } catch (java.security.GeneralSecurityException ex) {
109 }
110 HttpsURLConnection.setDefaultSSLSocketFactory(ctx.getSocketFactory());
111 try {
112 trustAllHttpsCertificates();
113 } catch (Exception e1) {
114 // TODO Auto-generated catch block
115 e1.printStackTrace();
116 }
117 ClientConfig config = new DefaultClientConfig();
118 try {
119 config.getProperties().put(
120 HTTPSProperties.PROPERTY_HTTPS_PROPERTIES,
121 new HTTPSProperties(new HostnameVerifier() {
122
123 @Override
124 public boolean verify(String hostname,
125 SSLSession session) {
126 // TODO Auto-generated method stub
127 return true;
128 }
129 }, ctx));
130
131 } catch (Exception e) {
132 }
133 return config;
134 }
135
136 private static void trustAllHttpsCertificates() throws Exception {
137
138 // Create a trust manager that does not validate certificate chains:
139 System.out
140 .println("\n[WARNING] SSL INSECURE: Trusting all https certificates\n");
141
142 javax.net.ssl.TrustManager[] trustAllCerts =
143
144 new javax.net.ssl.TrustManager[1];
145
146 javax.net.ssl.TrustManager tm = new miTM();
147
148 trustAllCerts[0] = tm;
149
150 javax.net.ssl.SSLContext sc =
151
152 javax.net.ssl.SSLContext.getInstance("SSL");
153
154 sc.init(null, trustAllCerts, null);
155
156 javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(
157
158 sc.getSocketFactory());
159
160 }
161
162 public static class miTM implements javax.net.ssl.TrustManager,
163 javax.net.ssl.X509TrustManager {
164 public java.security.cert.X509Certificate[] getAcceptedIssuers() {
165 return null;
166 }
167
168 public boolean isServerTrusted(
169 java.security.cert.X509Certificate[] certs) {
170 return true;
171 }
172
173 public boolean isClientTrusted(
174 java.security.cert.X509Certificate[] certs) {
175 return true;
176 }
177
178 public void checkServerTrusted(
179 java.security.cert.X509Certificate[] certs, String authType)
180 throws java.security.cert.CertificateException {
181 return;
182 }
183
184 public void checkClientTrusted(
185 java.security.cert.X509Certificate[] certs, String authType)
186 throws java.security.cert.CertificateException {
187 return;
188 }
189 }
190
191

Trusting all the certificates


For simplicity, whenever your WLS server is listening only on https(SSL), we are trusting all the certificates.

THIS IS NOT A RECOMMENDED SECURE APPROACH !

 


1 public static ClientConfig configureClient() {
2 System.setProperty("jsse.enableSNIExtension", "false");
3 try {
4 trustAllHttpsCertificates();
5 } catch (Exception e1) {
6 // TODO Auto-generated catch block
7 e1.printStackTrace();
8 }
9
10 SSLContext ctx = null;
11 javax.net.ssl.TrustManager[] trustAllCerts =
12
13 new javax.net.ssl.TrustManager[1];
14
15 javax.net.ssl.TrustManager tm = new miTM();
16
17 trustAllCerts[0] = tm;
18
19 javax.net.ssl.SSLContext sc;
20 try {
21 sc = javax.net.ssl.SSLContext.getInstance("SSL");
22 sc.init(null, trustAllCerts, null);
23 javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(
24
25 sc.getSocketFactory());
26 } catch (Exception e2) {
27 // TODO Auto-generated catch block
28 e2.printStackTrace();
29 }
30
31 try {
32 ctx = SSLContext.getInstance("SSL");
33 ctx.init(null, trustAllCerts, new SecureRandom());
34 } catch (java.security.GeneralSecurityException ex) {
35 }
36 HttpsURLConnection.setDefaultSSLSocketFactory(ctx.getSocketFactory());
37 try {
38 trustAllHttpsCertificates();
39 } catch (Exception e1) {
40 // TODO Auto-generated catch block
41 e1.printStackTrace();
42 }
43 ClientConfig config = new DefaultClientConfig();
44 try {
45 config.getProperties().put(
46 HTTPSProperties.PROPERTY_HTTPS_PROPERTIES,
47 new HTTPSProperties(new HostnameVerifier() {
48
49 @Override
50 public boolean verify(String hostname,
51 SSLSession session) {
52 // TODO Auto-generated method stub
53 return true;
54 }
55 }, ctx));
56
57 } catch (Exception e) {
58 }
59 return config;
60 }
61
62 private static void trustAllHttpsCertificates() throws Exception {
63
64 // Create a trust manager that does not validate certificate chains:
65 System.out
66 .println("\n[WARNING] SSL INSECURE: Trusting all https certificates\n");
67
68 javax.net.ssl.TrustManager[] trustAllCerts =
69
70 new javax.net.ssl.TrustManager[1];
71
72 javax.net.ssl.TrustManager tm = new miTM();
73
74 trustAllCerts[0] = tm;
75
76 javax.net.ssl.SSLContext sc =
77
78 javax.net.ssl.SSLContext.getInstance("SSL");
79
80 sc.init(null, trustAllCerts, null);
81
82 javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(
83
84 sc.getSocketFactory());
85
86 }
87
88 public static class miTM implements javax.net.ssl.TrustManager,
89 javax.net.ssl.X509TrustManager {
90 public java.security.cert.X509Certificate[] getAcceptedIssuers() {
91 return null;
92 }
93
94 public boolean isServerTrusted(
95 java.security.cert.X509Certificate[] certs) {
96 return true;
97 }
98
99 public boolean isClientTrusted(
100 java.security.cert.X509Certificate[] certs) {
101 return true;
102 }
103
104 public void checkServerTrusted(
105 java.security.cert.X509Certificate[] certs, String authType)
106 throws java.security.cert.CertificateException {
107 return;
108 }
109
110 public void checkClientTrusted(
111 java.security.cert.X509Certificate[] certs, String authType)
112 throws java.security.cert.CertificateException {
113 return;
114 }
115 }
116
117

Maven integration


For Continuous Integration we can use the above client to deploy our project directly from Maven. We can do that by using the org.codehaus.mojo plugin.

 


……
<wls-targets>MyCluster</wls-targets>
<wls-user>weblogic</wls-user>
<wls-password>MyPassword</wls-password>
<restEndpoint>https://<WLS-AdminServerIP>:7002/management/wls/latest/deployments/application </restEndpoint>
<deployment>target/MyApp.war</deployment>
<deploymentName>MyApp.war</deploymentName>
……
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2</version>
<configuration>
<mainClass>com.oracle.cloud.demo.oe.rest.JerseyClientPost</mainClass>
<arguments>
<argument>${wls-user}</argument>
<argument>${wls-password}</argument>
<argument>${restEndpoint}</argument>
<argument>target/MyApp.war</argument>
<argument>{ name: '${deploymentName}', targets: ['${wls-targets}'] }</argument>
</arguments>
</configuration>
<executions>
<execution>
<id>WLS-REST-DEPLOY</id>
<phase>WLS-REST-DEPLOY</phase>
<goals>
<goal>java</goal>
</goals>
</execution>
</executions>
</plugin>
……


Your maven invocation will look something like this: clean package exec:java

Thursday, February 7, 2013

Eclipse – OEPE bug (workaround): Cannot create application server connection (Weblogic, Tomcat, JBoss, …)

 

 

These days I was struggling with a Eclipse – OEPE bug. After deleting and adding several times some servers in the server tab I’ve noticed the following bug: the “add new server” wizard was informing that the password cannot be empty but in the same time the password field was read-only. This bug appears also when you move the workspace to another location/machine.

image

The solution(workaround) is quite simple:

  • you need to go to your {workspace-directory}/.metadata/.plugins/org.eclipse.core.runtime/.settings
  • delete this file: org.eclipse.wst.server.core.prefs
  • restart Eclipse

Now you should be able to create your WLS connection in eclipse. This issue/solution is valid for any application server connection in eclipse.

Tuesday, February 5, 2013

Tomcat(Servlet) JSE RMI application migration to Weblogic – leverage OEPE


1. Introduction

In this blog entry I'll go through the necessary steps of migrating an old fashion application from Tomcat/RMI Server to Weblogic. The original application was developed using Eclipse and contains an UI Servlet layer deployed on Tomcat and the business logic is a JSE application exposing the business logic via RMI. The Servlets are doing RMI calls against the exposed business methods.
I'll go through all the steps regarding the Eclipse -> OEPE migration and through migrating the Servlet/RMI server entirely to WLS by taking different approaches. There will be also some case studies regarding the approaches taken.
The current example project contains:
  • The UI layer = Servlets that are running on Tomcat.
    • TestServlet allow a user to add key/value entries in the session until Submit is pressed.
    • When submit is pressed the user is sent to the second servlet(DBUpdateConfirmationServlet) where the key/value pairs are taken from the session and are passed via RMI to the RMI server for updating a database.
  • RMI Server wraps with RMI the business logic. The business logic just contains methods for DB operations.
You can start with the attached eclipse project workspace. You will also need the SAMPLE schema project installed on a database that you have access to. You can find here also the migrated eclipse project workspace.

2. Migration Scenarios

2.1. Migrate the Servlet app from Tomcat to Weblogic
1. Create a Weblogic Server Connection in Eclipse OEPE
clip_image002[1]
You will create the connection from the local machine where OEPE is running to the Weblogic (Admin and Cluster) running on a different location or locally. You still need to have a Weblogic installation (not domain configuration) on your local machine where OEPE is running.
This should be your final result:
clip_image004[1]
You can see there both the AdminServer and the WLS Cluster.
Let’s try to redeploy our servlet app on the Weblogic Cluster:
clip_image006[1]
This is caused by the fact that the Eclipse Project JVM is 1.7 and the WLS JVM is 1.6. To Solve that go to Project Properties -> Project Facets and change from Java 1.7 to Java 1.6.
clip_image008[1]
Now you can deploy it and you’ll notice that the deployment will be done against the AdminServer, not against the cluster. We will deal with it later on.
Right-click on the Servlet app and choose -> Run As -> Run on Server
clip_image010[1]
Now you’ll see that there will be an error in the web page:
clip_image012[1]
This is because the new Context Root was not loaded by the Weblogic Server.
clip_image014[1]
The reason for that is the fact that in Tomcat the context root is specified in server.xml. This configuration file does not have a corresponded in Weblogic Server.
   1:  

   2: <Context docBase="MySimpleServlet" 

   3: path="/UpdateDatabaseTableEntries" reloadable="true" 

   4: source="org.eclipse.jst.jee.server:MySimpleServlet"/></Host> 

Now let’s specify the context root for weblogic server.
Right click on your WEB-INF folder and select New->Other:
clip_image016[1]
Then choose Oracle -> Weblogic -> Oracle Weblogic Web Module Descriptor:
clip_image018[1]
Then in the “Weblogic Web Module Deployment Descriptor” set the “Context Root” and the “Server Version”.
clip_image020[1]
Now run the application on the Weblogic Server. The application has successfully started:
clip_image022[1]
All the other application configurations, the ones specified as servlet annotations are automatically taken into consideration by Weblogic 12c as Weblogic 12c supports JEE6 Servlet 3.0 annotations.
If we try to run the application and submit an update then we will notice in the weblogic admin log the following error:
clip_image024[1]

There are 2 reasons for this error:


  • In the Servlet RMI client we are still using the localhost as the location for the RMI server when the location should be the IP of the location where the RMI server is running(our host system)

  • We should enable remote RMI clients

I’ve replaced the localhost with the host ip in the DbUpdateConfirmationServlet.java.
clip_image026[1]

I’ve opened the RMI ports on my firewall and the RMI remote client calls should be possible.
Now the application should work in the current status:

  • Servlet application deployed on the Weblogic Admin server running on my VBox vm
  • RMI Server running on the host machine.

Now let’s cluster our Servlet application.
First we need to enable session replication in our Servlet application.
Go to your application “Weblogic Web Module Deployment Descriptor” that is to be found under: /WebContent/WEB-INF/weblogic.xml and open the design view.
Go to Session ->Persistent Sore and choose from store type “Replicated if clustered”.
clip_image028[1]

The corresponding xml entry in weblogic.xml is:


   1: <wls:session-descriptor> 

   2: <wls:persistent-store-type>replicated_if_clustered</wls:persistent-store-type> 

   3: </wls:session-descriptor> 

Deploy your application to the WLS cluster:

  • Undeploy your application from the Admin Server.
  • Deploy it to the WLS cluster

Approach 1 (recommended): Use OEPE for WLS cluster deployment. In OEPE go to the Servers tab and right click on your Weblogic server connection. Choose Properties and then Weblogic->Publishing->Advanced. Move the AdminServer from right to left and your cluster from left to right. Now the default OEPE Weblogic deployment target will be your Weblogic Cluster.
clip_image030[1]

Now you can deploy your application directly from OEPE to the Weblogic Cluster.
Approach 2: Use WLS Admin Console for WLS cluster deployment. Using OEPE, deploy your application to Admin Server. Go to the Admin Console and then to Deployments and the choose “MySimpleServlet” application and navigate to the Targets tab. Uncheck AdminServer and check the lab cluster.
clip_image032[1]

Press Save.
Now the application will not be available anymore on this URL: http://adminserver-ip:adminserver-port/UpdateDatabaseTableEntries/. It will just be available on both of these URLs:
Now let’s test the Weblogic “Session Replication” feature:
A. Let’s open a connection against one of the managed servers: http://ms2-ip:ms2-port/UpdateDatabaseTableEntries/
B. Let’s add 3 updates requests in the session. After you have added 3 entries, you application should look like bellow, with you 3 entries being displayed.
clip_image034[1]

C. Now, in the same browser change the URL to the other managed server and add a new entry. You should see that the new entry has been added to a list that contains the entries added on the application deployed on the other managed server.
clip_image036[1]

This will happen also if one of the servers will go down – your application will be highly available as the session will be replicated to a different location in the WLS cluster. In a production environment you will not switch the listening ports and addresses manually in the URLs. In front of the WLS cluster you will have a load balancer that will do automatically load balancing and failover for your application. On Exalogic that load balancer will be called Oracle Traffic Director.
2.2. Migrate the RMI Server to Weblogic

Go to MySimpleRMIServer project and then to the RMIServer.java class. Add the following method:


   1: public static void runServer() throws RemoteException,

   2:             MalformedURLException

   3:     {

   4:         init();

   5:         LocateRegistry.createRegistry(1099);

   6:         DatabaseFacade dbFacade = new DatabaseFacadeImpl();

   7:         Naming.rebind("server.dbFacade", dbFacade);

   8:         System.out.println("server.RMI Server is ready.");

   9:     }

Then right-click on MySimpleServlet project and go to Properties -> Java Build Path and add the MySimpleRMIServer project to Projects tab:
clip_image038[1]
Then add the following method to your TestServlet.java:


   1: @Override

   2:     public void init(ServletConfig config) throws ServletException

   3:     {

   4:         super.init(config);

   5:         try

   6:         {

   7:             RMIServer.runServer();

   8:         }

   9:         catch (RemoteException e)

  10:         {

  11:             // TODO Auto-generated catch block

  12:             e.printStackTrace();

  13:         }

  14:         catch (MalformedURLException e)

  15:         {

  16:             // TODO Auto-generated catch block

  17:             e.printStackTrace();

  18:         }

  19:     }

Set the loadOnStartup priority to 2 for the update confirmation Servlet:


   1: @WebServlet(name = "DbUpdateConfirmationServlet", displayName = "Confirm Update Servlet", urlPatterns = { "/ConfirmUpdate" }, loadOnStartup = 2)

Create a new Project -> Java EE -> Enterprise Application Project and name it “MyServletRMIEnterpriseProject”.
clip_image040[1]
Press Next and include both of the projects (MySimpleRMIServer and MySimpleServlet) as modules to this JEE Enterprise project.
clip_image042[1]
Press Finish.
You will notice that the generated project contains 1 bounded library – MySimpleRMIServer.jar and 1 module(web) – MySimpleServlet.war.
clip_image044[1]
Right-click on the MyServletRMIEnterpriseProject and choose New -> Weblogic Deployment Plan.
clip_image046[1]
Press Next.
Name your deployment plan: MyDeploymentPlan.xml
clip_image048[1]
Press Next. Target your Enterprise application:
clip_image050[1]
Press Finish.
From the Weblogic Deployment Plan design view go to Modules ->MysimpleServlet.war -> weblogic-web-app and delete the 2XPath entries.
clip_image052[1]
Save.
Now run your Enterprise Application on WLS Cluster. Go to your servers tab inside OEPE and right click on your Weblogic connection and choose Publish and then publish your enterprise application and press Finish.
clip_image054[1]
Now you should see your Enterprise project deployed to your cluster:
clip_image056[1]
My WLS cluster contains 2 Managed Servers that are running on the same physical server. I’ve deployed my RMI Server to 2 WLS Managed Servers running on the same machine and now you should see one exception in one of the 2 WLS Managed Servers log saying that the RMI port 1099 is already in use.
In my case, on my Managed Server 1 MS_1 log I see the following exception:


   1: Connecting to the database... 

   2: java.rmi.server.ExportException: Port already in use: 1099; nested exception is: 

   3: java.net.BindException: Address already in use 

   4: at sun.rmi.transport.tcp.TCPTransport.listen(TCPTransport.java:310) 


Off course that having my Managed Servers running on different physical machines will only solve this issue. Routing, load balancing and failing over Servlet RMI calls is still unaddressed. In the next chapters we will address this. For the moment just access the servlet on one of the 2 managed servers and check if the updates are successfully performed – they should be:
· http://ms1-ip:ms1-port/UpdateDatabaseTableEntries/
· http://ms2-ip:ms2-port/UpdateDatabaseTableEntries/


2.3. Call the RMI exposed methods directly, without using RMI

Inside the Servlet init method, just call initialize the DB connection by using the init() RMIServer method. Do not create a RMI server anymore.


   1: @Override

   2:     public void init(ServletConfig config) throws ServletException

   3:     {

   4:         super.init(config);

   5:         RMIServer.init();

   6:         /*

   7:          * try { //RMIServer.runServer(); } In your

   8:          * DbUpdateConfirmationServlet.java do not use anymore RMI to call your

   9:          * update method. Just call it directly. //DatabaseFacade dbFacade =

  10:          * (DatabaseFacade) registry //.lookup("server.dbFacade");

  11:          * DatabaseFacadeImpl dbFacadeImpl=new DatabaseFacadeImpl(); …

  12:          */

  13:     ...    

  14:     }

  15: ...

  16: dbFacadeImpl.updateCustomerName(Integer.parseInt(idString), newName);

Re-publish the EAR application to the WLS cluster. You should not see the error anymore.


   1: Connecting to the database... 

   2: java.rmi.server.ExportException: Port already in use: 1099; nested exception is: 

   3: java.net.BindException: Address already in use 

   4: at sun.rmi.transport.tcp.TCPTransport.listen(TCPTransport.java:310) 

Now you can use a load balancer to load your http calls against your servlets deployed in either of the 2 WLS Managed Servers. Then the ex-RMI calls(currently just method calls) are done against the logic deployed on the same Managed Server.
The issues in this approach are:


  • You cannot target different containers, different size containers for your Servlet engine and you Enterprise Search engine. There can be the situation where you need less resources for the Servlet Engine(just 1 cluster with 2 managed servers) then for your Business Logic(1 cluster with 10 Managed Servers). Both clusters can be under the same domain.

  • You might want to apply different performance and tuning settings for your Business Logic Calls.

  • You might also want an automatic load-balancer and failover implemented and managed by WLS Cluster itself for the Servlet – Business Logic calls.

The answer to the issues above is that instead of using RMI for wrapping the Enterprise Search Engine, we can use EJB for this purpose. We will show that in the next chapter.
2.4. Wrap your application business logic using EJB instead of RMI

In OEPE create a new EJB project called MySimpleEJBWrapper.
clip_image058[1]
Add the MySimpleRMIServer as project reference to MySimpleEJBWrapper.
clip_image060[1]
Create a new SessionBean to expose you business logic with the following name and content:


   1: package oracle.test.ejbs;

   2:  

   3: import java.rmi.RemoteException;

   4: import javax.ejb.LocalBean;

   5: import javax.ejb.Stateless;

   6: import oracle.test.connections.DatabaseConnection;

   7: import oracle.test.impl.DatabaseFacadeImpl;

   8:  

   9: /**

  10:  * 

  11:  * Session Bean implementation class MyEJBWrapper

  12:  */

  13:  

  14: @Stateless(mappedName = "MyEJBWrapper")

  15: @LocalBean

  16: public class MyEJBWrapper

  17: {

  18:     DatabaseConnection databaseConnection;

  19:  

  20:     /**

  21:      * 

  22:      * Default constructor.

  23:      * 

  24:      * 

  25:      * 

  26:      * @throws RemoteException

  27:      */

  28:     public MyEJBWrapper() throws RemoteException

  29:  

  30:     {

  31:         super();

  32:         databaseConnection = new DatabaseConnection();

  33:         databaseConnection.initCreateAndGetDbConnection();

  34:     }

  35:  

  36:     public String getUpdatedCustomer(int id) throws RemoteException, Exception

  37:     {

  38:         return databaseConnection.getUpdateResult(id);

  39:     }

  40:  

  41:     public void updateCustomerName(int id, String name) throws Exception

  42:     {

  43:         databaseConnection.updateCustomerName(id, name);

  44:     }

  45: }

Go to MySimpleServlet project and add the MySimpleEJBWrapper project to java build path project dependencies and remove MySimpleRMIServer Project.
clip_image062[1]
Inject the EJB in my DBUpdateConfirmation.java servlet as:
@EJB MyEJBWrapper myEjBWrapperBean;
And call the update method directly from the EJB: myEjBWrapperBean.updateCustomerName(Integer.parseInt(idString), newName);
Republish your application to the WLS cluster:
clip_image064[1]
This is how your deployment should look in WLS admin console:
clip_image066[1]
Test your application.
2.5. Instead of creating the DB connection in your code, create a datasource on the WLS server and use that datasource for DB operations

Create a new datasource in WLS and deploy it to the WLS cluster. The jndi name should be jdbc/sample. Some db connection example:

  • DB name: XE
  • Hostname: localhost
  • Port: 1521
  • DB User name: sample
  • PWD= sample

Create a method in your DatabaseConnection.java class, RMIServer project to get this datasource via jndi name:


   1: public Connection setJndiDbConnection(String jndiName)

   2:     {

   3:         java.sql.Connection connection = null;

   4:  

   5:         try

   6:         {

   7:             javax.naming.Context initialContext = new javax.naming.InitialContext();

   8:             javax.sql.DataSource dataSource = (javax.sql.DataSource) initialContext

   9:                     .lookup(jndiName);

  10:             //"java:comp/env/jdbc/hrconnDS"

  11:             connection = dataSource.getConnection();

  12:             return connection;

  13:         }

  14:         catch (Exception e)

  15:         {

  16:             e.printStackTrace();

  17:             // or handle more gracefully

  18:         }

  19:         return null;

  20:     }

Use this new connection for DB statements.


   1: public void updateCustomerName(int id, String name) throws Exception

   2:     {

   3:         //Connection connection = MY_DB_CONNECTION;

   4:         Connection connection = setJndiDbConnection("jdbc/sample");

   5:  

   6:         Statement statement = connection.createStatement();

   7:         statement.executeUpdate("update sample.customer set customer.name='"

   8:                 + name + "' where customer.customer_id=" + id);

   9:         statement.close();

  10:         connection.close();

  11:     }

This new approach will allow you to better tune, manage, administer and monitor your DataSource by using the tools that WLS provides.
 

3. Monitoring the application with JRockit Mission Control and JRockit Flight Recorder


This chapter is just meant to give you an idea about the value that JRMC monitoring can bring to you. In the next rows I’ll highlight some of the most important features in the context of the example application that I’ve used in the first chapters.
Just a few monitoring examples:


  • Servlet monitoring:

clip_image068[1]


  • EJB monitoring:

clip_image070[1]


  • JDBC monitoring – TO BE CONTINUED