JDK-4136344 : (1.1) javah on just java.lang.Throwable fails
  • Type: Bug
  • Component: hotspot
  • Sub-Component: runtime
  • Affected Version: 1.1.6,1.1.7,1.1.8
  • Priority: P4
  • Status: Closed
  • Resolution: Won't Fix
  • OS:
    generic,solaris_2.5.1,solaris_2.6,windows_nt generic,solaris_2.5.1,solaris_2.6,windows_nt
  • CPU: generic,x86,sparc
  • Submitted: 1998-05-08
  • Updated: 2000-03-02
  • Resolved: 2000-03-02
Related Reports
Duplicate :  
Duplicate :  
Duplicate :  
Description
I'm classifying this as "runtime" instead of "javah" because it is really
a runtime problem.  The only reason we don't see it with the interpreter
is because "java.lang.Thread" is always resolved first.

% /usr/local/java/jdk1.1.7/solaris/bin/javah -d /tmp -classpath classes java.lang.Throwable
Signalled error "java/lang/ClassFormatError" with detail "Bad interface index"
java/lang/Throwable: no such class

% /usr/local/java/jdk1.1.7/solaris/bin/javah -d /tmp -classpath classes java.lang.Class java.lang.Throwable
[no error]

This is broken in 1.1.6 and 1.1.7 but is OK in 1.1.5.

dean.long@Eng 1998-05-07

Name: krT82822			Date: 09/29/99


with the following file Throwable.java

package java.lang;

public class Throwable  {

 }
we have the following error with jdk1.1.7B,
this same test was OK with jdk1.1.4
but it fails with jdk1.1.8_09
and it's OK with jdk1.2.1

javah -classpath $JDK_HOME/lib/classes.zip:./ java.lang.Throwable
Signalled error "java/lang/ClassFormatError" with detail "Bad interface index"
java/lang/Throwable: no such class

we can't use jdk1.2, and we would like a jdk 1.1.x compliant Y2K
(Review ID: 95883)
======================================================================

Name: krT82822			Date: 10/12/99


Under JDK version 1.1.3 (and I think 1.1.6) I was sucessfully
able to use the following command sequence.    The class files
DramaStatus.java and DramaException.java are below.

> javac -classpath .:/usr/java//lib/classes.zip -d . DramaStatus.java
> javac -classpath .:/usr/java//lib/classes.zip -d . DramaException.java
> javah -classpath .:/usr/java/lib/classes.zip:./au/gov/aao/drama/ -jni DramaException


When I tried this under JDK 1.1.8, the javah command failed. e.g.

> JAVA_HOME=/usr/local/java/jdk1.1.8
> javac -classpath .:/usr/local/java/jdk1.1.8/lib/classes.zip -d . DramaStatus.java
> javac -classpath .:/usr/local/java/jdk1.1.8/lib/classes.zip -d . DramaException.java
> javah -classpath .:/usr/local/java/jdk1.1.8/lib/classes.zip:./au/gov/aao/drama/ -jni DramaException
DramaException: no such class


I tried an alternative version of the javah command, as below, since
I beleive the requirement to specify the full package direction
may have been a bug in the older version.  There was no change

> javah -classpath .:/usr/local/java/jdk1.1.8/lib/classes.zip -jni DramaException
DramaException: no such class

Finally, I tried the following version

> javah -classpath .:/usr/local/java/jdk1.1.8/lib/classes.zip -jni au.gov.aao.drama.DramaException
Signalled error "java/lang/ClassFormatError" with detail "Bad interface index"
Signalled error "java/lang/NoClassDefFoundError" with detail "java/lang/Throwable"
Signalled error "java/lang/NoClassDefFoundError" with detail "java/lang/Exception"
au/gov/aao/drama/DramaException: no such class



Version details, java 1.1.3

> java -version
java version "1.1.3"
> java -fullversion
java full version "1.1.3n:1997.07.10"


Version details, java 1.1.8

> java -version
java version "1.1.8"
> java -fullversion
java full version "JDK1.1.8M"


In both cases, CLASSPATH was NOT set.  Although I did try
setting it to the same values as I was using with -classpath.

Java classes

// File DramaStatus.java
package au.gov.aao.drama;
/**
 * The DramaStatus class is used to access DRAMA status codes.
 *
 * @see DramaTask
 * @author Tony Farrell
 * @Version DramaStatus.java, Release 1.3, 06/04/99
 */
public class DramaStatus {

    private int statusCode = 0;

    public final static int OK = 0;

    static {
        System.loadLibrary ("dramajava");
    }

    /**
     * Construct a DramaStatus value from an integer value
     *
     * @param code The interger value to construct the code from.
     */
    DramaStatus(int code) {
        statusCode = code;
    }


    private static native String CvtToString(int status);

    /**
     * Convert a status code to a string.
     *
     * @returns The string translation of the status code.
     */
    public String toString() {
        return CvtToString(statusCode);
    }
    /**
     * Convert a status code to an integer value
     *
     * @returns The stauts code as an integer
     */
    public int toInt() {
        return statusCode;
    }

    /**
     * Tests a status code for equality with another status code
     * Remember that == will only test for a reference to the same object,
     * you must use this member function to test if two objects contain
     * the same code.
     *
     * @param s The status code to complare the object with
     * @returns True if the two codes refer to the same object
     */
    public boolean equals(DramaStatus s)
    {
        return (statusCode == s.statusCode);
    }
    /**
     * Tests a status code for equality with an integer value.
     *
     * @param s The status code to complare the object with
     * @returns True if the two codes refer to the same object
     */
    public boolean equals(int s)
    {
        return (statusCode == s);
    }
}
// End of file DramaStatus.java

// File DramaException.java
package au.gov.aao.drama;
import java.io.*;
import java.util.StringTokenizer;
/**
 *  This class implements exceptions for
 *  <a href="http://www.aao.gov.au/drama/html/dramaintro.html"><bf>DRAMA</bf></a> software.  The underlying C DRAMA software uses status codes throughout.
 * This exception class is a base for exceptions returned by the DRAMA Java
 * interface.  It also provides some integration with the DRAMA Ers module.
 *
 *
 * @see DramaStatus
 * @see DramaTask
 * @author Tony Farrell
 *
 * @Version DramaException.java, Release 1.10, 10/13/99
 */
public class DramaException extends Exception {
    private String detail;
    private DramaStatus statusCode;
    /**
     * Creates a DRAMA Exception object.
     *
     *  @param detailsString A string giving context for the error.
     *  @param status        The DRAMA Status code for the error.  If this
     *                       exception is ever converted back to a DRAMA
     *                       error report, this code can be fetched and
     *                       associated with the DRAMA error report.
     */
    public DramaException(String detailString, int status) {

        statusCode = new DramaStatus(status);
        detail = "Drama Error:" + detailString + ". DRAMA Status = " +
            statusCode;
    }
    /**
     * Creates a DRAMA Exception object.
     *
     *  @param detailsString A string giving context for the error.
     *  @param status        The DRAMA Status code for the error.  If this
     *                       exception is ever converted back to a DRAMA
     *                       error report, this code can be fetched and
     *                       associated with the DRAMA error report.
     */
    public DramaException(String detailString, DramaStatus status) {
        statusCode = status;
        detail = "Drama Error:" + detailString + ". DRAMA Status = " +
            statusCode;
    }
    /**
     * Return the status code associated with an exception.
     *
     * @returns The Drama Status associated with the exception.
     */
    public DramaStatus DramaStatus() {
        return statusCode;
    }
    
    // This version is used by the C++ routine DramaCheckAndCvt().  It is not
    // intended to be used from Java, but must be protected rather then
    // public to ensure the native code can access it.
    protected int DramaStatusInt() {
        return statusCode.toInt();
    }
    /**
     * Returns a string representation of a DRAMA Exception.
     *
     * @return The exception details as a string.
     */
     public String toString() {
	    return "DramaException[" + detail + "]";
     }

//   ReportIt is nothing more then a call to ErsRep.  We can't use the
//   DramaErs package as that package may throw this execption.
     private  native static void ReportIt(String s);

//   Called by DramaUtil.C/DramaCheckAndCvt to report a Java
//   exception using Ers.
    /**
     * Report a Java Exception using ERS.
     *
     * Thie function reports a Java Exception using the DRAMA ERS package,
     * allowing details to be forwarded to other tasks.
     *
     * Note, as it is a static function, is should be possible to call
     * it for any exception.
     *
     * @param e The exception to be reported.
     */
     public static void Report(Exception e) {


//          We output the exception stack trace into a byte array stream.
            OutputStream out = new ByteArrayOutputStream(1024);
            PrintWriter s = new PrintWriter(out);
            e.printStackTrace(s);

            ReportIt("JAVA Exception details are:");

//          Now work though each line in the string and output them
//          using ReportIt.
            StringTokenizer st = new StringTokenizer(out.toString(),"\n");
            while (st.hasMoreTokens())
            {
                ReportIt("  "+st.nextToken());
            }
            
        }
}
// End of file DramaException.java
(Review ID: 96463)
======================================================================

Comments
EVALUATION The code that causes the problem is in Locked_InitializeClass where we test type_table[interface_index] != CONSTANT_Class. In this case the value is CONSTANT_Class | CONSTANT_POOL_ENTRY_RESOLVED, because Throwable has been resolved as a result of resolving its superclass: Throwable --> Object --> Class --> ThreadDeath --> Error --> Throwable. dean.long@Eng 1998-05-07 Name: dd4877 Date: 03/02/2000 daniel.daugherty@eng 2000-03-02 Due to the upcoming retirement of the Classic VM and its JITs, this bug is being closed. If the same bug is known to be present in the HotSpot VM implementation, a separate bug should already exist in the relevant HotSpot subcategory. ======================================================================
11-06-2004

WORK AROUND There is a hidden cycle because resolving java.lang.Class triggers the resolving of several system classes. To avoid the bug, make sure java.lang.Class is resolved first to break cycles: javah [...] java.lang.Class [other classes] dean.long@Eng 1998-05-07
07-05-1998