public Class defineClass(ICompilableTypeInternal gsClass, boolean useSingleServingLoader) throws ClassNotFoundException { try { if (gsClass instanceof IGosuClassInternal && ((IGosuClassInternal) gsClass).hasBackingClass()) { return ((IGosuClassInternal) gsClass).getBackingClass(); } // there is no point in defining eval classes in a single serving class loader (it wastes // memory) if (useSingleServingLoader || TypeLord.isEvalProgram(gsClass) || isThrowawayProgram(gsClass) || isEnclosingTypeInSingleServingLoader(gsClass) || hasDiscreteNamespace(gsClass.getNamespace())) { // These classes are "fire and forget"; they need to be disposable after they run, // so we load them in a separate class loader so we can unload them -- it's the only // way to unload a class in java. return defineClassInLoader(gsClass, true); } return findOrDefineClass(gsClass); } catch (Exception e) { throw GosuExceptionUtil.forceThrow(e, gsClass.getName()); } }
private boolean shouldUseSingleServingLoader(ICompilableTypeInternal gsClass) { List<IGosuClassLoadingObserver> observers = CommonServices.getEntityAccess().getGosuClassLoadingObservers(); if (observers != null) { for (IGosuClassLoadingObserver observer : observers) { if (observer.shouldUseSingleServingLoader(gsClass)) { return true; } } } return hasDiscreteNamespace(gsClass.getNamespace()); }
private SingleServingGosuClassLoader getOrCreateSingleServingLoader( ICompilableTypeInternal gsClass) { ICompilableTypeInternal enclosingType = gsClass.getEnclosingType(); ClassLoader enclosingLoader = isOldStyleGosuAnnotationExpression(gsClass) ? null : getClassLoader(enclosingType); if (enclosingLoader instanceof SingleServingGosuClassLoader) { return (SingleServingGosuClassLoader) enclosingLoader; } SingleServingGosuClassLoader namespaceLoader = getDiscreteNamespaceLoader(gsClass.getNamespace()); return namespaceLoader == null ? new SingleServingGosuClassLoader(this) : namespaceLoader; }