/* * Licensed to the Apache Software Foundation (ASF) under one or more contributor license * agreements. See the NOTICE file distributed with this work for additional information regarding * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance with the License. You may obtain a * copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under the License * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express * or implied. See the License for the specific language governing permissions and limitations under * the License. */ package org.apache.geode.internal; import org.apache.geode.internal.i18n.LocalizedStrings; import java.util.*; import java.lang.reflect.*; import java.io.InvalidClassException; /** * This class defines general native utils. * * */ public class SmHelper { static final boolean pureMode = PureJavaMode.isPure(); /* ================== Native Methods =========================== */ /** * Returns the size in bytes of a C pointer in this shared library, returns 4 for a 32 bit shared * library, and 8 for a 64 bit shared library */ public static int pointerSizeBytes() { if (pureMode) { throw new IllegalStateException( LocalizedStrings.SmHelper_POINTERSIZEBYTES_UNAVAILABLE_IN_PURE_MODE.toLocalizedString()); } else { return _pointerSizeBytes(); } } private static native int _pointerSizeBytes(); /* ================== System Administration =========================== */ /** * Sleeps for the specified number of nanoseconds. */ private static native void _nanosleep(int nanos); /** * Sleeps for the specified number of nanoseconds. */ public static void nanosleep(long nanos) throws InterruptedException { if (Thread.interrupted()) throw new InterruptedException(); if (nanos <= 0) { return; } if (nanos >= 1000000) { Thread.sleep(nanos / 1000000, (int) (nanos % 1000000)); } else { if (pureMode) { // fix for bug 35150 Thread.yield(); } else { _nanosleep((int) nanos); } } } /** * Returns the GemFire native code library's version string. */ public static String getNativeVersion() { if (pureMode) { return LocalizedStrings.SmHelper_NATIVE_CODE_UNAVAILABLE.toLocalizedString(); } else { return _getNativeVersion(); } } private static native String _getNativeVersion(); public static String getSystemId() { if (pureMode) { return "pureJavaMode"; } else { return _getSystemId(); } } private static native String _getSystemId(); /** Cache of class -> has zero-arg constructor */ private static Map zeroArgConstructorCache = new HashMap(); /** Cache of class -> has public zero-arg constructor */ private static Map publicConstructorCache = new HashMap(); /** * Allocates a new JOM instance of <code>c</code> and invokes the zero-argument constructor of * <code>initClass</code> on the new object to initialize it. This takes the place of the late, * lamented <code>allocateNewObject</code> method of <code>java.io.ObjectInputStream</code> in JDK * 1.3. * * @throws InvalidClassException If <code>c</code> or <code>initClass</code> represents a * primitive class. * @throws NoSuchMethodError If <code>initClass</code> doesn't have a zero-argument constructor * @throws IllegalAccessException If the zero-argument constructor is not public (only for * <code>Externalizable</code> classes in which <code>c.equals(initClass)</code> */ public static Object allocateJOMObject(Class c, Class initClass) throws IllegalAccessException, InvalidClassException { if (c.isPrimitive()) { throw new InvalidClassException(LocalizedStrings.SmHelper_IS_PRIMITIVE.toLocalizedString(), c.getName()); } else if (initClass.isPrimitive()) { throw new InvalidClassException(LocalizedStrings.SmHelper_IS_PRIMITIVE.toLocalizedString(), initClass.getName()); } // boolean hasZeroArgInit; if (!zeroArgConstructorCache.containsKey(initClass)) { try { // Constructor init = initClass.getDeclaredConstructor(new Class[0]); if (Modifier.isPublic(initClass.getModifiers())) { publicConstructorCache.put(initClass, Boolean.TRUE); } else { publicConstructorCache.put(initClass, Boolean.FALSE); } } catch (NoSuchMethodException ex) { zeroArgConstructorCache.put(initClass, Boolean.FALSE); throw new NoSuchMethodError(); } } else { Boolean b = (Boolean) zeroArgConstructorCache.get(initClass); if (!b.booleanValue()) { throw new NoSuchMethodError(); } } // // Doesn't let us invoke the non-public constructors of inner // // classes // boolean isPublic = // ((Boolean) publicConstructorCache.get(initClass)).booleanValue(); // if (c.equals(initClass) && !isPublic) { // throw new IllegalAccessException(); // } return _allocateJOMObject(c, initClass); } /** * Natively allocates a new JOM instance of <code>c</code> and invokes the zero-argument * constructor of <code>initClass</code> on the new object to initialize it. This takes the place * of the late, lamented <code>allocateNewObject</code> method of * <code>java.io.ObjectInputStream</code> in JDK 1.3. */ private static native Object _allocateJOMObject(Class c, Class initClass); /** * Uses native code to set the value of an object JOM field */ public static native void _setObjectField(Object o, Field field, Object newValue); }