-
1. Re: ModuleClassLoader (JBoss AS7), interfaces and Remote EJB
wdfink Feb 4, 2013 3:15 PM (in response to grubi)Often this is a issue where a class is passed by reference and not by value to a different application.
Could you provide a bit more information about packaging and your lookup and EJB access code?
-
2. Re: ModuleClassLoader (JBoss AS7), interfaces and Remote EJB
grubi Feb 5, 2013 3:30 AM (in response to wdfink)I will try it
As I wrote in the first post, we have a WebFramework and many Applications, which get common information from the WebFramework (like users, auth, business data, ...). They are all packaged in a WAR and share a common library, where we provide interfaces and tools for EJB, CDI, JSF, ... .
When the application server starts we first deploy the WebFramework and then all applications. Each application has a @Singleton @Stateless @Startup Bean which will, in this case, ask for the maintenance information from the WebFramework.
Required classes / interfaces from the common library:
IRemoteMaintenanceEJB (@Remote): This EJB is implemented in each application it either receives the information sent from the framework (hence the @Remote) or it ask itself for information. This is the mentioned @Singleton, ... Bean (when implemented).
@Remote
public interface IRemoteMaintenanceEJB {
public void maintenanceUpdate(List<IMaintenanceInfo> maintenances);
}
IRemoteWebFrameworkEJB (@Remote): Thie EJB is implemented in the WebFramework and provides access to all maintenances of an application.
@Remote
public interface IRemoteWebFrameworkEJB {
public List<IMaintenanceInfo> getMaintenances(int applicationId);
}
IMaintenanceInfo: The interfaces for the transferred maintenances (one instance per maintenance). It extends Serializable to enforce it.
public interface IMaintenanceInfo extends Serializable {
// some getters for int, Date, String and a boolean
}
Required classes in the WebFramework:
WebFrameworkEJBImpl (@Stateless): Thie is the implementation of IRemoteWebFrameworkEJB and simple fetches all maintenances from a database, instanciates a MaintenanceInfoImpl for each result and returns it as a java list (List<IMaintenanceInfo>).
@Stateless
public class WebFrameworkEJB implements IRemoteWebFrameworkEJB {
@Override
public List<IMaintenanceInfo> getMaintenances(int applicationID) {
// some black magic
}
}
MaintenanceInfoImpl: This is the implementation of IMaintenanceInfo which should be transferred from the WebFramework to the application.
public class MaintenanceInfo implements IMaintenanceInfo {
private static final long serialVersionUID = ...;
// member variables and getters/setters for the int, Date, String and boolean
// overwrites equals and toString
}
Finally the required classes in the Application:
MaintenanceEJBImpl: This is the implementation of IRemoteMaintenanceEJB.
@Singleton
@Startup
@LocalBean
@Named
public class MaintenanceEJB implements IRemoteMaintenanceEJB {
@PostConstruct
public void initialize() {
// ask for maintenances on startup - see below
}
@Override
public void maintenanceUpdate(List<IMaintenanceInfo> maintenanceInfo) {
// Iterate over the list, perform some calculations on existing maintenances in this EJB and finally sort the list
// see below
}
}
As soon as the MaintenanceEJBImpl is instantiated it will execute the following code in @PostConstruct (without error handling)
Context ctx = new InitialContext();
IRemoteWebFrameworkEJB remoteEjb = (IRemoteWebFrameworkEJB) ctx.lookup(String.format("java:global/%s/%s!%s", appName, className, interfaceName));
// appName = "WebFramework", className = "WebFrameworkEJBImpl", interfaceName = "package.IRemoteWebFrameworkEJB"
maintenanceUpdate(remoteEjb.getMaintenances(applicationId));
The ClassCastException occurres as soon as I iterate over this list (in maintenanceUpdate)
for (IMaintenanceInfo maintenance : maintenanceInfo) { // class cast exception
// do something
}
When the WebFramework calls the maintenanceUpdate() via the remote instance (same lookup as above) of the IRemoteMaintenanceEJB it will result in the mentioned ClassNotFoundException.
-
3. Re: ModuleClassLoader (JBoss AS7), interfaces and Remote EJB
grubi Feb 8, 2013 8:02 AM (in response to grubi)Any ideas?
-
4. Re: ModuleClassLoader (JBoss AS7), interfaces and Remote EJB
grubi Feb 20, 2013 3:39 AM (in response to grubi)Still looking for a solution.
No EJB guru around?
Or any other idea where I could ask for help?
-
5. Re: ModuleClassLoader (JBoss AS7), interfaces and Remote EJB
wdfink Feb 21, 2013 5:34 AM (in response to grubi)1 of 1 people found this helpfulFrom what I understand you have different applications which all use the IMaintenanceInfo interface.
I suppose that you pack the Interface or the Imple into each application, right?
In this case it is not possible to work with 'call by reference' b/c the classloader's are different and you have such CCEx.
You may extract the common classes into a module and set a dependency, or you have to use remoteIF with call-by-value which might be a performance drawback (but is full spec compliant).
-
6. Re: ModuleClassLoader (JBoss AS7), interfaces and Remote EJB
grubi Feb 21, 2013 6:00 AM (in response to wdfink)Thanks, that answer made it clear!
The common classes are packed in each application through the common library in WEB-INF/lib.
With "remoteIF " you mean "remote interface"?
I thought that I already use the remote interface of my EJBs b/c of the way I lookup the instance. If I'm wrong, what do I have to do to really use the remoteIF?
call-by-value will be automatically used as soon as it is the remote interface?
-
7. Re: ModuleClassLoader (JBoss AS7), interfaces and Remote EJB
wdfink Feb 21, 2013 1:55 PM (in response to grubi)Yes remoteIF mean remote interface.
It depends on the lookup what type you get back.
I'm not 100% sure, but I suppose default is by-reference.
Add the element to the ejb3 subsystem
<in-vm-remote-interface-invocationType pass-by-value="true"/>
You might toggle true/false to see whether it has effect.