Thursday, 24 December 2009

Fast Way to Create a Web Service from an EJB3 Entity

Normally I would create an EJB session bean to expose my Entity queries from my Entity beans, but I thought it would be easier to just create a Java Service Facade and expose that as a web service as shown below.

1. In my project create an "Entity from table" using the new object gallery item in the EJB node. In this example we use the classic DEPT table.
2. Then edit your Dept entity to create another named query as shown below, as well as a toString method to display the bean.

....

@Entity
@NamedQueries({
@NamedQuery(name = "Dept.findAll", query = "select o from Dept o"),
@NamedQuery(name = "Dept.findByDeptno", query = "select o from Dept o where o.deptno = :deptno")
})
public class Dept
implements Serializable

...

@Override
public String toString()
{
return "Dept [" + deptno + ", " + dname + ", " + loc + "]";
}

3. From the EJB new object gallery select "Java Service Facade", in the wizard I only exposed these methods as well as a main method to test it with.
  • public List getDeptFindAll() public
  • public List getDeptFindByDeptno(Long deptno)
4. Add code to the main as follows to ensure the Java Service Facade works.

public static void main(String [] args)
{
final JavaServiceFacade javaServiceFacade = new JavaServiceFacade();
// TODO: Call methods on javaServiceFacade here...
List<Dept> deps = javaServiceFacade.getDeptFindAll();
for (Dept d: deps)
{
System.out.println(d);
}
}

5. Run it to verify it works well. Inside the persistence.xml I edited the following property (eclipselink.logging.level=INFO) to reduce the amount of output we get at runtime.

<persistence-unit name="Model-Test" transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<class>model.Dept</class>
<properties>
<property name="eclipselink.jdbc.driver"
value="oracle.jdbc.OracleDriver"/>
<property name="eclipselink.jdbc.url"
value="jdbc:oracle:thin:@//beast.au.oracle.com:1523/linux11gr2"/>
<property name="eclipselink.jdbc.user" value="scott"/>
<property name="eclipselink.jdbc.password"
value="3E20F8982C53F4ABA825E30206EC8ADE"/>
<property name="eclipselink.logging.level" value="INFO"/>
<property name="eclipselink.target-server" value="WebLogic_10"/>
</properties>
</persistence-unit>

Output:

... [EL Warning]: 2009-12-24 11:48:40.203--Failed to get InitialContext for MBean registration: javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file: java.naming.factory.initial
Dept [10, ACCOUNTING, NEW YORK]

Dept [20, RESEARCH, DALLAS]
Dept [30, SALES, CHICAGO]

Dept [40, OPERATIONS, BOSTON]

6. Now finally create a web service from the "JavaServiceFacade.java". To do this I simply invoked the "Create Java Web Service" from the object gallery or even easier use it's context menu option "Create Web Service".

Now you can test it using the "Test Web Service Wizard" option from the web service itself as now it is a Web Service as per step #6.

Friday, 18 December 2009

Starting A Coherence Cache Server from ANT

Started setting up some coherence demos through ant, in doing so created a small template to work from which enables me to start a coherence cache server. With this you simply place your source code within the SRC directory and it will compile it, package it (once we add a package task), and run the cache server.

1. Firstly create a directory as follows , adding the files (build.properties, build.xml) and 2 directories (src, lib) as shown below.

Directory Name - start-cache-server

build.properties
build.xml
classes - DIRECTORY
lib - DIRECTORY
src - DIRECTORY

2. Ensure you have ant in your path.

D:\jdev\ant-demos\coherence\start-cache-server>ant -version
Apache Ant version 1.7.0 compiled on December 13 2006

3. Edit build.properties ensuring we set coherence home correctly

# oracle.coherence.home
#
oracle.coherence.home=D:/jdev/coherence/352/coherence

# jvmargs
#
# JVM args to pass into the command at runtime to set heap size etc

jvmargs=-server -showversion -Xms512m -Xmx512m

4. Edit build.xml to look as follows

<?xml version="1.0" encoding="windows-1252" ?>

<project default="run-default" name="demo" basedir=".">

<property file="build.properties"/>

<path id="j2ee.classpath">
<pathelement path="${oracle.coherence.home}/lib/coherence.jar"/>
</path>

<property name="src.dir" value="src"/>
<property name="classes.dir" value="classes"/>
<property name="lib.dir" value="lib"/>
<property name="class.name" value="com.tangosol.net.DefaultCacheServer"/>
<property name="jmxclass.name" value="com.tangosol.net.management.MBeanConnector"/>

<target name="init">
<tstamp/>
<mkdir dir="${classes.dir}"/>
</target>

<target name="clean" description="Clean lib, classes directories">
<delete dir="${classes.dir}"/>
</target>

<target name="compile" description="Compiles classes into ${classes.dir}" depends="init">
<javac srcdir="${src.dir}"
debug="true"
destdir="${classes.dir}"
includes="**/*.java" >
<classpath refid="j2ee.classpath"/>
</javac>
</target>

<target name="run-default" depends="compile" description="Run the cache server">
<echo message="Starting cache server with jvm args : ${jvmargs}"/>
<java classname="${class.name}" fork="true">
<!--
Add system properties as follows
<sysproperty key="tangosol.pof.enabled" value="true"/>
-->

<jvmarg line="${jvmargs}"/>
<classpath>
<path refid="j2ee.classpath"/>
</classpath>
</java>
</target>

<target name="run-jmx" depends="compile" description="Run the JMX enabled cache server">
<echo message="Starting JMX enabled cache server with jvm args : ${jvmargs}"/>
<java classname="${jmxclass.name}" fork="true">
<sysproperty key="tangosol.coherence.management" value="all"/>
<sysproperty key="tangosol.coherence.management.remote" value="true"/>
<sysproperty key="com.sun.management.jmxremote" value="true"/>
<jvmarg line="${jvmargs}"/>
<arg line="-rmi" />
<classpath>
<path refid="j2ee.classpath"/>
</classpath>
</java>
</target>

</project>
5. Run cache server using the ant task shown below.

D:\jdev\ant-demos\coherence\start-cache-server>ant run-default
Buildfile: build.xml

init:
[mkdir] Created dir: D:\jdev\ant-demos\coherence\start-cache-server\classes

compile:

run-default:
[echo] Starting cache server with jvm args : -server -showversion -Xms512m -Xmx512m
[java] java version "1.6.0_07"
[java] Java(TM) SE Runtime Environment (build 1.6.0_07-b06)
[java] Java HotSpot(TM) Server VM (build 10.0-b23, mixed mode)
[java] 2009-12-18 10:15:15.062/0.406 Oracle Coherence 3.5.2/463 (thread=main, member=n/a): Loaded operational configur
ation from resource "jar:file:/D:/jdev/coherence/352/coherence/lib/coherence.jar!/tangosol-coherence.xml"
[java] 2009-12-18 10:15:15.078/0.422 Oracle Coherence 3.5.2/463 (thread=main, member=n/a): Loaded operational override
s from resource "jar:file:/D:/jdev/coherence/352/coherence/lib/coherence.jar!/tangosol-coherence-override-dev.xml"
[java] 2009-12-18 10:15:15.078/0.422 Oracle Coherence 3.5.2/463 (thread=main, member=n/a): Optional configuration overri
de "/tangosol-coherence-override.xml" is not specified
[java] 2009-12-18 10:15:15.093/0.437 Oracle Coherence 3.5.2/463 (thread=main, member=n/a): Optional configuration overri
de "/custom-mbeans.xml" is not specified
[java]
[java] Oracle Coherence Version 3.5.2/463
[java] Grid Edition: Development mode
[java] Copyright (c) 2000, 2009, Oracle and/or its affiliates. All rights reserved.
[java]
[java] 2009-12-18 10:15:15.531/0.875 Oracle Coherence GE 3.5.2/463 (thread=main, member=n/a): Loaded cache configurati
on from "jar:file:/D:/jdev/coherence/352/coherence/lib/coherence.jar!/coherence-cache-config.xml"
[java] 2009-12-18 10:15:16.265/1.609 Oracle Coherence GE 3.5.2/463 (thread=Cluster, member=n/a): Service Cluster joined
the cluster with senior service member n/a
[java] 2009-12-18 10:15:19.515/4.859 Oracle Coherence GE 3.5.2/463 (thread=Cluster, member=n/a): Created a new cluster
"cluster:0xD3FB" with Member(Id=1, Timestamp=2009-12-18 10:15:16.031, Address=10.187.80.135:8088, MachineId=57735, Location=site:
au.oracle.com,machine:papicell-au,process:3708, Role=CoherenceServer, Edition=Grid Edition, Mode=Development, CpuCount=2, SocketCo
unt=1) UID=0x0ABB5087000001259EEC7BBFE1871F98
[java] 2009-12-18 10:15:19.546/4.890 Oracle Coherence GE 3.5.2/463 (thread=Invocation:Management, member=1): Service Man
agement joined the cluster with senior service member 1
[java] 2009-12-18 10:15:19.875/5.219 Oracle Coherence GE 3.5.2/463 (thread=DistributedCache, member=1): Service Distribu
tedCache joined the cluster with senior service member 1
[java] 2009-12-18 10:15:19.953/5.297 Oracle Coherence GE 3.5.2/463 (thread=ReplicatedCache, member=1): Service Replicate
dCache joined the cluster with senior service member 1
[java] 2009-12-18 10:15:19.953/5.297 Oracle Coherence GE 3.5.2/463 (thread=OptimisticCache, member=1): Service Optimisti
cCache joined the cluster with senior service member 1
[java] 2009-12-18 10:15:19.968/5.312 Oracle Coherence GE 3.5.2/463 (thread=Invocation:InvocationService, member=1): Serv
ice InvocationService joined the cluster with senior service member 1
[java] 2009-12-18 10:15:19.968/5.312 Oracle Coherence GE 3.5.2/463 (thread=main, member=1): Started DefaultCacheServer
...
[java]
[java] SafeCluster: Name=cluster:0xD3FB
[java]
[java] Group{Address=224.3.5.2, Port=35463, TTL=4}
[java]
[java] MasterMemberSet
[java] (
[java] ThisMember=Member(Id=1, Timestamp=2009-12-18 10:15:16.031, Address=10.187.80.135:8088, MachineId=57735, Location=sit
e:au.oracle.com,machine:papicell-au,process:3708, Role=CoherenceServer)
[java] OldestMember=Member(Id=1, Timestamp=2009-12-18 10:15:16.031, Address=10.187.80.135:8088, MachineId=57735, Location=s
ite:au.oracle.com,machine:papicell-au,process:3708, Role=CoherenceServer)
[java] ActualMemberSet=MemberSet(Size=1, BitSetCount=2
[java] Member(Id=1, Timestamp=2009-12-18 10:15:16.031, Address=10.187.80.135:8088, MachineId=57735, Location=site:au.orac
le.com,machine:papicell-au,process:3708, Role=CoherenceServer)
[java] )
[java] RecycleMillis=120000
[java] RecycleSet=MemberSet(Size=0, BitSetCount=0
[java] )
[java] )
[java]
[java] Services
[java] (
[java] TcpRing{TcpSocketAccepter{State=STATE_OPEN, ServerSocket=10.187.80.135:8088}, Connections=[]}
[java] ClusterService{Name=Cluster, State=(SERVICE_STARTED, STATE_JOINED), Id=0, Version=3.5, OldestMemberId=1}
[java] InvocationService{Name=Management, State=(SERVICE_STARTED), Id=1, Version=3.1, OldestMemberId=1}
[java] DistributedCache{Name=DistributedCache, State=(SERVICE_STARTED), LocalStorage=enabled, PartitionCount=257, BackupCou
nt=1, AssignedPartitions=257, BackupPartitions=0}
[java] ReplicatedCache{Name=ReplicatedCache, State=(SERVICE_STARTED), Id=3, Version=3.0, OldestMemberId=1}
[java] Optimistic{Name=OptimisticCache, State=(SERVICE_STARTED), Id=4, Version=3.0, OldestMemberId=1}
[java] InvocationService{Name=InvocationService, State=(SERVICE_STARTED), Id=5, Version=3.1, OldestMemberId=1}
[java] )
[java]

Few things to note here.

- We don't have anything in the SRC directory we simply add code we wish to use in our cache server here, like cahe store implementations etc.

- When you do have SRC to compile you will need to add a package task as shown below for example.

<target name="package"
depends="compile"
description="Package application into ${ant.project.name}.jar">
<jar basedir="${classes.dir}" destfile="${lib.dir}/${ant.project.name}.jar">
<include name="**/*.class"/>
</jar>
</target>

From the build.xml there is also a target to start a JMX enabled node using "ant run-jmx"

Wednesday, 9 December 2009

PLSQL commit every X records and Coherence putAll every X records

Note for self:

Was using this in Write-Behind Caching Demo with Oracle Coherence using PLSQL Bulk Binds.

When using PLSQL to bulk insert code as follows to control the commit time.

-- control number of records to insert before calling COMMIT
NUM_OF_RECORDS_TO_INSERT constant number := 10000;

IF (mod(l_count, NUM_OF_RECORDS_TO_INSERT) = 0) THEN
FORALL i IN mid.FIRST..mid.LAST
insert into messages (message_id, message_type, message)
values (mid(i), mt(i), m(i));
END IF;

When loading many cache records ensure we only call putAll to control the amount of records to insert into the cache in one hit.
final private static int BATCH_SIZE = 1000;

Map buffer = new HashMap();

long start = System.currentTimeMillis();

for (int i = 1; i <= records; i++)
{
Message message = new Message
(new BigDecimal(i),
"M",
String.format("Message %s from test client", i));
buffer.put(String.valueOf(i), message);

if ((i % BATCH_SIZE) == 0)
{
messageCache.putAll(buffer);
buffer.clear();
}
}

if (!buffer.isEmpty())
{
messageCache.putAll(buffer);
buffer.clear();
}

Friday, 4 December 2009

Having SQL*Plus run within Jdeveloper's Log window

Invoking SQL*Plus is what I do a lot from JDeveloper, so there are 2 things I setup everytime I do a fresh install of JDeveloper.

1. Use external tools to avoid having to enter password as per this blog entry a while ago.

http://theblasfrompas.blogspot.com/2007/10/avoiding-having-to-enter-password-when.html

2. Secondly I now only use sqlplus.exe rather then sqlplusw.exe to ensure that it never leaves JDeveloper itself and so the output is redirected to JDeveloper's log window. Of course you have to then add "exit" to your scripts so that the process itself doesn't hang around.

Also it's worth making sure you start from the directory of the SQL file your invoking if you wish to include other files as part of the SQL script itself which don't reference a path themselves.

Eg:

Program Executable: D:\oracle\product\10.2.0\db_1\BIN\sqlplus.exe
Arguments: scott/tiger@(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=beast.au.oracle.com)(PORT=1521)))(CONNECT_DATA=(SERVICE_NAME=linux11g))) @${file.path}
Run Directory: ${file.dir}

Demo output as follows showing how I invoke SQL*Plus and what we pass into it to avoid opening up a new window for SQL*Plus.

Thursday, 19 November 2009

Accessing the Oracle Universal Connection Pool MBean using JConsole

Now I am just tranistioning to the Oracle Universal Connection Pool I found that it has a useful MBean known as "UniversalConnectionPoolMBean" which you can view/manipulate with "jconsole" using JDK 1.6. Here is a screen shot of jconsole attached to the JVM which is has a Universal Connection Pool running within it. Once attached to the JVM access it as follows.

1. Click on the MBean tab
2. Click the + symbol for "oracle.ucp.admin.UniversalConnectionPoolMBean"
3. Click on the "Attributes" or "Methods" node and you can view/update the pool using that MBean

The javadoc for the MBean this can be found here.

http://download.oracle.com/docs/cd/B28359_01/java.111/e11990/oracle/ucp/admin/UniversalConnectionPoolManagerMBean.html

In the example below I was using Oracle's UCP within a coherence cache server for write behind to an Oracle database.

Thursday, 5 November 2009

Oracle Coherence - read-write-backing-map-scheme

I spent the last 2 weeks in Boston working with the oracle coherence team and how that product works and I am impressed with it. One thing which I was keen on testing out / learning in depth was the read-write-backing-map-scheme. I specifically wanted to learn write-behind which when enabled the cache will delay writes to the back end cache store, which in my example would be an Oracle 11g database. To me there is really only 2 options for this to be as quick as possible and of course use connection pooling which UCP (Oracle Universal Connection Pool) is perfect for.

1. JDBC Batching
2. PLSQL bulk binds

Whats important though is that we only commit after X amount of records, and only go to the database when we are ready to insert those X amount of records in a single round trip. To me PLSQL bulk binds make sense here, as all it takes is to convert those cache entries into an SQL object which the database can interpret from PLSQL. Once that's done your PLSQL is as simple as this really.


FORALL i IN mid.FIRST..mid.LAST
insert into messages (message_id, message_type, message)
values (mid(i), mt(i), m(i));

COMMIT;

I will post a full example on this shortly which also shows how to read the data back into the cache.

More about this can be found here on what I want to setup. My initial testing showed 1,000,000 records inserted without too much issues BUT there are a couple of things to be aware from coherence and oracle itself.

http://coherence.oracle.com/display/COH35UG/Read-Through%2C+Write-Through%2C+Write-Behind+and+Refresh-Ahead+Caching

Thursday, 8 October 2009

Quick unix command to determine JDBC driver version

Thought this was alot easier then extracting the actual JDBC JAR file and viewing META-INF/MANIFEST.MF. Of course you can still use the JDBC API via DatabaseMetaData, but normally you don't need to go to that effort.

UNIX

> unzip -p ojdbc14.jar META-INF/MANIFEST.MF | grep -C 1 version

WINDOWS

> unzip -p ojdbc14.jar META-INF/MANIFEST.MF

Note: If you have grep.exe for windows you could use this.

> unzip -p ojdbc14.jar META-INF/MANIFEST.MF | grep -C version

Output (Unix demo)
------------------------

[oracle@beast lib]$ unzip -p ojdbc14.jar META-INF/MANIFEST.MF | grep -C 1 version
Manifest-Version: 1.0
Implementation-Version: "Oracle JDBC Driver version - 10.1.0.5.0"
Specification-Title: "Oracle JDBC driver classes for use with JDK1.4"
Specification-Version: "Oracle JDBC Driver version - 10.1.0.5.0"
Implementation-Title: "ojdbc14.jar"

If your using 11g JDBC driver then you can do it as follows.

http://theblasfrompas.blogspot.com/2007/09/fast-way-to-determine-exact-11g-jdbc.html

Thursday, 24 September 2009

Trace/Diagnostics output from ADF BC Web Services using FMC (EM) in OFM 11g R1

When you deploy your ADF BC Application module as a Web Service interface you can take advantage of Fusion Middleware Contol (EM) to trace the web service execution from FMC (EM) itself as I will show here.

Note: This is only applicable to ADF BC Web Services, the same steps won't work for JAX-WS or PLSQL web services created in JDeveloper 11g R1.

The documentation for Service-Enabled application modules can be found here.

Oracle® Fusion Middleware Fusion Developer's Guide for Oracle Application Development Framework
11g Release 1 (11.1.1)

Part Number B31974-03
11 Integrating Service-Enabled Application Modules
http://download.oracle.com/docs/cd/E12839_01/web.1111/b31974/bcextservices.htm#CJAJGIEB

In order to do this we need to achieve 3 steps here.

1. Setup Fusion Middleware Control (EM) in your domain

In short your domain will need to be setup as per these steps.

http://theblasfrompas.blogspot.com/2009/07/installing-adf-runtime-on-oracle-fusion.html

2. Deploy an ADF BC App Module as a Web Service Interface

Note: It is assumed you have a client method exposed in your ADF BC application module. An example of such a method is as follows. You will need to ensure the method is exposed as a client method.


public String getVersion ()
{
return getSession().getVersion();
}

2.1. Right click on your application module XML file and and select "Open {app module name}"
2.2. Select "Service Interface"
2.3. Select the + symbol
2.4. Enter in the service interface details.
2.5. Click next
2.6. Shuttle across the methods you wish to expose.
2.7. Ignore the "Service View Instances" and click next
2.8 Click Finish.

You end up with something as follows in the application navigator.





















2.9. Now we need to create a deployment profile which we do by double clicking on the proejct to invoke the "Project properties" dialog.
2.10. Select "deployment"
2.11. Click New
2.12. Select the archive type as "Business Components service Interface"

2.13. Give it a name and press Ok

At this point you have created an EJB JAR file , which you can deploy by using the menu item for the workspace "Deploy" and targeting an Application Server Connection for your OFM 11g R1 server. Once deployed you should end up with output as follows.

[10:38:37 AM] ---- Deployment started. ----
[10:38:37 AM] Target platform is (Weblogic 10.3).
[10:38:44 AM] Entering Target Selection Dialog
[10:38:48 AM] Retrieving existing application information
[10:38:48 AM] Running dependency analysis...
[10:38:48 AM] Building...
[10:38:49 AM] Deploying 3 profiles...
[10:38:49 AM] Wrote EJB Module to D:\jdev11gr1\jdeveloper\jdev\mywork\ADFBC-WS\Demo\deploy\ADFBC-WS-Demo-context-root.jar
[10:38:50 AM] Wrote Archive Module to D:\jdev11gr1\jdeveloper\jdev\mywork\ADFBC-WS\Demo\deploy\adfbc-ws_Common.jar
[10:38:50 AM] Wrote Enterprise Application Module to D:\jdev11gr1\jdeveloper\jdev\mywork\ADFBC-WS\deploy\Demo_adfbc-ws.ear
[10:38:52 AM] INFO: Unable to load annotation weblogic.javaee.CallByReferencefor parsing. The annotation is ignored.
[10:38:52 AM] INFO: Unable to load annotation weblogic.javaee.CallByReferencefor parsing. The annotation is ignored.
[10:38:52 AM] INFO: GenericWSWarAnnotationListener.parseAnnotatedClass Adding Servlet Mapping with URL pattern /AppModuleService for annotated WebService class pas.au.adf.ws.server.serviceinterface.AppModuleServiceImpl
[10:38:54 AM] Deploying Application...
[10:38:59 AM] [Deployer:149191]Operation 'deploy' on application 'Demo_adfbc-ws' is initializing on 'debug_ws'
[10:39:16 AM] [Deployer:149192]Operation 'deploy' on application 'Demo_adfbc-ws' is in progress on 'debug_ws'
[10:39:21 AM] [Deployer:149194]Operation 'deploy' on application 'Demo_adfbc-ws' has succeeded on 'debug_ws'
[10:39:21 AM] Application Deployed Successfully.
[10:39:21 AM] Elapsed time for deployment: 43 seconds
[10:39:21 AM] ---- Deployment finished. ----


3. Use FMC (EM) to trace the ADF BC web service execution.


3.1 Log into FMC (EM) as follows

http://{server}:{port}/em

3.2 In the navigator pane, expand WebLogic Domain
3.3. Expand the domain
3.4. Select the desired server from the list.
3.5. From the WebLogic Sever menu, select Logs > Log Configuration
3.6. On the "Log Levels" tab you need to select "Loggers with persistent Log Level State", then expand the "Specify Loggers"
3.7. At the bottom and enter the logger name "oracle.webservices" and optionally setup the "
Diagnostic Logging Level" you wish to use.
3.8. Press Apply.

Now at this point we have to restart the server.

Once re-started log back into EM and verify the Log configuration shows "oracle.webservices" as shown below.














Now we can test our web services as shown in this entry and verify we get web services diagnostics logging placed into the log file "debug_ws-diagnostic.log" which would be in a directory as follows $DOMAIN_HOME/servers/{managed-server-name}/logs

http://theblasfrompas.blogspot.com/2009/09/web-services-security-in-ofm-11g-r1.html

An example of the output is as follows


<anonymous>
] [ecid: 0000IFdFy2wFw000jzwkno1Aidcd00003S,0:3] [WEBSERVICE_PORT.name:
AppModuleServiceSoapHttpPort] [APP: Demo_adfbc-ws] [J2EE_MODULE.name:
ADFBC-WS-Demo-context-root] [WEBSERVICE.name: AppModuleService]
[J2EE_APP.name: Demo_adfbc-ws] Incomplete connection information
[2009-09-24T09:32:46.827+10:00] [debug_ws] [WARNING] []
[oracle.adf.share.jndi.ReferenceStoreHelper] [tid: [ACTIVE].ExecuteThread:
'2' for queue: 'weblogic.kernel.Default (self-tuning)'] [userId:
<anonymous>
] [ecid: 0000IFdFy2wFw000jzwkno1Aidcd00003S,0:3] [WEBSERVICE_PORT.name:
AppModuleServiceSoapHttpPort] [APP: Demo_adfbc-ws] [J2EE_MODULE.name:
ADFBC-WS-Demo-context-root] [WEBSERVICE.name: AppModuleService]
[J2EE_APP.name: Demo_adfbc-ws] Incomplete connection reference object
[2009-09-24T09:32:50.828+10:00] [debug_ws] [TRACE] [OWS-04010]
[oracle.webservices.service] [tid: [ACTIVE].ExecuteThread: '2' for queue:
'weblogic.kernel.Default (self-tuning)'] [userId:
<anonymous>
] [ecid: 0000IFdFy2wFw000jzwkno1Aidcd00003S,0:3] [SRC_CLASS:
oracle.j2ee.ws.server.ServerMessages] [APP: Demo_adfbc-ws] [SRC_METHOD:
fineMsgServletResponse] [arg:
{/pas/au/adf/ws/common/}AppModuleServiceSoapHttpPort] [arg:
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
<env:Header/>
<env:Body>
<ns0:getVersionResponse xmlns:ns0="/pas/au/adf/ws/common/types/">
<result xmlns="/pas/au/adf/ws/common/types/">11.1.1.54.7</result>
</ns0:getVersionResponse>
</env:Body>
</env:Envelope>
] The SOAP response for port:
{/pas/au/adf/ws/common/}AppModuleServiceSoapHttpPort is:[[

<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
<env:Header/>
<env:Body>
<ns0:getVersionResponse xmlns:ns0="/pas/au/adf/ws/common/types/">
<result xmlns="/pas/au/adf/ws/common/types/">11.1.1.54.7</result>
</ns0:getVersionResponse>
</env:Body>
</env:Envelope>
]]
</anonymous>
</anonymous>
</anonymous>

You can also view the log file from FMC (EM) as follows
:

- From the WebLogic Sever menu, select Logs > View Log Messages
- Click on "Target Log Files" button.
- In the log files table select the row containing "debug_ws-diagnostic.log" and press the button "View Log File".

More Information

Oracle® Fusion Middleware Security and Administrator's Guide for Web Services
11g Release 1 (11.1.1)
Part Number B32511-01
15 Diagnosing Problems
http://download.oracle.com/docs/cd/E12839_01/web.1111/b32511/diagnosing.htm#WSSEC1226

Monday, 14 September 2009

Web Services Security in OFM 11g R1

I ran 2 good blog entries for securing web services from JDeveloper 11g onto WLS 11g R1. Both these are great starting points for that and worked well. Saves a lot of time when it's all laid out step by step.

http://one-size-doesnt-fit-all.blogspot.com/2009/08/one-way-ssl-with-jax-ws-using.html

http://kingsfleet.blogspot.com/2009/01/security-policy-worked-example.html

I always create my WLS domains adding Fusion Middleware Control and that then gives you the ability to test the web service from a browser as well as view some runtime statistics for the web service itself when logging into the "/em" application installed into the admin server.

The blog entry showing how to install Fusion Middleware Control into a WLS 11g R1 domain is as follows. I even started deploying from that application rather then using the traditional console application.

http://theblasfrompas.blogspot.com/2009/07/installing-adf-runtime-on-oracle-fusion.html

So in short

1. Log into em using an url as follows

http://{server}:{adminserverport}/em

2. Click on your web service application
3. If indeed web services exist in the application you will see a web services table and "Java EE Web Services" tab as shown below.














4. Click on the "Test" icon to test your web service.

Tuesday, 1 September 2009

JDeveloper 11g - PLSQL Web Service Returning a Table of Objects

Got a few emails about problems using a Table of Objects within PLSQL Web Services now it's been reintroduced into JDeveloper 11g. Here is a small demo which worked fine for me.

1. Run the following SQL in the classic SCOTT schema

drop type dept_type;
drop type dept_list_table;

create type dept_type as object
(deptno NUMBER,
dname VARCHAR2(14),
loc varchar2(13),
cr_date date)
/

create type dept_list_table is table of dept_type
/

purge recyclebin;

create or replace package ws_package as

function test_dept_table return dept_list_table;

end ws_package;
/
show errors;

create or replace package body ws_package as

function test_dept_table return dept_list_table is

all_depts dept_list_table := dept_list_table();
dRecType dept_type;
i number := 0;

begin

-- iterate through all depts
for r_list in (select * from dept) loop

i := i + 1;

dRecType := dept_type(null, null, null, null);
dRecType.deptno := r_list.deptno;
dRecType.dname := r_list.dname;
dRecType.loc := r_list.loc;
dRecType.cr_date := sysdate;

all_depts.extend;
all_depts(i) := dRecType;

end loop;

return all_depts;

end test_dept_table;

end ws_package;
/
show errors;
2. Create a PLSQL Web Service called "DemoWS" using the defaults for the package WS_PACKAGE.

3. Right click on the Web Service "DemoWS" and select "Run". It may take a while to start but eventually you should see it's started as follows.

Run startup time: 10437 ms.
[Application WebServicesTest deployed to Server Instance DefaultServer]

Target URL -- http://localhost:7101/WebServicesTest-PLSQLTest-context-root/DemoWSPort
09/08/13 09:49:19 Web service DemoWS has been started on the embedded server

4. Copy the URL above into a browser.
5. Click on "Test Page"
6. Click on the only function "testDeptTable"
7. Verify response as follows.

<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
<env:Header />
<env:Body>
<m:testDeptTableResponse xmlns:m="http://au/support/ws/DemoWS.wsdl">
<result xmlns:typ="http://au/support/ws/DemoWS.wsdl/types/">
<typ:DeptTypeUser>
<typ:dname>ACCOUNTING</typ:dname>
<typ:loc>NEW YORK</typ:loc>
<typ:deptno>10</typ:deptno>
<typ:crDate>2009-08-13T08:36:53.000+10:00</typ:crDate>
</typ:DeptTypeUser>
<typ:DeptTypeUser>
<typ:dname>RESEARCH</typ:dname>
<typ:loc>DALLAS</typ:loc>
<typ:deptno>20</typ:deptno>
<typ:crDate>2009-08-13T08:36:53.000+10:00</typ:crDate>
</typ:DeptTypeUser>
<typ:DeptTypeUser>
<typ:dname>SALES</typ:dname>
<typ:loc>CHICAGO</typ:loc>
<typ:deptno>30</typ:deptno>
<typ:crDate>2009-08-13T08:36:53.000+10:00</typ:crDate>
</typ:DeptTypeUser>
<typ:DeptTypeUser>
<typ:dname>OPERATIONS</typ:dname>
<typ:loc>BOSTON</typ:loc>
<typ:deptno>40</typ:deptno>
<typ:crDate>2009-08-13T08:36:53.000+10:00</typ:crDate>
</typ:DeptTypeUser>
</result>
</m:testDeptTableResponse>
</env:Body>
</env:Envelope>

Note: If you wanted to test using the Table as an IN parameter simply create a method as follows in the PLSQL package which would enable you to test this as well.

function echo_dept_list_table (v1 in dept_list_table) return dept_list_table is

begin

return v1;

end echo_dept_list_table;