move to springloaded

This commit is contained in:
Rob Winch
2014-01-16 21:49:54 -06:00
parent 416ce6a3bc
commit 5361830d56
212 changed files with 5 additions and 7 deletions

View File

@@ -0,0 +1,321 @@
/*
* Copyright 2010-2012 VMware and contributors
*
* Licensed 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.springsource.loaded;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.StringTokenizer;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.springsource.loaded.agent.SpringPlugin;
/**
* Captures configurable elements - these are set (to values other than the defaults) in TypeRegistry when the system property
* springloaded.configuration is processed. It is possible to tweak them during testcases to simplify what is being tested - the
* test should reset them to their original values on completion.
*
* @author Andy Clement
* @since 0.5.0
*/
public class GlobalConfiguration {
private static Logger log = Logger.getLogger(GlobalConfiguration.class.getName());
/**
* Are references to fields being modified - covering both the GETS/SETS and the reflective references.
*/
public final static boolean fieldRewriting = true;
public static boolean catchersOn = true;
/**
* If active, SpringLoaded will be trying to watch for types changing on the file system once they have been made reloadable.
*/
public static boolean fileSystemMonitoring = false;
/**
* Global control for loadtime logging
*/
public static boolean logging = false;
/**
* verbose mode can trigger extra messages. Enable with 'verbose=true'
*/
public static boolean verboseMode = false;
/**
* Global control for runtime logging
*/
public static boolean isRuntimeLogging = false;
public static boolean callsideRewritingOn = true;
/**
* Allows a cache to be cleaned up as the agent starts (effectively starting with a new cache, if 'caching' is true)
*/
public static boolean cleanCache = false;
/**
* Determine whether on disk caching will be used.
*/
public static boolean isCaching = false;
/**
* A well known profile (e.g. grails) can tweak a lot of the default options in a particular way.
*/
public static String profile = null;
/**
* The base directory in which to create any cache (.slcache folder). If null then user.home will be used.
*/
public static String cacheDir = null;
public final static boolean logNonInterceptedReflectiveCalls = false;
/**
* Global control for checking assertions
*/
public final static boolean assertsOn = false;
public final static boolean isProfiling = false;
public static boolean directlyDefineTypes = true;
public final static boolean interceptReflection = true;
public static boolean reloadMessages = false;// can be forced on for testing
/**
* When a reload is attempted, if this is true it will be checked to confirm it is allowed and does not violate the supported
* reloadable changes that can be made to a type.
*/
public static boolean verifyReloads = true;
/**
* When classes are dumped by Utils.dump() this specifies where. A null value will cause us to dump into the default temp
* folder.
*/
public static String dumpFolder = null;
/**
* Global configuration properties set based on the value of system property 'springloaded'. If null then not yet initialized
* (and a call to initializeFromSystemProperty()) is needed. If settings are truely once per VM, they are set directly in
* GlobalConfiguration whereas if they may be overridden on a per classloader level, they are set in this properties object and
* may be overridden by the springloaded.properties files accessible through each classloader.
*/
public static Properties globalConfigurationProperties;
/**
* List of slashed classnames for types we should 'dump' during processing (for debugging purposes).
*/
public static List<String> classesToDump;
public static int maxClassDefinitions = 100;
/**
* List of dotted classnames representing classnames of plugins that should be loaded.
*/
public static List<String> pluginClassnameList;
public final static boolean debugplugins;
/**
* Look for a springloaded system property and initialize the 'default system wide' configuration based upon it.
*/
static {
// classesToDump = new ArrayList<String>();
// classesToDump.add("Demo");
globalConfigurationProperties = new Properties();
// Load global configuration
boolean debugPlugins = false;
try {
boolean specifiedCaching = false;
String value = System.getProperty("springloaded");
if (GlobalConfiguration.isRuntimeLogging && log.isLoggable(Level.FINEST)) {
log.finest("GlobalConfiguration: being configured from '" + value + "'");
}
// value is a ';' separated list of configuration options which either may be name=value settings or directives (just a name)
if (value != null) {
StringTokenizer st = new StringTokenizer(value, ";");
while (st.hasMoreTokens()) {
String kv = st.nextToken();
int equals = kv.indexOf('=');
if (equals != -1) {
// key=value
String key = kv.substring(0, equals);
// Supported settings:
// dump=XX,YYY,ZZZ
// - this option lists classes for which we should dump the bytecode, names are dotted
if (key.equals("dump")) {
String classList = kv.substring(equals + 1);
StringTokenizer clSt = new StringTokenizer(classList, ",");
classesToDump = new ArrayList<String>();
while (clSt.hasMoreTokens()) {
classesToDump.add(clSt.nextToken().replace('.', '/'));
}
if (isRuntimeLogging && log.isLoggable(Level.INFO)) {
log.info("configuration: dumping: " + classesToDump);
}
// } else if (key.equals("interceptReflection")) { // global setting
// interceptReflection = kv.substring(equals + 1).equalsIgnoreCase("true");
// if (isRuntimeLogging && log.isLoggable(Level.INFO)) {
// log.info("configuration: interceptReflection = " + interceptReflection);
// }
} else if (key.equals("cleanCache")) {
cleanCache = kv.substring(equals + 1).equalsIgnoreCase("true");
} else if (key.equals("caching")) {
specifiedCaching = true;
isCaching = kv.substring(equals + 1).equalsIgnoreCase("true");
} else if (key.equals("debugplugins")) {
debugPlugins = true;
} else if (key.equals("profile")) {
profile = kv.substring(equals + 1);
} else if (key.equals("cacheDir")) {
cacheDir = kv.substring(equals + 1);
} else if (key.equals("callsideRewritingOn")) { // global setting
callsideRewritingOn = kv.substring(equals + 1).equalsIgnoreCase("true");
if (isRuntimeLogging && log.isLoggable(Level.INFO)) {
log.info("configuration: callsideRewritingOn = " + callsideRewritingOn);
}
// } else if (key.equals("logNonInterceptedReflectiveCalls")) { // global setting
// logNonInterceptedReflectiveCalls = kv.substring(equals + 1).equalsIgnoreCase("true");
// if (isRuntimeLogging && log.isLoggable(Level.INFO)) {
// log.info("configuration: logNonInterceptedReflectiveCalls = " + logNonInterceptedReflectiveCalls);
// }
} else if (key.equals("verifyReloads")) { // global setting
verifyReloads = kv.substring(equals + 1).equalsIgnoreCase("true");
if (isRuntimeLogging && log.isLoggable(Level.INFO)) {
log.info("configuration: verifyReloads = " + verifyReloads);
}
} else if (key.equals("dumpFolder")) { // global setting
dumpFolder = kv.substring(equals + 1);
if (isRuntimeLogging && log.isLoggable(Level.INFO)) {
log.info("configuration: dumpFolder = " + dumpFolder);
}
} else if (key.equals("maxClassDefinitions")) {
try {
maxClassDefinitions = Integer.parseInt(kv.substring(equals + 1));
if (isRuntimeLogging && log.isLoggable(Level.INFO)) {
log.info("configuration: maxClassDefinitions = " + maxClassDefinitions);
}
} catch (NumberFormatException nfe) {
System.err.println("ERROR: unable to parse " + kv.substring(equals + 1) + " as a integer");
}
} else if (key.equals("logging")) {
GlobalConfiguration.isRuntimeLogging = kv.substring(equals + 1).equalsIgnoreCase("true");
GlobalConfiguration.logging = kv.substring(equals + 1).equalsIgnoreCase("true");
System.out.println("Spring-Loaded logging = (" + GlobalConfiguration.isRuntimeLogging + ","
+ GlobalConfiguration.logging + ")");
} else if (key.equals("verbose")) {
GlobalConfiguration.verboseMode = kv.substring(equals + 1).equalsIgnoreCase("true");
GlobalConfiguration.reloadMessages = verboseMode;
} else if (key.equals("rebasePaths")) {
// value is a series of "a=b,c=d,e=f" indicating from and to
globalConfigurationProperties.put("rebasePaths", kv.substring(equals + 1));
} else if (key.equals("inclusions")) {
globalConfigurationProperties.put("inclusions", kv.substring(equals + 1));
} else if (key.equals("exclusions")) {
globalConfigurationProperties.put("exclusions", kv.substring(equals + 1));
} else if (key.equals("plugins")) {
// plugins=com.myplugin.Plugin,com.somethingelse.SomeOtherPlugin
String pluginList = kv.substring(equals + 1);
StringTokenizer pluginListTokenizer = new StringTokenizer(pluginList, ",");
pluginClassnameList = new ArrayList<String>();
while (pluginListTokenizer.hasMoreTokens()) {
pluginClassnameList.add(pluginListTokenizer.nextToken());
}
}
} else {
// directive
}
}
}
// Profile support. A profile is a shortcut for configuring a bunch of options
if (profile != null) {
if (profile.equals("grails")) {
// Configure options based on a grails profile
// turn on caching if we have a cacheDir set or can put one in the .grails folder under user.home
if (cacheDir == null) {
try {
String userhome = System.getProperty("user.home");
if (userhome != null) {
cacheDir = new StringBuilder(userhome).append(File.separator).append(".grails").toString();
new File(cacheDir).mkdir();
}
} catch (Throwable t) {
System.err.println("looks like user.home is not set, or cannot write to it: cannot create cache.");
t.printStackTrace(System.err);
}
}
if (!specifiedCaching) {
if (cacheDir != null) {
isCaching = true;
}
}
if (pluginClassnameList == null) {
pluginClassnameList = new ArrayList<String>();
}
pluginClassnameList.add("org.springsource.loaded.SystemPropertyConfiguredIsReloadableTypePlugin");
// turn off the 3.0 reloading, for now (just because it hasn't been tested)
SpringPlugin.support305 = false;
}
} else {
if (isCaching) {
try {
String userhome = System.getProperty("user.home");
if (userhome != null) {
cacheDir = userhome;
}
} catch (Throwable t) {
System.err.println("looks like user.home is not set: cannot create cache.");
t.printStackTrace(System.err);
}
}
}
if (isCaching) {
// Ensure cache folder exists
try {
File cacheDirFile = new File(cacheDir);
if (!cacheDirFile.exists()) {
boolean created = cacheDirFile.mkdirs();
if (!created) {
System.err.println("Caching deactivated: failed to create cache directory: " + cacheDir);
isCaching = false;
}
} else {
if (!cacheDirFile.isDirectory()) {
System.err.println("Caching deactivated: unable to use specified cache area, it is not a directory: "
+ cacheDirFile);
isCaching = false;
}
}
} catch (Exception e) {
System.err.println("Unexpected problem creating specified cachedir: " + cacheDir);
e.printStackTrace();
}
}
} catch (Throwable t) {
System.err.println("Unexpected problem reading global configuration setting:" + t.toString());
t.printStackTrace();
}
debugplugins = debugPlugins;
}
}