@Nullable public InstanceFactory findInstanceFactory(@Nonnull Type mockedType) { InstanceFactory instanceFactory = mockedTypesAndInstances.get(mockedType); if (instanceFactory != null) { return instanceFactory; } Class<?> mockedClass = getClassType(mockedType); //noinspection ReuseOfLocalVariable instanceFactory = mockedTypesAndInstances.get(mockedClass); if (instanceFactory != null) { return instanceFactory; } boolean abstractType = mockedClass.isInterface() || isAbstract(mockedClass.getModifiers()); for (Entry<Type, InstanceFactory> entry : mockedTypesAndInstances.entrySet()) { Type registeredMockedType = entry.getKey(); Class<?> registeredMockedClass = getClassType(registeredMockedType); if (abstractType) { registeredMockedClass = getMockedClassOrInterfaceType(registeredMockedClass); } if (mockedClass.isAssignableFrom(registeredMockedClass)) { instanceFactory = entry.getValue(); break; } } return instanceFactory; }
private Collection createList() throws IOException { Collection list = null; if (_type == null) list = new ArrayList(); else if (!_type.isInterface()) { try { list = (Collection) _type.newInstance(); } catch (Exception e) { } } if (list != null) { } else if (SortedSet.class.isAssignableFrom(_type)) list = new TreeSet(); else if (Set.class.isAssignableFrom(_type)) list = new HashSet(); else if (List.class.isAssignableFrom(_type)) list = new ArrayList(); else if (Collection.class.isAssignableFrom(_type)) list = new ArrayList(); else { try { list = (Collection) _type.newInstance(); } catch (Exception e) { throw new IOExceptionWrapper(e); } } return list; }
/** * Sets up the mocks defined in the given mock class. * * <p>If the type {@linkplain MockClass#realClass referred to} by the mock class is actually an * interface, then a {@linkplain #newEmptyProxy(ClassLoader, Class) new empty proxy} is created. * * @param mockClassOrInstance the mock class itself (given by its {@code Class} literal), or an * instance of the mock class * @return the new proxy instance created for the mocked interface, or {@code null} otherwise * @throws IllegalArgumentException if a given mock class fails to specify the corresponding real * class using the {@code @MockClass(realClass = ...)} annotation; or if a mock class defines * a mock method for which no corresponding real method or constructor exists in the real * class; or if the real method matching a mock method is {@code abstract} * @see #setUpMock(Class, Object) * @see #setUpMocks(Object...) * @see <a * href="http://code.google.com/p/jmockit/source/browse/trunk/main/test/mockit/MockAnnotationsTest.java#696"> * Example</a> */ public static <T> T setUpMock(Object mockClassOrInstance) { Class<?> mockClass; Object mock; if (mockClassOrInstance instanceof Class<?>) { mockClass = (Class<?>) mockClassOrInstance; mock = null; } else { mockClass = mockClassOrInstance.getClass(); mock = mockClassOrInstance; } MockClassSetup setup = new MockClassSetup(mock, mockClass); Class<?> realClass = setup.getRealClass(); T proxy = null; if (realClass.isInterface()) { //noinspection unchecked proxy = (T) newEmptyProxy(mockClass.getClassLoader(), realClass); setup.setRealClass(proxy.getClass()); } setup.redefineMethods(); return proxy; }
/** * check whether a class should not be considered for transformation * * @param clazz the class to check * @return true if clazz should not be considered for transformation otherwise false */ protected boolean isSkipClass(Class<?> clazz) { if (!inst.isModifiableClass(clazz)) { return true; } // we can safely skip array classes, interfaces and primitive classes if (clazz.isArray()) { return true; } if (clazz.isInterface()) { return true; } if (clazz.isPrimitive()) { return true; } String name = clazz.getName(); if (isBytemanClass(name) || !isTransformable(name)) { return true; } return false; }
@Override public void visit( final int version, final int access, final String name, final String signature, final String superName, final String[] interfaces) { Set<String> interfacesSet = new LinkedHashSet<String>(); if (interfaces != null) Collections.addAll(interfacesSet, interfaces); for (Class extraInterface : classList) { if (extraInterface.isInterface()) interfacesSet.add(BytecodeHelper.getClassInternalName(extraInterface)); } final boolean addGroovyObjectSupport = !GroovyObject.class.isAssignableFrom(superClass); if (addGroovyObjectSupport) interfacesSet.add("groovy/lang/GroovyObject"); super.visit( V1_5, ACC_PUBLIC, proxyName, signature, BytecodeHelper.getClassInternalName(superClass), interfacesSet.toArray(new String[interfacesSet.size()])); addDelegateFields(); if (addGroovyObjectSupport) { createGroovyObjectSupport(); } for (Class clazz : classList) { visitClass(clazz); } }
public void addMatchingSetters() { check(implInterface || !dataTypeIn.isInterface()); Set<String> usedFields = new HashSet<>(); if (constructorParams != null) { usedFields.addAll(constructorParams); } if (factoryParams != null) { usedFields.addAll(factoryParams); } for (List<String> list : setters.values()) { usedFields.addAll(list); } for (String fieldName : fields.keySet()) { FieldGen fieldGen = fields.get(fieldName); Method getter = fieldGen.method; if (getter == null) continue; if (usedFields.contains(fieldName)) continue; String setterName = "set" + Character.toUpperCase(fieldName.charAt(0)) + fieldName.substring(1); try { Method setter; if (implInterface) setter = dataTypeOut.getMethod(setterName, getter.getReturnType()); else setter = dataTypeIn.getMethod(setterName, getter.getReturnType()); if (!isPrivate(setter.getModifiers())) { addSetter(setter, asList(fieldName)); } } catch (NoSuchMethodException e) { throw new RuntimeException(e); } } }
/** * Create a default object of the given type. Prefers constructors with as few arguments as * possible. Creates an empty proxy for interfaces. * * @param type type to instantiate * @return default instance * @throws Exception if the default instance could not be created */ private static Object instantiateType(Class<?> type) throws Exception { if (type.isPrimitive()) return Defaults.defaultValue(type); else if (type == Void.class) return null; else if (type.isArray()) return Array.newInstance(type, 0); else if (type.isInterface()) return Proxy.newProxyInstance( type.getClassLoader(), new Class[] {type}, new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { return null; } }); // Take a constructor with as few params as possible Constructor constructor = type.getDeclaredConstructors()[0]; for (Constructor<?> c : type.getDeclaredConstructors()) { if (c.getParameterTypes().length < constructor.getParameterTypes().length) constructor = c; } Object[] params = new Object[constructor.getParameterTypes().length]; for (int i = 0; i < constructor.getParameterTypes().length; i++) { params[i] = instantiateType(constructor.getParameterTypes()[i]); } return constructor.newInstance(params); }
public void addSetter(Method method, List<String> fields) { check(implInterface || !dataTypeIn.isInterface()); checkNotNull(method); checkNotNull(fields); check(!isPrivate(method.getModifiers()), "Setter cannot be private: %s", method); check(method.getGenericParameterTypes().length == fields.size()); check(!setters.containsKey(method)); setters.put(method, fields); }
public SerializerGenClass(Class<?> type, Class<?> typeImpl) { checkNotNull(type); checkNotNull(typeImpl); check(type.isInterface()); check(type.isAssignableFrom(typeImpl)); this.dataTypeIn = type; this.dataTypeOut = typeImpl; this.implInterface = true; }
public static <T> List<T> createProxy( List<T> items, Class<T> type, Map<String, ProxyFilter> prop2Filter) { if (type == null || items == null) { throw new IllegalArgumentException("parameters are null"); } if (!type.isInterface()) { throw new IllegalArgumentException("proxy type is not a interface"); } return new ProxyListHandler<T>(items, type, prop2Filter); }
public void setConstructor(Constructor<?> constructor, List<String> fields) { check(implInterface || !dataTypeIn.isInterface()); checkNotNull(constructor); checkNotNull(fields); check(this.constructor == null, "Constructor is already set: %s", this.constructor); check(!isPrivate(constructor.getModifiers()), "Constructor cannot be private: %s", constructor); check(constructor.getGenericParameterTypes().length == fields.size()); this.constructor = constructor; this.constructorParams = fields; }
public static void premain(String args, Instrumentation inst) throws Exception { try { String[] agentArgs; if (args == null) agentArgs = new String[] {""}; else agentArgs = args.split(","); if (!agentArgs[0].equals("instrumenting")) jarFileName = agentArgs[0]; BaseClassTransformer rct = null; rct = new BaseClassTransformer(); if (agentArgs[0].equals("instrumenting")) { initVMClasses = new HashSet<String>(); for (Class<?> c : inst.getAllLoadedClasses()) { ((Set<String>) initVMClasses).add(c.getName()); } } if (!agentArgs[0].equals("instrumenting")) { inst.addTransformer(rct); Tracer.setLocals(new CounterThreadLocal()); Tracer.overrideAll(true); for (Class<?> c : inst.getAllLoadedClasses()) { try { if (c.isInterface()) continue; if (c.isArray()) continue; byte[] bytes = rct.getBytes(c.getName()); if (bytes == null) { continue; } inst.redefineClasses(new ClassDefinition[] {new ClassDefinition(c, bytes)}); } catch (Throwable e) { synchronized (System.err) { System.err.println("" + c + " failed..."); e.printStackTrace(); } } } Runtime.getRuntime() .addShutdownHook( new Thread() { public void run() { Tracer.mark(); try { PrintStream ps = new PrintStream("bailout.txt"); ps.println("Bailouts: " + Tracer.getBailoutCount()); ps.close(); } catch (Exception e) { } Tracer.unmark(); } }); if ("true".equals(System.getProperty("bci.observerOn"))) Tracer.overrideAll(false); } } catch (Exception e) { e.printStackTrace(); } }
static JavaMembers lookupClass( Scriptable scope, Class<?> dynamicType, Class<?> staticType, boolean includeProtected) { JavaMembers members; scope = ScriptableObject.getTopLevelScope(scope); ClassCache cache = ClassCache.get(scope); Map<Class<?>, JavaMembers> ct = cache.getClassCacheMap(); Class<?> cl = dynamicType; for (; ; ) { members = ct.get(cl); if (members != null) { return members; } try { members = new JavaMembers(scope, cl, includeProtected); break; } catch (SecurityException e) { // Reflection may fail for objects that are in a restricted // access package (e.g. sun.*). If we get a security // exception, try again with the static type if it is interface. // Otherwise, try superclass if (staticType != null && staticType.isInterface()) { cl = staticType; staticType = null; // try staticType only once } else { Class<?> parent = cl.getSuperclass(); if (parent == null) { if (cl.isInterface()) { // last resort after failed staticType interface parent = ScriptRuntime.ObjectClass; } else { throw e; } } cl = parent; } } } if (cache.isCachingEnabled()) ct.put(cl, members); return members; }
private T newContextObject() { try { if (type.isInterface()) { return (T) Classes.newDynamicProxy(type); } else { return (T) type.newInstance(); } } catch (Exception anExc) { throw new XmlReadingException(anExc); } }
public void setFactory(Method methodFactory, List<String> fields) { check(implInterface || !dataTypeIn.isInterface()); checkNotNull(methodFactory); checkNotNull(fields); check(this.factory == null, "Factory is already set: %s", this.factory); check(!isPrivate(methodFactory.getModifiers()), "Factory cannot be private: %s", methodFactory); check(isStatic(methodFactory.getModifiers()), "Factory must be static: %s", methodFactory); check(methodFactory.getGenericParameterTypes().length == fields.size()); this.factory = methodFactory; this.factoryParams = fields; }
public static PropertyDescriptor[] getPropertyDescriptors(Class<?> objectClass) { // If the class is an interface, use custom method to get all prop descriptors in the // inheritance hierarchy. // PropertyUtils.getPropertyDescriptors() does not work correctly for interface inheritance. It // finds props in the // actual interface ok, but does not find props in the inheritance hierarchy. if (objectClass.isInterface()) { return getInterfacePropertyDescriptors(objectClass); } else { return BeanUtils.getPropertyDescriptors(objectClass); } }
/** * Create entity factory for entities with a predefined component composition. * * @param factory type to create. * @param <T> type to create. Should implement {@link EntityFactory}. * @return Implementation of EntityFactory. * @see EntityFactory for instructions about configuration. */ @SuppressWarnings("unchecked") public <T extends EntityFactory> T createFactory(Class<?> factory) { if (!factory.isInterface()) throw new MundaneWireException("Expected interface for type: " + factory); String impl = factory.getName() + "Impl"; try { Class<?> implClass = ClassReflection.forName(impl); Constructor constructor = ClassReflection.getConstructor(implClass, World.class); return (T) constructor.newInstance(this); } catch (ReflectionException e) { throw new RuntimeException(e); } }
public void addField(Field field, SerializerGen serializer, int added, int removed) { check(implInterface || !dataTypeIn.isInterface()); check(isPublic(field.getModifiers())); String fieldName = field.getName(); check(!fields.containsKey(fieldName), "Duplicate field '%s'", field); FieldGen fieldGen = new FieldGen(); fieldGen.field = field; fieldGen.serializer = serializer; fieldGen.versionAdded = added; fieldGen.versionDeleted = removed; fieldGen.offset = lastOffset; lastOffset += getType(field.getType()).getSize(); fields.put(fieldName, fieldGen); }
TestedField( @Nonnull InjectionState injectionState, @Nonnull Field field, @Nonnull Tested metadata) { this.injectionState = injectionState; testedField = field; this.metadata = metadata; fullInjection = metadata.fullyInitialized() ? new FullInjection(injectionState) : null; Class<?> fieldType = field.getType(); if (fieldType.isInterface()) { testedObjectCreation = null; } else { testedObjectCreation = new TestedObjectCreation(injectionState, fullInjection, field); injectionState.lifecycleMethods.findLifecycleMethods(fieldType); } }
private Mod loadCustomMod(URLClassLoader loader, String className) throws IOException, ClassNotFoundException, IllegalAccessException, InstantiationException { Class<?> cl = null; try { cl = loader.loadClass(className); } catch (NoClassDefFoundError e) { Logger.log(Logger.LOG_MOD, "WARNING: skipping %s: %s", className, e.toString()); } if (cl != null && !cl.isInterface() && Mod.class.isAssignableFrom(cl)) { int flags = cl.getModifiers(); if (!Modifier.isAbstract(flags) && Modifier.isPublic(flags)) { return newModInstance(cl.asSubclass(Mod.class)); } } return null; }
static Object js_createAdpter(Context cx, Scriptable scope, Object[] args) { int N = args.length; if (N == 0) { throw ScriptRuntime.typeError0("msg.adapter.zero.args"); } Class superClass = null; Class[] intfs = new Class[N - 1]; int interfaceCount = 0; for (int i = 0; i != N - 1; ++i) { Object arg = args[i]; if (!(arg instanceof NativeJavaClass)) { throw ScriptRuntime.typeError2( "msg.not.java.class.arg", String.valueOf(i), ScriptRuntime.toString(arg)); } Class c = ((NativeJavaClass) arg).getClassObject(); if (!c.isInterface()) { if (superClass != null) { throw ScriptRuntime.typeError2("msg.only.one.super", superClass.getName(), c.getName()); } superClass = c; } else { intfs[interfaceCount++] = c; } } if (superClass == null) superClass = ScriptRuntime.ObjectClass; Class[] interfaces = new Class[interfaceCount]; System.arraycopy(intfs, 0, interfaces, 0, interfaceCount); Scriptable obj = ScriptRuntime.toObject(cx, scope, args[N - 1]); Class adapterClass = getAdapterClass(scope, superClass, interfaces, obj); Class[] ctorParms = {ScriptRuntime.ContextFactoryClass, ScriptRuntime.ScriptableClass}; Object[] ctorArgs = {cx.getFactory(), obj}; try { Object adapter = adapterClass.getConstructor(ctorParms).newInstance(ctorArgs); return getAdapterSelf(adapterClass, adapter); } catch (Exception ex) { throw Context.throwAsScriptRuntimeEx(ex); } }
/** * @return all of the classes x in the given directory (recursively) such that * clazz.isAssignableFrom(x). */ private List<Class> getAssignableClasses(File path, Class<TetradSerializable> clazz) { if (!path.isDirectory()) { throw new IllegalArgumentException("Not a directory: " + path); } @SuppressWarnings("Convert2Diamond") List<Class> classes = new LinkedList<>(); File[] files = path.listFiles(); if (files == null) { throw new NullPointerException(); } for (File file : files) { if (file.isDirectory()) { classes.addAll(getAssignableClasses(file, clazz)); } else { String packagePath = file.getPath(); packagePath = packagePath.replace('\\', '.'); packagePath = packagePath.replace('/', '.'); packagePath = packagePath.substring(packagePath.indexOf("edu.cmu"), packagePath.length()); int index = packagePath.indexOf(".class"); if (index == -1) { continue; } packagePath = packagePath.substring(0, index); try { Class _clazz = getClass().getClassLoader().loadClass(packagePath); if (clazz.isAssignableFrom(_clazz) && !_clazz.isInterface()) { classes.add(_clazz); } } catch (ClassNotFoundException e) { e.printStackTrace(); } } } return classes; }
/** * @param classloader * @param superClass * @param classes * @param className */ @SuppressWarnings("unchecked") private static void checkAndAddClass( ClassLoader classloader, Class superClass, LinkedList<Class> classes, String className) { if (className.indexOf('$') > -1) return; try { Class subClass = classloader.loadClass(className); if (subClass != null && !superClass.equals(subClass) && superClass.isAssignableFrom(subClass) && !subClass.isInterface() && !classes.contains(subClass)) { classes.add(subClass); } } catch (Throwable th) { logger.log(Level.WARNING, "checkAndAddClass error", th); } }
/** * Search the Interfaces implemented by this Class for in-bound Facets * * @param objectClass * @return Set of Facet classes for the class */ public static Set<Class<?>> getFacetClasses(Class<?> objectClass) { Set<Class<?>> facetClasses = new HashSet<Class<?>>(); // TODO check for @Facet annotated Fields with IN direction if (objectClass.isInterface()) { addIfFacet(objectClass, facetClasses); } else { while (Facet.class.isAssignableFrom(objectClass)) { Class<?>[] interfaceClasses = objectClass.getInterfaces(); for (int index = 0; index < interfaceClasses.length; ++index) { addIfFacet(interfaceClasses[index], facetClasses); } objectClass = objectClass.getSuperclass(); } } return facetClasses; }
public Type navigateParameterized(String name, Type[] params) throws OclTypeException { Type ret = Basic.navigateAnyParameterized(name, params); if (ret != null) return ret; Method foundmethod = null; // this is very similar to tudresden.ocl.lib.OclAnyImpl.findMethod // if you find a bug here, its probably there as well. // suprisingly one has not to go after interfaces since methods // inherited from interfaces are automatically included into the // implementing class. This does not happen for methods inherited // from the superclass, so we have to ascend to all superclasses. // unfortunately the above is only true for classes, getSuperclass invoked // on an interface returns null, regardless of the interfaces extended by the // interface. Therefore, we need to check out getInterfaces() if iclass is // an interface HashSet hsVisited = new HashSet(); LinkedList llToVisit = new LinkedList(); if (c.isInterface()) { // as we're dealing with actual instances, it can be assumed that Object is // a superclass llToVisit.add(java.lang.Object.class); } classloop: for (Class iclass = c; iclass != null; ) // iclass=iclass.getSuperclass()) { Method[] methods = iclass.getDeclaredMethods(); methodloop: for (int i = 0; i < methods.length; i++) { if (!name.equals(methods[i].getName())) continue methodloop; Class[] methodparams = methods[i].getParameterTypes(); if (params.length != methodparams.length) continue methodloop; System.err.print("Checking method " + name + " ("); for (int j = 0; j < methodparams.length; j++) { if (j != 0) { System.err.print(", "); } System.err.print(methodparams[j]); } System.err.println(")"); for (int j = 0; j < params.length; j++) if (!params[j].conformsTo(getTypeForClass(methodparams[j]))) { System.err.println("No conformance for paramter # " + j); continue methodloop; } if (foundmethod == null) foundmethod = methods[i]; else throw new OclTypeException("ambigious method " + name + " of " + c + ") queried."); break classloop; } // determine classes to be visited if (iclass.isInterface()) { Class[] ca = iclass.getInterfaces(); for (int i = 0; i < ca.length; i++) { if (!hsVisited.contains(ca[i])) { llToVisit.add(ca[i]); } } } else { if (!hsVisited.contains(iclass.getSuperclass())) { llToVisit.add(iclass.getSuperclass()); } } // mark current class visited hsVisited.add(iclass); // go to next class if (!llToVisit.isEmpty()) { iclass = (Class) llToVisit.remove(0); } else { iclass = null; } } if (foundmethod == null) { StringBuffer sb = new StringBuffer(); sb.append(c.toString() + " has no method " + name + " with parameters ("); for (int i = 0; i < params.length; i++) { if (i != 0) sb.append(", "); sb.append(params[i] + "/" + params[i]); } sb.append(")"); throw new OclTypeException(sb.toString()); } return getTypeForClass(foundmethod.getReturnType()); }
/** * Process and loop until told to stop. A callback_done will stop the loop and will return a * result. Otherwise null is returned. */ public Object run() throws CommandException { Object result = null; boolean shutdown = false; boolean closeWhenDone = true; Commands.ValueObject valueObject = new Commands.ValueObject(); // Working value object so not continually recreated. InvokableValueSender valueSender = new InvokableValueSender(); // Working valuesender so not continually recreated. try { boolean doLoop = true; /** * Note: In the cases below you will see a lot of finally clauses that null variables out. * This is because this is a long running loop, and variables declared within blocks are not * garbage collected until the method is terminated, so these variables once set would never * be GC'd. The nulling at the end of the case makes sure that any of those objects set are * now available for garbage collection when necessary. */ while (doLoop && isConnected()) { byte cmd = 0; try { if (LINUX_1_3) socket.setSoTimeout(1000); // Linux 1.3 bug, see comment on LINUX_1_3 cmd = in.readByte(); if (LINUX_1_3 && isConnected()) socket.setSoTimeout(0); // Linux 1.3 bug, see comment on LINUX_1_3 } catch (InterruptedIOException e) { continue; // Timeout, try again } switch (cmd) { case Commands.QUIT_CONNECTION: doLoop = false; break; // Close this connection case Commands.TERMINATE_SERVER: doLoop = false; shutdown = true; // Shutdown everything break; case Commands.GET_CLASS: String className = in.readUTF(); Class aClass = null; Class superClass = null; String superClassName = null; boolean added = false; try { aClass = Class.forName( className); // Turns out using JNI format for array type will work fine. added = server.getIdentityID(aClass, valueObject); boolean isInterface = aClass.isInterface(); boolean isAbstract = java.lang.reflect.Modifier.isAbstract(aClass.getModifiers()); superClass = aClass.getSuperclass(); superClassName = (superClass != null) ? superClass.getName() : ""; // $NON-NLS-1$ out.writeByte(Commands.GET_CLASS_RETURN); out.writeInt(valueObject.objectID); out.writeBoolean(isInterface); out.writeBoolean(isAbstract); out.writeUTF(superClassName); out.flush(); } catch (ClassNotFoundException e) { valueObject.set(); Commands.sendErrorCommand(out, Commands.GET_CLASS_NOT_FOUND, valueObject); } catch (ExceptionInInitializerError e) { sendException(e.getException(), valueObject, out); } catch (LinkageError e) { sendException(e, valueObject, out); } catch (Throwable e) { // Something bad, did we add a class? If we did remove it from the table. if (added) server.removeObject(server.getObject(valueObject.objectID)); throw e; } finally { // clear out for GC to work. className = null; aClass = null; superClass = null; superClassName = null; valueObject.set(); } break; case Commands.GET_CLASS_FROM_ID: int classID = in.readInt(); try { aClass = (Class) server.getObject(classID); boolean isInterface = aClass.isInterface(); boolean isAbstract = java.lang.reflect.Modifier.isAbstract(aClass.getModifiers()); superClass = aClass.getSuperclass(); superClassName = (superClass != null) ? superClass.getName() : ""; // $NON-NLS-1$ out.writeByte(Commands.GET_CLASS_ID_RETURN); out.writeUTF(aClass.getName()); out.writeBoolean(isInterface); out.writeBoolean(isAbstract); out.writeUTF(superClassName); out.flush(); } catch (ClassCastException e) { valueObject.set(); Commands.sendErrorCommand(out, Commands.CLASS_CAST_EXCEPTION, valueObject); } finally { // clear out for GC to work. aClass = null; superClass = null; superClassName = null; valueObject.set(); } break; case Commands.GET_OBJECT_DATA: int objectID = in.readInt(); Object anObject = null; try { anObject = server.getObject(objectID); valueObject.setObjectID(objectID, server.getIdentityID(anObject.getClass())); Commands.writeValue(out, valueObject, true); } catch (ClassCastException e) { valueObject.set(); Commands.sendErrorCommand(out, Commands.CLASS_CAST_EXCEPTION, valueObject); } finally { anObject = null; // Clear out for GC to work valueObject.set(); } break; case Commands.RELEASE_OBJECT: int id = in.readInt(); server.removeObject(server.getObject(id)); break; case Commands.NEW_INIT_STRING: classID = in.readInt(); // ID Of class to do new upon. String initString = in.readUTF(); // The init string. Object newValue = null; Class theClass = null; try { theClass = (Class) server.getObject(classID); if (theClass == null) { // The class wasn't found. So imply ClassNotFound exception. throw new ClassNotFoundException(); } InitializationStringParser parser = null; try { parser = InitializationStringParser.createParser(initString); newValue = parser.evaluate(); boolean primitive = parser.isPrimitive(); // If expected class is Void.TYPE, that means don't test the type of the result // to verify if correct type, just return what it really is. if (theClass != Void.TYPE && primitive != theClass.isPrimitive()) { valueObject.set(); Commands.sendErrorCommand(out, Commands.CLASS_CAST_EXCEPTION, valueObject); continue; // Goto next command. } if (primitive) { try { // Need to do special tests for compatibility and assignment. sendObject( newValue, classID != Commands.VOID_TYPE ? classID : server.getIdentityID(parser.getExpectedType()), valueObject, out, true); // This will make sure it goes out as the correct primitive type } catch (ClassCastException e) { // The returned type is not of the correct type for what is expected. valueObject.set(); Commands.sendErrorCommand(out, Commands.CLASS_CAST_EXCEPTION, valueObject); continue; // Goto next command } } else { if (newValue != null) { // Test to see if they are compatible. (Null can be assigned to any object, // so that is why it was tested out above). // If expected class is Void.TYPE, that means don't test the type of the result // to verify if correct type, just return what it really is. if (theClass != Void.TYPE && !theClass.isInstance(newValue)) { // The returned type is not of the correct type for what is expected. valueObject.set(); Commands.sendErrorCommand(out, Commands.CLASS_CAST_EXCEPTION, valueObject); continue; // Goto next command } } sendObject( newValue, NOT_A_PRIMITIVE, valueObject, out, true); // Send out as an object. } } catch (InitializationStringEvaluationException e) { if (e instanceof EvaluationException) { // Want to return the real exception. sendException(e.getOriginalException(), valueObject, out); } else { // Couldn't be evaluated, return an error for this. setExceptionIntoValue(e.getOriginalException(), valueObject); Commands.sendErrorCommand(out, Commands.CANNOT_EVALUATE_STRING, valueObject); } } finally { parser = null; // Clear out for GC to work } } catch (Throwable e) { sendException(e, valueObject, out); } finally { // Clear out for GC to work initString = null; theClass = null; newValue = null; valueObject.set(); } break; case Commands.INVOKE: Object target = null; Object[] parms = null; Class returnType = null; java.lang.reflect.Method aMethod = null; try { int methodID = in.readInt(); // ID of method to invoke aMethod = (java.lang.reflect.Method) server.getObject(methodID); // Method to invoke Commands.readValue(in, valueObject); target = getInvokableObject(valueObject); Commands.readValue(in, valueObject); if (valueObject.type == Commands.ARRAY_IDS) { // It is an array containing IDs, as it normally would be. valueSender.initialize(valueObject); Commands.readArray(in, valueObject.anInt, valueSender, valueObject, false); parms = (Object[]) valueSender.getArray(); } else { // It is all objects or null, so it should be an Object[] or null. If not, then this // is an error. parms = (Object[]) valueObject.anObject; } if (!aMethod.isAccessible()) aMethod.setAccessible( true); // We will allow all to occur. Let access control be handled by IDE and // compiler. newValue = aMethod.invoke(target, parms); returnType = aMethod.getReturnType(); if (returnType.isPrimitive()) { int returnTypeID = server.getIdentityID(returnType); // Need to tell sendObject the correct primitive type. sendObject(newValue, returnTypeID, valueObject, out, true); } else { sendObject( newValue, NOT_A_PRIMITIVE, valueObject, out, true); // Just send the object back. sendObject knows how to iterpret the type } } catch (CommandException e) { throw e; // Throw it again. These we don't want to come up as an exception proxy. // These should end the thread. } catch (java.lang.reflect.InvocationTargetException e) { // This is a wrappered exception. Return the wrappered one so it looks like // it was the real one. (Sometimes the method being invoked is on a // java.lang.reflect.Constructor.newInstance, // which in turn is an InvocationTargetException, so we will go until we don't have an // InvocationTargetException. Throwable t = e; do { t = ((java.lang.reflect.InvocationTargetException) t).getTargetException(); } while (t instanceof java.lang.reflect.InvocationTargetException); sendException(t, valueObject, out); } catch (Throwable e) { sendException(e, valueObject, out); // Turn it into a exception proxy on the client. } finally { // Clear out for GC to work valueObject.set(); parms = null; target = null; aMethod = null; returnType = null; newValue = null; valueSender.clear(); } break; case Commands.INVOKE_WITH_METHOD_PASSED: aClass = null; String methodName = null; Class[] parmTypes = null; target = null; parms = null; returnType = null; aMethod = null; try { Commands.readValue(in, valueObject); aClass = (Class) getInvokableObject(valueObject); // The class that has the method. methodName = in.readUTF(); Commands.readValue(in, valueObject); if (valueObject.type == Commands.ARRAY_IDS) { // It is an array containing IDs, as it normally would be. valueSender.initialize(valueObject); Commands.readArray(in, valueObject.anInt, valueSender, valueObject, false); parmTypes = (Class[]) valueSender.getArray(); } else { // It null, so it should be an null. If not, then this is an error. parmTypes = null; } aMethod = aClass.getMethod(methodName, parmTypes); // Now we get the info for the invocation of the method and execute it. Commands.readValue(in, valueObject); target = getInvokableObject(valueObject); Commands.readValue(in, valueObject); if (valueObject.type == Commands.ARRAY_IDS) { // It is an array containing IDs, as it normally would be. valueSender.initialize(valueObject); Commands.readArray(in, valueObject.anInt, valueSender, valueObject, false); parms = (Object[]) valueSender.getArray(); } else { // It is all objects or null, so it should be an Object[] or null. If not, then this // is an error. parms = (Object[]) valueObject.anObject; } if (!aMethod.isAccessible()) aMethod.setAccessible( true); // We will allow all to occur. Let access control be handled by IDE and // compiler. newValue = aMethod.invoke(target, parms); returnType = aMethod.getReturnType(); if (returnType.isPrimitive()) { int returnTypeID = server.getIdentityID(returnType); // Need to tell sendObject the correct primitive type. sendObject(newValue, returnTypeID, valueObject, out, true); } else { sendObject( newValue, NOT_A_PRIMITIVE, valueObject, out, true); // Just send the object back. sendObject knows how to iterpret the type } } catch (CommandException e) { throw e; // Throw it again. These we don't want to come up as an exception proxy. // These should end the thread. } catch (java.lang.reflect.InvocationTargetException e) { // This is a wrappered exception. Return the wrappered one so it looks like // it was the real one. (Sometimes the method being invoked is on a // java.lang.reflect.Constructor.newInstance, // which in turn is an InvocationTargetException, so we will go until we don't have an // InvocationTargetException. Throwable t = e; do { t = ((java.lang.reflect.InvocationTargetException) t).getTargetException(); } while (t instanceof java.lang.reflect.InvocationTargetException); sendException(t, valueObject, out); } catch (Throwable e) { sendException(e, valueObject, out); // Turn it into a exception proxy on the client. } finally { aClass = null; methodName = null; parmTypes = null; // Clear out for GC to work valueObject.set(); parms = null; target = null; aMethod = null; returnType = null; newValue = null; valueSender.clear(); } break; case Commands.GET_ARRAY_CONTENTS: try { target = server.getObject(in.readInt()); // Array to get the ids for. valueObject.setArrayIDS( new ArrayContentsRetriever(target), Array.getLength(target), Commands.OBJECT_CLASS); Commands.writeValue(out, valueObject, true); // Write it back as a value command. } catch (CommandException e) { throw e; // Throw it again. These we don't want to come up as an exception proxy. // These should end the thread. } catch (Throwable e) { sendException(e, valueObject, out); // Turn it into a exception proxy on the client. } finally { target = null; valueObject.set(); } break; case Commands.CALLBACK_DONE: try { if (connectionThread != null) { valueObject.set(); Commands.sendErrorCommand(out, Commands.UNKNOWN_COMMAND_SENT, valueObject); } else { try { Commands.readBackValue(in, valueObject, Commands.NO_TYPE_CHECK); if (valueObject.type == Commands.ARRAY_IDS) { // It is an array containing IDs, as it normally would be. valueSender.initialize(valueObject); Commands.readArray(in, valueObject.anInt, valueSender, valueObject, false); result = valueSender.getArray(); } else { result = getInvokableObject(valueObject); } doLoop = false; // We need to terminate and return result closeWhenDone = false; // Don't close, we will continue. } catch (CommandErrorException e) { // There was an command error on the other side. This means // connection still good, but don't continue the callback processing. doLoop = false; // We need to terminate and return result closeWhenDone = false; // Don't close, we will continue. throw e; // Let it go on out. } } } finally { valueObject.set(); valueSender.clear(); } break; case Commands.ERROR: try { // Got an error command. Don't know what to do but read the // value and simply print it out. Commands.readValue(in, valueObject); result = getInvokableObject(valueObject); System.out.println("Error sent to server: Result=" + result); // $NON-NLS-1$ } finally { valueObject.set(); } break; case Commands.EXPRESSION_TREE_COMMAND: try { processExpressionCommand(valueObject, valueSender); } finally { valueObject.set(); valueSender.clear(); } break; default: // Unknown command. We don't know how long it is, so we need to shut the connection // down. System.err.println("Error: Invalid cmd send to server: Cmd=" + cmd); // $NON-NLS-1$ doLoop = false; closeWhenDone = true; break; } } } catch (EOFException e) { // This is ok. It means that the connection on the other side was terminated. // So just accept this and go down. } catch (CommandException e) { throw e; } catch (SocketException e) { if (socket != null) throw new UnexpectedExceptionCommandException( false, e); // socket null means a valid close request } catch (Throwable e) { e.printStackTrace(); } finally { if (closeWhenDone) { try { for (Iterator itr = expressionProcessors.values().iterator(); itr.hasNext(); ) { ExpressionProcesserController exp = (ExpressionProcesserController) itr.next(); exp.close(); } } finally { expressionProcessors.clear(); } if (in != null) try { in.close(); } catch (Exception e) { } in = null; if (out != null) try { out.close(); } catch (Exception e) { } out = null; close(); } } if (closeWhenDone && connectionThread != null) server.removeConnectionThread(connectionThread); if (shutdown) server.requestShutdown(); return result; }
/** * Parse the BSHBlock for for the class definition and generate the class using ClassGenerator. */ public static Class generateClassImpl( String name, Modifiers modifiers, Class[] interfaces, Class superClass, BSHBlock block, boolean isInterface, CallStack callstack, Interpreter interpreter) throws EvalError { // Scripting classes currently requires accessibility // This can be eliminated with a bit more work. try { Capabilities.setAccessibility(true); } catch (Capabilities.Unavailable e) { throw new EvalError( "Defining classes currently requires reflective Accessibility.", block, callstack); } NameSpace enclosingNameSpace = callstack.top(); String packageName = enclosingNameSpace.getPackage(); String className = enclosingNameSpace.isClass ? (enclosingNameSpace.getName() + "$" + name) : name; String fqClassName = packageName == null ? className : packageName + "." + className; BshClassManager bcm = interpreter.getClassManager(); // Race condition here... bcm.definingClass(fqClassName); // Create the class static namespace NameSpace classStaticNameSpace = new NameSpace(enclosingNameSpace, className); classStaticNameSpace.isClass = true; callstack.push(classStaticNameSpace); // Evaluate any inner class class definitions in the block // effectively recursively call this method for contained classes first block.evalBlock(callstack, interpreter, true /*override*/, ClassNodeFilter.CLASSCLASSES); // Generate the type for our class Variable[] variables = getDeclaredVariables(block, callstack, interpreter, packageName); DelayedEvalBshMethod[] methods = getDeclaredMethods(block, callstack, interpreter, packageName); ClassGeneratorUtil classGenerator = new ClassGeneratorUtil( modifiers, className, packageName, superClass, interfaces, variables, methods, classStaticNameSpace, isInterface); byte[] code = classGenerator.generateClass(); // if debug, write out the class file to debugClasses directory if (DEBUG_DIR != null) try { FileOutputStream out = new FileOutputStream(DEBUG_DIR + '/' + className + ".class"); out.write(code); out.close(); } catch (IOException e) { throw new IllegalStateException( "cannot create file " + DEBUG_DIR + '/' + className + ".class", e); } // Define the new class in the classloader Class genClass = bcm.defineClass(fqClassName, code); // import the unq name into parent enclosingNameSpace.importClass(fqClassName.replace('$', '.')); try { classStaticNameSpace.setLocalVariable( ClassGeneratorUtil.BSHINIT, block, false /*strictJava*/); } catch (UtilEvalError e) { throw new InterpreterError("unable to init static: " + e); } // Give the static space its class static import // important to do this after all classes are defined classStaticNameSpace.setClassStatic(genClass); // evaluate the static portion of the block in the static space block.evalBlock(callstack, interpreter, true /*override*/, ClassNodeFilter.CLASSSTATIC); callstack.pop(); if (!genClass.isInterface()) { // Set the static bsh This callback String bshStaticFieldName = ClassGeneratorUtil.BSHSTATIC + className; try { LHS lhs = Reflect.getLHSStaticField(genClass, bshStaticFieldName); lhs.assign(classStaticNameSpace.getThis(interpreter), false /*strict*/); } catch (Exception e) { throw new InterpreterError("Error in class gen setup: " + e); } } bcm.doneDefiningClass(fqClassName); return genClass; }
/** * Gets registered object from CacheMap. The algorithm used to look up is <br> * 1. First check for exact match with clazz and context.<br> * 2. If didn't find, look for interfaces that clazz implements using the exact context.<br> * 3. If still didn't find, look for super class of clazz using the exact context. <br> * 4. If still didn't find, using the exact clazz with default context.<br> * 5. If still didn't find, return null.<br> * If found a match in step 1, 2, 3 or 4, it will return the registered object immediately. * * @param clazz the class which is used as the primary key. * @param context the context which is used as the secondary key. This parameter could be null in * which case the default context is used. * @return registered object the object associated with the class and the context. */ public T getRegisteredObject(Class<?> clazz, K context) { if (clazz == null) { return null; } Cache<K, T> cache = getCache(clazz); if (cache == null || !cache.containsKey(context)) { List<Class<?>> classesToSearch = new ArrayList<>(); classesToSearch.add(clazz); if (TypeUtils.isPrimitive(clazz)) { classesToSearch.add(TypeUtils.convertPrimitiveToWrapperType(clazz)); } else if (TypeUtils.isPrimitiveWrapper(clazz)) { classesToSearch.add(TypeUtils.convertWrapperToPrimitiveType(clazz)); } // Direct super interfaces, recursively addAllInterfaces(classesToSearch, clazz); Class<?> superClass = clazz; // Direct super class, recursively while (!superClass.isInterface()) { superClass = superClass.getSuperclass(); if (superClass != null) { classesToSearch.add(superClass); addAllInterfaces(classesToSearch, superClass); } else { break; } } if (!classesToSearch.contains(Object.class)) { classesToSearch.add(Object.class); // use Object as default fallback. } // search to match context first for (Class<?> c : classesToSearch) { Cache<K, T> cacheForClass = getCache(c); if (cacheForClass != null) { T object = cacheForClass.getObject(context); if (object != null) { return object; } } } // fall back to default context if (!_defaultContext.equals(context)) { for (Class<?> c : classesToSearch) { Cache<K, T> cacheForClass = getCache(c); if (cacheForClass != null) { T object = cacheForClass.getObject(_defaultContext); if (object != null) { return object; } } } } } if (cache != null) { T object = cache.getObject(context); if (object == null && !_defaultContext.equals(context)) { return getRegisteredObject(clazz, _defaultContext); } if (object != null) { return object; } } return null; }
public DataValueModelImpl(Class<T> type) { this.type = type; if (!type.isInterface()) throw new IllegalArgumentException("type must be an interface, was " + type); Method[] methods = type.getMethods(); for (Method method : methods) { Class<?> declaringClass = method.getDeclaringClass(); if (declaringClass == Object.class || declaringClass == Externalizable.class || declaringClass == BytesMarshallable.class || declaringClass == Copyable.class || declaringClass == Byteable.class) continue; // ignore the default or static methods if (isMethodDefaultOrStatic(method)) continue; String name = method.getName(); Class<?>[] parameterTypes = method.getParameterTypes(); final Class<?> returnType = method.getReturnType(); switch (parameterTypes.length) { case 0: { String name5 = getUnlock(name); if (name5 != null && returnType == void.class) { FieldModelImpl fm = acquireField(name5); fm.unlock(method); break; } String name4 = getBusyLock(name); if (name4 != null && returnType == void.class) { FieldModelImpl fm = acquireField(name4); fm.busyLock(method); break; } String name3 = getTryLock(name); if (name3 != null && returnType == boolean.class) { FieldModelImpl fm = acquireField(name3); fm.tryLock(method); break; } String name6 = getSizeOf(name); if (name6 != null && returnType == int.class) { FieldModelImpl fm = acquireField(name6); fm.sizeOf(method); break; } if (returnType == void.class) throw new IllegalArgumentException("void () not supported " + method); String name2 = getGetter(name, returnType); if (isVolatileGetter(name2)) { FieldModelImpl fm = acquireField(volatileGetterFieldName(name2)); fm.volatileGetter(method); fm.setVolatile(true); } else { FieldModelImpl fm = acquireField(name2); fm.getter(method); } break; } case 1: { String name7 = getUsing(name, method); if (name7 != null) { FieldModelImpl fm = acquireField(name7); fm.getUsing(method); break; } String name5 = getTryLockNanos(name); if (name5 != null && returnType == boolean.class) { FieldModelImpl fm = acquireField(name5); fm.tryLockNanos(method); break; } String name4 = getAtomicAdder(name); if (name4 != null) { FieldModelImpl fm = acquireField(name4); fm.atomicAdder(method); break; } String name3 = getAdder(name); if (name3 != null) { FieldModelImpl fm = acquireField(name3); fm.adder(method); break; } String name6 = getGetterAt(name, returnType); if (name6 != null && parameterTypes[0] == int.class && returnType != void.class) { if (isVolatileGetter(name6)) { FieldModelImpl fm = acquireField(volatileGetterFieldName(name6)); fm.volatileIndexedGetter(method); fm.setVolatile(true); } else { FieldModelImpl fm = acquireField(name6); fm.indexedGetter(method); } break; } if (returnType != void.class) throw new IllegalArgumentException("setter must be void " + method); String name2 = getSetter(name); if (isOrderedSetter(name2)) { FieldModelImpl fm = acquireField(orderedSetterFieldName(name2)); fm.orderedSetter(method); } else { FieldModelImpl fm = acquireField(name2); fm.setter(method); } break; } case 2: { String name2 = getCAS(name); if (name2 != null && returnType == boolean.class) { FieldModelImpl fm = acquireField(name2); fm.cas(method); break; } String name3 = getSetterAt(name); if (name3 != null && parameterTypes[0] == int.class && returnType == void.class) { if (isOrderedSetter(name3)) { FieldModelImpl fm = acquireField(orderedSetterFieldName(name3)); fm.orderedIndexedSetter(method); } else { FieldModelImpl fm = acquireField(name3); fm.indexedSetter(method); } break; } } default: { throw new IllegalArgumentException("method not supported " + method); } } } for (Map.Entry<String, FieldModelImpl> entry : fieldModelMap.entrySet()) { FieldModelImpl model = entry.getValue(); if ((model.getter() == null && model.getUsing() == null) || (model.setter() == null && model.getter().getReturnType().isPrimitive())) if (model.volatileGetter() == null || (model.orderedSetter() == null && model.volatileGetter().getReturnType().isPrimitive())) if (model.indexedGetter() == null || (model.indexedSetter() == null && model.indexedGetter().getReturnType().isPrimitive())) if (model.volatileIndexedGetter() == null || (model.orderedIndexedSetter() == null && model.volatileIndexedGetter().getReturnType().isPrimitive())) if (model.busyLock() == null || model.unlock() == null) throw new IllegalArgumentException( "Field " + entry.getKey() + " must have a getter & setter, or getAt & setAt, or busyLock & unlock."); if (model.indexedGetter() != null || model.indexedSetter() != null) if (model.indexSize() == null) throw new IllegalStateException( "You must set a MaxSize for the range of the index for the getter or setter"); Class ftype = model.type(); if (!isScalar(ftype) && !nestedMap.containsKey(ftype)) nestedMap.put(ftype, new DataValueModelImpl(ftype)); } }
/** * Construct a proxy generator. This generator is used when we need to create a proxy object for a * class or an interface given a map of closures. * * @param closureMap the delegates implementations * @param superClass corresponding to the superclass class visitor * @param interfaces extra interfaces the proxy should implement * @param proxyLoader the class loader which should be used to load the generated proxy * @param delegateClass if not null, generate a delegate field with the corresponding class * @param emptyBody if set to true, the unimplemented abstract methods will receive an empty body * instead of throwing an {@link UnsupportedOperationException}. */ public ProxyGeneratorAdapter( final Map<Object, Object> closureMap, final Class superClass, final Class[] interfaces, final ClassLoader proxyLoader, final boolean emptyBody, final Class delegateClass) { super(new ClassWriter(0)); this.visitedMethods = new LinkedHashSet<Object>(); this.delegatedClosures = closureMap.isEmpty() ? EMPTY_DELEGATECLOSURE_MAP : new HashMap<String, Boolean>(); boolean wildcard = false; for (Map.Entry<Object, Object> entry : closureMap.entrySet()) { String name = entry.getKey().toString(); if ("*".equals(name)) { wildcard = true; } this.delegatedClosures.put(name, Boolean.FALSE); } this.hasWildcard = wildcard; // if we have to delegate to another object, generate the appropriate delegate field // and collect the name of the methods for which delegation is active this.generateDelegateField = delegateClass != null; this.objectDelegateMethods = generateDelegateField ? createDelegateMethodList(delegateClass, interfaces) : EMPTY_STRING_SET; this.delegateClass = delegateClass; // a proxy is supposed to be a concrete class, so it cannot extend an interface. // If the provided superclass is an interface, then we replace the superclass with Object // and add this interface to the list of implemented interfaces boolean isSuperClassAnInterface = superClass.isInterface(); this.superClass = isSuperClassAnInterface ? Object.class : superClass; // create the base list of classes which have possible methods to be overloaded this.classList = new LinkedList<Class>(); this.classList.add(superClass); if (generateDelegateField) { classList.add(delegateClass); } if (interfaces != null) { Collections.addAll(this.classList, interfaces); } this.proxyName = proxyName(); this.loader = proxyLoader != null ? new InnerLoader(proxyLoader) : findClassLoader(superClass); this.emptyBody = emptyBody; // generate bytecode ClassWriter writer = (ClassWriter) cv; ClassReader cr = createClassVisitor(Object.class); cr.accept(this, 0); byte[] b = writer.toByteArray(); // CheckClassAdapter.verify(new ClassReader(b), true, new PrintWriter(System.err)); cachedClass = loader.defineClass(proxyName.replace('/', '.'), b); // cache no-arg constructor Class[] args = generateDelegateField ? new Class[] {Map.class, delegateClass} : new Class[] {Map.class}; Constructor constructor; try { constructor = cachedClass.getConstructor(args); } catch (NoSuchMethodException e) { constructor = null; } cachedNoArgConstructor = constructor; }