Issue Details (XML | Word | Printable)

Key: GLASSFISH-16078
Type: Bug Bug
Status: Resolved Resolved
Resolution: Won't Fix
Priority: Major Major
Assignee: Mitesh Meswani
Reporter: skandalfo
Votes: 0
Watchers: 1

If you were logged in you would be able to see more operations.

RMI connections from appserver back to appclient for retrieving classes already present at the server.

Created: 22/Feb/11 09:25 AM   Updated: 03/Mar/11 02:56 PM   Resolved: 03/Mar/11 02:56 PM
Component/s: entity-persistence
Affects Version/s: None
Fix Version/s: None

Time Tracking:
Not Specified


Glassfish 3.1 b41 on Windows XP

Tags: glassfish RMI
Participants: kumara, Mitesh Meswani, skandalfo and Tim Quinn

 Description  « Hide

We're deploying an Enterprise Application containing an embedded Application Client that's deployed to the client via Java Web Start.

We have all the common artifacts inside the lib subdirectory of the .ear.

The client calls an injected remote interface of a bean, which has a method like this:

public void importConfiguration(TasksAndResources configuration);

The class TaskAndResources is serializable, and contains JPA 2.0 entities inside, via Set<Task> and Set<Resource> member attributes. These are present both in the client dependencies and in the .ear lib subdirectory.

However, when the client calls the above method, the Glassfish server connects back to the client (random RMI port listening) in order to retrieve the class definitions for Task, Resource, and ResourceRequirement (another entity that relates the former, but that's not directly referenced by the TaskAndResources class that's declared in the interface method).

We've verified these call backs by using Wireshark and dumping the packets. The requests from the server to the client seem to use an operation called "meta".

This seems rather strange. Why would the server need to download those classes, when they're already present in the .ear file, and a dependency (via MANIFEST.MF ClassPath attribute) to the called ejb implementation?

Moreover, this breaks any hope we could have of being able to deploy the appclient when there's any kind of firewall between the client and the server. Since the callback port is random and non-configurable, we can't even create an ad-hoc rule.

I guess there must be some classloader related problem when de-serializing the client request; the Task, Resource and ResourceRequirement classes aren't found in whatever classpath is used for that classloader (even if actually present in the .ear), and then they get requested from the client. The ejb call then succeeds, BTW.

We detected this because the client would fail in client machines with more than one interface, when the random-port RMI server would declare a non-routable IP address for a local private interface.

kumara added a comment - 22/Feb/11 03:00 PM

Start with standalone client, will most likely need to go to orb or entity-persistence. Is it another manifestation of automatic weaving of persistent entities making client and server class definition different? In that the workaround might be to turn weaving off.

skandalfo added a comment - 24/Feb/11 02:45 AM

Hi again, and thanks for the reply.

We did add this XML fragment to the persistence.xml of the persistence unit containing the affected entity classes, in the hopes of disabling weaving:

<property name="eclipselink.weaving" value="false" />

We found the description of this property here:

However, after deploying our application with the modified persistence.xml file, we still see the meta requests for the three entity classes from the server to the client at the random RMI port

Perhaps we didn't disable weaving properly? Or is it a server-global configuration that cannot be disabled in the specific persistence.xml?

Tim Quinn added a comment - 24/Feb/11 01:48 PM

At least for the moment I am transferring this to the entity-persistence component, from where most of the help is likely to come.

Mitesh Meswani added a comment - 28/Feb/11 06:12 PM - edited

>We did add this XML fragment to the persistence.xml of the persistence unit containing the affected entity classes, in the hopes of disabling weaving

Specifying the property should disable weaving. To make sure that we are on same page as far as the ear content is concerned, can you please provide the structure of your .ear. I am assuming following:

appclient.jar #Contains appclient + Remote interface that you are calling into
ejb.jar #contains ejbs
pu.jar #Contains your entities and META-INF/persistence.xml

Are you by any chance injecting EMF in your appclient code?

skandalfo added a comment - 01/Mar/11 09:11 AM

Sorry for the noise.

We did indeed put those properties into the WRONG Persistence Unit (we modified our test PU, not our deployment PU).

Once we disabled weaving for the correct PU, Wireshark doesn't see any connection back from the server, nor any class download from the client to the server. It seems to be working as expected.

So it seems that the problem is actually related to weaving.

skandalfo added a comment - 01/Mar/11 09:12 AM - edited

BTW the only things injected to the application client are stateless session bean references.

skandalfo added a comment - 01/Mar/11 09:28 AM

I'll also include the layout of the .ear.

The root files are a webapp, three EJB modules and the appclient module.

Every EJB module has the @Local/@Remote interfaces that they implement in a correspondingly named -interfaces .jar file in the lib subdirectory.

The shared persistence unit classes are in lib/kronos-model.jar, which also depends on lib/kronos-sink-interfaces.jar, lib/kronos-task-interfaces.jar and lib/kronos-trigger-interfaces.jar

These are the files:


Mitesh Meswani added a comment - 01/Mar/11 06:32 PM

Thanks for all the information. You should be able to use static weaving to get benefits of weaving and not run into the issue. Can you please give it a try. You can find the instruction here

skandalfo added a comment - 02/Mar/11 11:23 AM

We've tested, and it works correctly when using static weaving too.

Mitesh Meswani added a comment - 03/Mar/11 02:56 PM

Thanks for confirming that static weaving works. The core issue here is that RMI-IIOP treats weaved and unweaved classes as different. Ken explains this very well in his blog ( Relevant section is copied at [1]. Currently we would suggest you to use static weaving as a workaround to this issue. I am closing this issue as "won't fix"

[1] From Ken's blog
One very interesting issue that showed up in 3.1 is related to JPA. We have some applications in which the same class appears in both the client and the server, and is marshaled as part of an RMI-IIOP request. However, the class is one that is instrumented by the JPA bytecode weaver on the server side. New JPA behavior introduced in GlassFish 3.1 added a new field to the modified class, and this in turn changed the RMI-IIOP hashcode for the class. The result of this is that (as far as Java Serialization or RMI-IIOP marshaling semantics are concerned) the old class and the new class are now different versions of the same class, and special handling is needed. RMI-IIOP handles this case using a remote object called the full value descriptor (FVD), which is sent in an IIOP message the first time a value type is marshaled on a newly opened ORB connection. When the receiver of an object detects that the version of the object received is not the same as the version of the object in the receiving VM, a method named "meta" is invoked on the FVD. This introduces an extra round trip at the network level, considerably slowing the request processing. This problem affected issues 15816 and 16078. There is no easy ORB-level solution for this (caching meta data from FVDs may be possible, but would be a bit tricky). The solutions are either to change the behavior of the JPA weaver, or to make both sides (client and server) weave (or not) the same way.