151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/*
251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Copyright (c) 2001, 2003, Oracle and/or its affiliates. All rights reserved.
351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is free software; you can redistribute it and/or modify it
651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * under the terms of the GNU General Public License version 2 only, as
751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * published by the Free Software Foundation.  Oracle designates this
851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * particular file as subject to the "Classpath" exception as provided
951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * by Oracle in the LICENSE file that accompanied this code.
1051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
1151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is distributed in the hope that it will be useful, but WITHOUT
1251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * version 2 for more details (a copy is included in the LICENSE file that
1551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * accompanied this code).
1651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
1751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * You should have received a copy of the GNU General Public License version
1851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2 along with this work; if not, write to the Free Software Foundation,
1951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
2151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * or visit www.oracle.com if you need additional information or have any
2351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * questions.
2451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */
2551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
2651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#include "jni.h"
2751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#include "jvm.h"
2851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
29cab01ac294bb8ded259851673baa4c6ca226f828Steven Moreland#include <nativehelper/JNIHelp.h>
308d05e88f57c1ea5543d4012687c70cd64efcada0Piotr Jastrzebski
318d05e88f57c1ea5543d4012687c70cd64efcada0Piotr Jastrzebski#define NATIVE_METHOD(className, functionName, signature) \
328d05e88f57c1ea5543d4012687c70cd64efcada0Piotr Jastrzebski{ #functionName, signature, (void*)(className ## _ ## functionName) }
3351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
3451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskistatic jclass noSuchMethodErrCl;
3551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
364ef72d32afd6f6b81306b2664a6f3f30f6103ebfPrzemyslaw Szczepaniakstatic void ObjectStreamClass_initNative(JNIEnv *env)
3751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski{
3851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    jclass cl = (*env)->FindClass(env, "java/lang/NoSuchMethodError");
3951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    if (cl == NULL) {           /* exception thrown */
4051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return;
4151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
4251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    noSuchMethodErrCl = (*env)->NewGlobalRef(env, cl);
4351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski}
4451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
4551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/*
4651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Class:     java_io_ObjectStreamClass
4751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Method:    hasStaticInitializer
48fd17eabf30cec65a5cfb4df1a298fcf515ef7c93Przemyslaw Szczepaniak * Signature: (Ljava/lang/Class;Z)Z
4951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
5051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns true if the given class defines a <clinit>()V method; returns false
5151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * otherwise.
5251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */
5351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr JastrzebskiJNIEXPORT jboolean JNICALL
548d05e88f57c1ea5543d4012687c70cd64efcada0Piotr JastrzebskiObjectStreamClass_hasStaticInitializer(JNIEnv *env, jclass this,
55fd17eabf30cec65a5cfb4df1a298fcf515ef7c93Przemyslaw Szczepaniak                                       jclass clazz,
56fd17eabf30cec65a5cfb4df1a298fcf515ef7c93Przemyslaw Szczepaniak                                       jboolean checkSuperclass)
5751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski{
5851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    jclass superCl = NULL;
5951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    jmethodID superClinitId = NULL;
6051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    jmethodID clinitId =
6151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        (*env)->GetStaticMethodID(env, clazz, "<clinit>", "()V");
6251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    if (clinitId == NULL) {     /* error thrown */
6351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        jthrowable th = (*env)->ExceptionOccurred(env);
6451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        (*env)->ExceptionClear(env);    /* normal return */
6551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (!(*env)->IsInstanceOf(env, th, noSuchMethodErrCl)) {
6651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            (*env)->Throw(env, th);
6751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
6851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return JNI_FALSE;
6951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
7051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
71fd17eabf30cec65a5cfb4df1a298fcf515ef7c93Przemyslaw Szczepaniak    // Android-changed, if checkSuperclass == true, remove check for
72fd17eabf30cec65a5cfb4df1a298fcf515ef7c93Przemyslaw Szczepaniak    // superclass clinitId != child clinitId.
73fd17eabf30cec65a5cfb4df1a298fcf515ef7c93Przemyslaw Szczepaniak    // We're returning true to enable deserializing classes without explicit serialVersionID
74fd17eabf30cec65a5cfb4df1a298fcf515ef7c93Przemyslaw Szczepaniak    // that would fail in this check (b/29064453).
75fd17eabf30cec65a5cfb4df1a298fcf515ef7c93Przemyslaw Szczepaniak    if (checkSuperclass == JNI_FALSE) {
76fd17eabf30cec65a5cfb4df1a298fcf515ef7c93Przemyslaw Szczepaniak        return JNI_TRUE;
77fd17eabf30cec65a5cfb4df1a298fcf515ef7c93Przemyslaw Szczepaniak    }
78fd17eabf30cec65a5cfb4df1a298fcf515ef7c93Przemyslaw Szczepaniak
7951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /*
8051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Check superclass for static initializer as well--if the same method ID
8151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * is returned, then the static initializer is from a superclass.
8251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Empirically, this step appears to be unnecessary in 1.4; however, the
8351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * JNI spec makes no guarantee that GetStaticMethodID will not return the
8451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * ID for a superclass initializer.
8551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
8651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    if ((superCl = (*env)->GetSuperclass(env, clazz)) == NULL) {
8751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return JNI_TRUE;
8851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
8951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    superClinitId =
9051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        (*env)->GetStaticMethodID(env, superCl, "<clinit>", "()V");
9151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    if (superClinitId == NULL) {        /* error thrown */
9251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        jthrowable th = (*env)->ExceptionOccurred(env);
9351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        (*env)->ExceptionClear(env);    /* normal return */
9451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (!(*env)->IsInstanceOf(env, th, noSuchMethodErrCl)) {
9551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            (*env)->Throw(env, th);
9651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
9751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return JNI_TRUE;
9851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
9951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
10051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    return (clinitId != superClinitId);
10151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski}
1028d05e88f57c1ea5543d4012687c70cd64efcada0Piotr Jastrzebski
1038d05e88f57c1ea5543d4012687c70cd64efcada0Piotr Jastrzebskistatic JNINativeMethod gMethods[] = {
104fd17eabf30cec65a5cfb4df1a298fcf515ef7c93Przemyslaw Szczepaniak  NATIVE_METHOD(ObjectStreamClass, hasStaticInitializer, "(Ljava/lang/Class;Z)Z"),
1058d05e88f57c1ea5543d4012687c70cd64efcada0Piotr Jastrzebski};
1068d05e88f57c1ea5543d4012687c70cd64efcada0Piotr Jastrzebski
1078d05e88f57c1ea5543d4012687c70cd64efcada0Piotr Jastrzebskivoid register_java_io_ObjectStreamClass(JNIEnv* env) {
1088d05e88f57c1ea5543d4012687c70cd64efcada0Piotr Jastrzebski  jniRegisterNativeMethods(env, "java/io/ObjectStreamClass", gMethods, NELEM(gMethods));
1094ef72d32afd6f6b81306b2664a6f3f30f6103ebfPrzemyslaw Szczepaniak  ObjectStreamClass_initNative(env);
1108d05e88f57c1ea5543d4012687c70cd64efcada0Piotr Jastrzebski}
111