Here is a picture of the composite application with an EJB adapter as Service and Reference.
In this blog I will explain you first, how the SDO EJB is created and then how we use this as a Reference and as a Service
Select the Session Bean and generate a service interface on this
Now it goes totally wrong with the JDeveloper wizard 11G R1.
First step is fix the packages names of the SDO and SDOImpl classes, then we can refactor these classes and move it to the entities package. With this as result.
Select the session bean again and generate for the second time the service interface. Now we will get the WSDL.
Move the EJB WSDL and XSD to the Session bean package. With this as result.
Open the Entity XSD and change the target namespace and xmlns namespace to the same name as the package name in my case /nl/whitehorses/hr/ejb/entities/.
Using the SDO Ejb as a reference in Soa Suite 11g
Fill in the JNDI of the EJB on soa suite server , select the EJB jar and provide the Remote EJB interface class name.
Here is the result of a EJB service instance.
Here the link to official EJB adapter documentation. ( This can be a lot better )
Download here the EJB project I used and here the Soa Suite project.
In this blog I will explain you first, how the SDO EJB is created and then how we use this as a Reference and as a Service
Create SDO Eclipse EJB
First step is to create an EJB entity with Eclipselink as persistence provider. For this example I used the Employees table of the HR schema. Next step is to create an EJB Session Bean.
Here is an overview of my EJB model project.
Select the Session Bean and generate a service interface on this
Now it goes totally wrong with the JDeveloper wizard 11G R1.
First step is fix the packages names of the SDO and SDOImpl classes, then we can refactor these classes and move it to the entities package. With this as result.
Select the session bean again and generate for the second time the service interface. Now we will get the WSDL.
Move the EJB WSDL and XSD to the Session bean package. With this as result.
Open the Entity XSD and change the target namespace and xmlns namespace to the same name as the package name in my case /nl/whitehorses/hr/ejb/entities/.
before
after
Open the XSD of the WSDL and import the entity schema and fix the namespace.
Change /nl.whitehorses.hr.ejb.services/ to /nl/whitehorses/hr/ejb/services/ in every java, XSD or WSDL file
after
Open the XSD of the WSDL and import the entity schema and fix the namespace.
Change /nl.whitehorses.hr.ejb.services/ to /nl/whitehorses/hr/ejb/services/ in every java, XSD or WSDL file
Create a Datasource to the HR schema in Weblogic and make sure you are using the XA Oracle Driver and target this Datasource to the Soa suite server.
Deploy the EJB to the Soa Suite instance.
Open the composite application and drag the EJB adapter on the reference part of the composite.
Fill in the JNDI of the EJB on soa suite server , select the EJB jar and provide the Remote EJB interface class name.
Select the WSDL , Go the classes folder of the EJB model project and select the Session bean WSDL. This will copy the WSDL and the XSD to the local project folders and also import the jar. That's all , now you can invoke this in a BPEL process.
We can use the same EJB as starting point of our composite application. This time Soa Suite only uses the interface and does nothing with the Session Bean methods.
Drag the EJB adapter to the Services side of the composite overview.
The Service ID is very important because we need this name in serviceFactory.createService, The rest is the same as in the reference part. Use this EJB Service in a BPEL process.
The Service ID is very important because we need this name in serviceFactory.createService, The rest is the same as in the reference part. Use this EJB Service in a BPEL process.
Now we only have to make a simple java class where we call this EJB composite service.
package nl.whitehorses.soa.ejb.service;
import commonj.sdo.helper.DataFactory;
import java.util.Properties;
import javax.naming.Context;
import javax.naming.InitialContext;
import nl.whitehorses.hr.ejb.entities.EmployeesSDO;
import nl.whitehorses.hr.ejb.services.HrEmployeeEJB;
import oracle.integration.platform.blocks.sdox.ejb.api.SOAServiceFactory;
import oracle.integration.platform.blocks.sdox.ejb.api.SOAServiceInvokerBean;
import oracle.jbo.common.sdo.SDOHelper;
public class callejb {
public callejb() {
super();
}
public static void main(String[] args) {
try {
// very important to load every schema you use in the EJB
try {
SDOHelper.INSTANCE.defineSchema("nl/whitehorses/hr/ejb/entities/", "EmployeesSDO.xsd");
SDOHelper.INSTANCE.defineSchema("nl/whitehorses/hr/ejb/services/", "HrEmployeeEJBBeanWS.xsd");
} catch (Exception ex) {
ex.printStackTrace();
}
Properties props = new Properties();
props.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
// soa suite server
props.put(Context.PROVIDER_URL, "t3://localhost:8001");
InitialContext ctx = new InitialContext(props);
SOAServiceInvokerBean invoker = (SOAServiceInvokerBean)ctx.lookup("SOAServiceInvokerBean#oracle.integration.platform.blocks.sdox.ejb.api.SOAServiceInvokerBean");
//-- Create a SOAServiceFactory instance
SOAServiceFactory serviceFactory = SOAServiceFactory.newInstance(invoker);
// use the Service Id in the EJB service adapter
HrEmployeeEJB hrEmployeeEJB = serviceFactory.createService("EmployeeService", HrEmployeeEJB.class);
EmployeesSDO employeesSDO = ( EmployeesSDO )DataFactory.INSTANCE.create(EmployeesSDO.class);
employeesSDO.setDepartmentId(1L);
employeesSDO.setEmail("aaa@aa.nl");
employeesSDO.setEmployeeId(1L);
employeesSDO.setFirstName("edwin");
employeesSDO.setJobId("aa");
employeesSDO.setLastName("biemond");
employeesSDO.setPhoneNumber("123");
employeesSDO.setSalary(1000);
EmployeesSDO resultEmployeesSDO = hrEmployeeEJB.persistEmployeesSDO(employeesSDO);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
Here is the result of a EJB service instance.
Here the link to official EJB adapter documentation. ( This can be a lot better )
Download here the EJB project I used and here the Soa Suite project.
Marko said
ReplyDeletewhen i try to call ejb service from one-way bpel process eclilispelink throws an exception during parameter deserialization (parameter extends SDODataObject).
ejb call from (a)synch bpel process is working.
Hi Marko.
ReplyDeleteInteresting, I will take a look.
thanks edwin
Hi,
ReplyDeleteI am facing a problem while calling an EJB method having complex type as input,
Employee persistEmployee(Employee employee)
It says “Binding Component failed to invoke method persistEmployeeSDO”
From the logs, I see ClassCastException has occured
Caused by: java.lang.ClassCastException: org.eclipse.persistence.sdo.helper.ListWrapper cannot be cast to org.eclipse.persistence.sdo.SDODataObject
at org.eclipse.persistence.sdo.SDOResolvable.readExternal(SDOResolvable.java:258)
at commonj.sdo.impl.ExternalizableDelegator.readExternal(ExternalizableDelegator.java:83)
at org.eclipse.persistence.sdo.SDOExternalizableDelegator.readExternal(SDOExternalizableDelegator.java:60)
But, I am able make a call EJB method having simple type as input
Employee getEmployee(Long empId).
Any inputs on this.
Thanks in Advance,
Vidya
Hi Vidya,
ReplyDeleteCan you remove the List variables ( manytoone etc ) from the employee entity , lets see if it works with a simple entity
thanks Edwin
Hi Edwin,
ReplyDeleteI don't see any list variables in employee entity.
Still i am facing same issue.
Thanks,
Vidya
Hi,
ReplyDeleteDoes retrieving from the ejb works. ( only a persist problem )
Can you make a testcase for me or for Oracle support.
you can send it to biemond at gmail dot com
thanks
Hi,
ReplyDeleteI had sent you Test Case to your gmail mail id.
Thanks,
Vidya
Hi Vidya,
ReplyDeleteit is working with me , I send your testcase back with some working bpel examples
hope this helping .
thanks Edwin
Hi Edwin,
ReplyDeleteThanks for your support once again.
I observed one strange thing. If my composite contains a synchronous BPEL process, then I am able to invoke a persistEmployee method successfully. Your test case also contains a synchronous BPEL process.
I don't have any clue why it is working for synchronous BPEL process and not working for asynchronous BPEL process.
Any inputs on this?
Thanks,
Vidya
Hi guys,
ReplyDeletewe have same problem, this example won't work if bpel is asynch or instanced by file adapter. if you replace input parameters with simple types ejb method call will work in sync or asynch or bpels instanced by file adapter. this is not a problem with method result,results can be SDO objects in any case.
this issue is raised on metalink without response for a month.
if you like i can send you example projects for described scenarios
Hi Edwin,
ReplyDeleteCan you confirm if running the callejb class will persist the employee data in the database?
I have tried running it without errors but the data was not persisted. Did I miss something?
Regards,
Pino
Hi,
ReplyDeletethat should work, can you check modelunit of the persistence.xml
if you use the transaction manager of the application server and use a datasource.
and can you put the logging on fine ( persistence.xml ) then you can see in the console of the wls server the SQL output. you should see the update statement.
thanks
I can test the getemployeenameprocess
ReplyDeletein the enterprise manager and the corresponding SQL and SysOut statements are reflected in the console, but running the main method of callejb class does not invoke the persistEmployeesSDO() session bean method even though the steps in the BPEL were executed.
Pino
Hi
ReplyDeleteCan you check two things for me , make a entity and try to call the remote persist method not the sdo one and look in the database
and in PS1 somehow the jndi name in the composite.xml reference is mixed up with a wrong element
this is the right one
<reference name="EmployeeReferenceService"
ui:wsdlLocation="HrEmployeeEJBBeanWS.wsdl">
<interface.wsdl interface="/nl/whitehorses/hr/ejb/services/#wsdl.interface(HrEmployeeEJBBeanWS)"/>
<binding.ejb javaInterface="nl.whitehorses.hr.ejb.services.HrEmployeeEJB"
jarLocation="ejbSdoHr.jar"
jndiName="AdfEjbHr-model-HrEmployeeEJB#nl.whitehorses.hr.ejb.services.HrEmployeeEJB"/>
</reference>
Hi Edwin,
ReplyDeleteI did not have problems with the EmployeeReferenceService (Reference swimlane). In that, I was able to have a test case where the persistEmployeeSDO() works.
My problem is in the EmployeeService (Service swimlane). When I run your client calledejb the BPEL activities were executed successfully, but the persistEmployeesSDO() was not invoked even though that I had already fix the jndiName attribute( I actually copied the whole <binding.ejb> of the EmployeeReferenceService and applied it to the EmployeeService).
Another thing- What to use for the jarLocation? "ejbSdoHr.jar" or "sdo_svc_model.jar"
Right now, I am suspecting that the problem is on how the EmployeeService and BPELProcess2 is being bound.
I will try to do some more tweaking and will let you know of any result.
Regards,
Pino
Ok, Now I know what you mean.
ReplyDeleteindeed , the ejb service does nothing , in that case you will use the ejb interface as starting point , after that bpel takes it over. and BPEL you can do what you want.
Only the ejb reference does the retrievel , merge and persists.
thanks
Hi Edwin,
ReplyDeleteCan you please expalin JNDI of the EJB on soa suite server.
And after creating datasource for HR schema in weblogic console, do we need to update that any where?
Regards
PavanKumar.M
Hi,
ReplyDeletecan you explain your problem.
The datasource will be used in the EJB. ( persistence.xml ) .
the same datasource can be used in a db or aq resource adapter.
thanks
Hi Edwin,
ReplyDeleteI am using 11g PS2. I have created EJB and created data source as you mentioned. In bpel i am calling remove operation of EJB. I am getting binding fault saying "Invocation Exeption: :" as summary.
I have tested StandaloneEJB and it is ok. Seems some configuration issues.
Please show me the way.
Regards
PavanKumar.M
Hi,
ReplyDeleteCan you check the reference part in the composite , sometimes the wizard is not working well ( uses wrong attributes). check the jndiName attribute if it contains the jndi name.
thanks
Hi Edwin,
ReplyDeleteWe followed the steps to use an EJB Service. We have deployed and can successfully call a SOA composite. We've added an EJB Adapter to provide an additional method of calling the composite. When trying to call the composite EJB, we get:
java.lang.reflect.UndeclaredThrowableException
at $Proxy1.getRetail(Unknown Source)
at testejbclient.callejb.main(callejb.java:61)
Caused by: java.lang.ClassNotFoundException: o0.v1.services.rules.co.com.GetRetail
at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
more details of the exception at http://forums.oracle.com/forums/thread.jspa?threadID=2194850&tstart=0
Regards,
Subha
Hi,
ReplyDeleteCan you check if you made a service interface jar and use that everywhere and dont include the bean, only the interface and entities.
thanks
Hi Edwin,
ReplyDeleteFYI. There must be a lot of changes in 11.1.1.5 because I got a lot of issues when I run your sample client "callejb.java" in JDeveloper 11.1.1.5. The same is true with my own samples that I have made. Aside from the missing classes, I am stuck with the following error:
"Caused by: oracle.mds.config.MDSConfigurationException: MDS-01330: unable to load MDS configuration document
MDS-01329: unable to load element "persistence-config"
MDS-01370: MetadataStore configuration for metadata-store-usage "mstore-usage_1" is invalid.
MDS-01259: The metadata store "oracle.mds.persistence.stores.file.FileMetadataStore" cannot be instantiated.
oracle/dms/instrument/Noun"
FYI and regards,
Rommel Pino
Hi Pino,
ReplyDeleteIndeed, it seems like a bug. I think its need the some kind of configuration for the DMS which is located in the SOA MDS.
I think it should not use DMS ( I think it is something for performance ) or detect that is not necessary.
Maybe Oracle made some different client classes for this or it has to remove the dependency to DMS
can you check the jars
thanks
Sorry to resurrect this post but we are facing the similar class cast exception
ReplyDelete--------------------------------
java.lang.ClassCastException: org.eclipse.persistence.sdo.helper.ListWrapper cannot be cast to org.eclipse.persistence.sdo.SDODataObject
--------------------------------
as we have upgraded SOA Middle from 11.1.1.2 (PS1) to 11.1.1.5 (PS4).
What we detect is that ${wn.bea.home}/modules/org.eclipse.persistence_1.0.0.0_1-2-0.jar changed to
${wn.bea.home}/modules/org.eclipse.persistence_1.1.0.0_2-1.jar
and
for commonj.sdo_1.0.0.0_1-0.jar, it is still available and a new is available that we are using instead commonj.sdo_2.1.0.jar.
Are we right to use the new one (2.1.0) or should we stick to 1.0.0.0_1-0 or is it another thing ?
Regards,
Guillaume
Hi,
ReplyDeleteI also use the latest eclipselink and it is working fine for jpa.
Do you use it for soa suite or for deploying adf bc sdo web services.
Nowadays you can call the ejb session bean without any sdo.
sdo wizard in jdev was very buggy and is now a little bit better.
thanks
Hi Pino,
ReplyDeleteI have a Question, I have one composite which is having BPEL component and Calling the EJB webserive as referece.
Bpel is calling one method of the EJB serive, if that method give exception then how to handle and i want to retry to call that method to get the output.
so now how can write the retry exception mechanism in bpel.
Advance Thanks,
Ramu
Hi,
DeleteI think you get a binding error which you can handle in BPEL with catch all or the specific error catch or do it in the fault framework
plus with transactions you can better set the EJB method to requires new else you will see the error when BPEL finishes and then it is too late.
Thanks
Hi,
ReplyDeleteThe wizard to create service interface in JDeveloper 11g R1 does not work. It does not create .xsd files etc. How can I pass this step?
thx,
Parisa