Hello,
After my previous post http://www.javablog.fr/documentum-bof-sbo-service-based-business-object-tbo-type-based-business-object-aspects.html, just a mini post related an error java.lang.NoSuchMethodException which occurs when the use of a SBO’s method whereas it exists. Basically in JAVA, the problem seems concern the type of POJO’s argument used between the SBO and the SBO’s client (like DCTM JOB…), the package or attributes could be different.
03 | IDfService dfService = DfClient.getLocalClientEx().newService( "com.huo.lu.business.sbo.ecm.mail.IMailSBO" , session.getSessionManager()); |
05 | Method method = dfService.getClass().getMethod( "sendMail" , com.huo.lu.business.sbo.ecm.mail.Mail. class ); |
07 | method.invoke(dfService, mailMessage); |
09 | } catch (Exception e) { |
10 | throw new DfException(MessageFormat.format( "MailSBO.sendMail({0}, {1})" , session, mailMessage), e); |
13 | ....Caused by: java.lang.NoSuchMethodException: com.huo.lu.business.sbo.ecm.mail.impl.MailSBO.sendMail(com.huo.lu.business.sbo.ecm.mail.Mail) |
14 | at java.lang.Class.getMethod(Class.java: 1624 ) |
This error doesn’t concern the presence or not of “serialVersionUID” attribute in a POJO.The Serial Version ID is used when serializing and deserializing an object. Java recognizes if the bytes you want to deserialize match the local class version. If not it will throw an exception. This is important when doing RMI or persisting object structures.
1 | private static final long serialVersionUID = 6512673270706929264L; |
However, this error occurs even with a local POJO class totally identical with the POJO class version in SBO (same package, same source), so, a simple solution is the adding of JAR containing the POJO used in SBO in the CLIENT side. Another solution is the use of class loader of remote SBO when the method is loaded/retrieved with the use of JAVA reflection for instantiation for given REMOTE POJO classes.
2 | Method method = dfService.getClass().getMethod( "sendMail" , com.huo.lu.business.sbo.ecm.mail.Mail. class ); |
5 | Method method = dfService.getClass().getMethod( "sendMail" , dfService.getClass().getClassLoader().loadClass( "com.huo.lu.business.sbo.ecm.mail.Mail" )); |
Here, a full example using the SBO class loader and JAVA reflection.
So, the local POJO classes (InternetAddress / Mail) are NOT necessary:
01 | package com.huo.lu.business.sbo.ecm.mail; |
05 | public class InternetAddress { |
07 | private String address; |
08 | public InternetAddress() { |
01 | package com.huo.lu.business.sbo.ecm.mail; |
07 | private InternetAddress from; |
08 | private List<InternetAddress> to; |
09 | private List<InternetAddress> cc; |
10 | private List<InternetAddress> bcc; |
11 | private String subject; |
01 | IDfService dfService = DfClient.getLocalClientEx().newService( "com.huo.lu.business.sbo.ecm.mail.IMailSBO" , session.getSessionManager()); |
03 | ClassLoader classLoaderOfRemoteService = dfService.getClass().getClassLoader(); |
05 | Class<?> clazzMail = classLoaderOfRemoteService.loadClass( "com.huo.lu.business.sbo.ecm.mail.Mail" ); |
07 | Class<?> clazzInternetAddress = classLoaderOfRemoteService.loadClass( "com.huo.lu.business.sbo.ecm.mail.InternetAddress" ); |
09 | Mail objectMail = new Mail(); |
10 | objectMail = clazzMail.newInstance(); |
16 | Constructor<?> constructorInternetAddress = clazzInternetAddress.getConstructor( new Class[] { String. class , String. class }); |
17 | Object objectInternetAddress = constructorInternetAddress.newInstance( new Object[] { SENDER_EMAIL, SENDER_FRIENDLYNAME }); |
18 | Method methodSetFrom = objectMail.getClass().getMethod( "setFrom" , clazzInternetAddress); |
19 | methodSetFrom.invoke(objectMail, objectInternetAddress); |
25 | List<Object> listOfAssigneesInternetAddress = new ArrayList<Object>(); |
26 | for (Iterator<String> emailAssigneesIter = emailAssignees.iterator(); emailAssigneesIter.hasNext();) { |
27 | String emailAssigneeStr = emailAssigneesIter.next(); |
29 | Constructor<?> constructorInternetAddress = clazzInternetAddress.getConstructor( new Class[] { String. class }); |
30 | Object objectInternetAddress = constructorInternetAddress.newInstance( new Object[] { emailAssigneeStr }); |
31 | listOfAssigneesInternetAddress.add(objectInternetAddress); |
34 | Method methodSetTo = objectMail.getClass().getMethod( "setTo" , List. class ); |
35 | methodSetTo.invoke(objectMail, listOfAssigneesInternetAddress); |
41 | Method methodSetSubject = objectMail.getClass().getMethod( "setSubject" , String. class ); |
42 | methodSetSubject.invoke(objectMail, "SUBJECT 123" ); |
48 | Method methodSetBody = objectMail.getClass().getMethod( "setBody" , String. class ); |
49 | methodSetBody.invoke(objectMail, createMailBody()); |
52 | Method method = dfService.getClass().getMethod( "sendMail" , clazzMail); |
53 | method.invoke(dfService, objectMail); |
Best regards
Huseyin OZVEREN
Related