JDK-6618406 : the problems of calling methods via invokevirtual
  • Type: Bug
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: 1.4.2_05
  • Priority: P3
  • Status: Closed
  • Resolution: Cannot Reproduce
  • OS: linux_redhat_4.0
  • CPU: x86
  • Submitted: 2007-10-18
  • Updated: 2010-08-05
  • Resolved: 2008-06-17
Related Reports
Relates :  
Description
The problems was found on the following environment.

OS : Readhat EL 4 (x86)
JDK: 1.4.2_05 (Server VM)

The details:

(1)com.licensee.uji.http.HttpSessionProfile

This class has a following method that is not specified any access modifier.

--------
void setApplicationProfile(ApplicationProfile)
--------

(2)com.licensee.sms.sol.sys.servlet.SMSCJFSessionProfile

The following method with public access modifier in this class has the
same signature as (1).

--------
public void setApplicationProfile(ApplicationProfile)
--------

(2)'s SMSCJFSessionProfile extends (1)'s HttpSessionProfile shown
   below. Since (1)'s package name is different from (2)'s, (2)'s
   method does not override (1)'s.

+--------------------------+
|(1) HttpSessionProfile    |
+--------------------------+
+--------------------------+
| ~setApplicationProfile   |
+--------------------------+
            A
            |
+--------------------------+
|(2) SMSCJFSessionProfile  |
+--------------------------+
+--------------------------+
| +setApplicationProfile   |
+--------------------------+

(3)com.licensee.uji.http.HttpSessionProfile.getSessionProfile(ApplicationProfile,SessionProfile) calls (1)'s method like below.

--------
  ((HttpSessionProfile)profile).setApplicationProfile(ApplicationProfile);
--------

(3) and (1) are in the same package, but calling (1)'s method may fail.

To investigate the cause, the following code inserts print() near
setApplicationProfile mehod calling.

----->
/* ObjectDispatcher.java */

package com.licensee.uji.http;
....
  protected SessionProfile getSessionProfile(ApplicationProfile ap, HttpSession session) {
    SessionProfile profile = (SessionProfile) session.getAttribute(SESSION);
    if (profile == null) {
      Ami.println(session, "getSessionProfile: profile == null.");    ---------------- (a)
      profile = ap.getFactory().newSessionProfile();
      if (profile == null) {
        Ami.println("getSessionProfile: newSessionProfile() return null."); ---------- (b)
      } else {
        Ami.println("getSessionProfile: newSessionProfile() "         ---------------- (c)
            + profile.getClass().getName() + " (" + Integer.toHexString(profile.hashCode()) + ")");
      }
      if (profile instanceof HttpSessionProfile) {
        Ami.println("getSessionProfile: profile instanceof HttpSessionProfile."); ---- (d)
        ((HttpSessionProfile) profile).init(session);
        Ami.println("getSessionProfile: Before setApplicationProfile ap =" + ap); ---- (e)
        ((HttpSessionProfile) profile).setApplicationProfile(ap);
        Ami.println("getSessionProfile: After setApplicationProfile ap =" + ap);  ---- (f)
      } else {
        ap.getLogComposer().println(LOGLEVEL, 
            "uji:Warning - a result of newSessionProfile is not an instance of HttpSessionProfile");
      }
      session.setAttribute(SESSION, profile);
      session.removeAttribute(BEAN_PROFILE);
    }
    return profile;
  }
<-----

----->
/* HttpSessionProfile.java */

package com.licensee.uji.http;

  void setApplicationProfile(ApplicationProfile ap) {
	Ami.println("setApplicationProfile: ap =" + ap
                     + " sp =" + Integer.toHexString(this.hashCode())); -------------- (x)
	if (ap == null) {
		new Throwable("setApplicationProfile").printStackTrace();
	}
    this.ap = ap;
  }
<-----

Below is the log.

run correctly:
----->
(a) [18/09/2007 18:43:23:306 +0900] ApcAmi: getSessionProfile: profile == null.
(c) [18/09/2007 18:43:23:306 +0900] ApcAmi: getSessionProfile: newSessionProfile() com.licensee.sms.sol.sys.servlet.SMSCJFSessionProfile (129ec81)
(d) [18/09/2007 18:43:23:306 +0900] ApcAmi: getSessionProfile: profile instanceof HttpSessionProfile.
(e) [18/09/2007 18:43:23:306 +0900] ApcAmi: getSessionProfile: Before setApplicationProfile ap =com.licensee.sms.sol.sys.servlet.SMSCJFApplicationProfile@eca36e
(x) [18/09/2007 18:43:23:306 +0900] ApcAmi: setApplicationProfile: ap =com.licensee.sms.sol.sys.servlet.SMSCJFApplicationProfile@eca36e sp =129ec81
(f) [18/09/2007 18:43:23:307 +0900] ApcAmi: getSessionProfile: After setApplicationProfile ap =com.licensee.sms.sol.sys.servlet.SMSCJFApplicationProfile@eca36e
<-----

wrong behavior:
----->
(a) [18/09/2007 19:05:03:283 +0900] ApcAmi: getSessionProfile: profile == null.
(c) [18/09/2007 19:05:03:283 +0900] ApcAmi: getSessionProfile: newSessionProfile() com.licensee.sms.sol.sys.servlet.SMSCJFSessionProfile (147f96a)
(d) [18/09/2007 19:05:03:283 +0900] ApcAmi: getSessionProfile: profile instanceof HttpSessionProfile.
(e) [18/09/2007 19:05:03:283 +0900] ApcAmi: getSessionProfile: Before setApplicationProfile ap =com.licensee.sms.sol.sys.servlet.SMSCJFApplicationProfile@eca36e
(f) [18/09/2007 19:05:03:284 +0900] ApcAmi: getSessionProfile: After setApplicationProfile ap =com.licensee.sms.sol.sys.servlet.SMSCJFApplicationProfile@eca36e
<-----

Comparing the two logs, (c) points the variable profile was set to
SMSCJFSessionProfile in both logs before calling setApplicationProfile
method.

When running correctly, log (x) shows
com.licensee.uji.http.HttpSessionProfile#setApplicationProfile was
called successfully but it was not called in the wrong case.

Since com.licensee.sms.sol.sys.servlet.SMSCJFSessionProfile is
customer's package, it is impossible to collect data to see if
SMSCJFSessionProfile#setApplicationProfile was executed when running
incorrectly.

In (3), The problem will not occur if stop using dynamic compilation.

Comments
EVALUATION Bug has been in incomplete state for nearly 9 months. Closing as not-reproducible.
17-06-2008