/** check for new listeners that are dynamically configured */ @Override public void propertyChanged(Config config, String key, String oldValue, String newValue) { if ("listener".equals(key)) { if (oldValue == null) oldValue = ""; String[] nv = config.asStringArray(newValue); String[] ov = config.asStringArray(oldValue); String[] newListeners = Misc.getAddedElements(ov, nv); Class<?>[] argTypes = { Config.class, JPF.class }; // Many listeners have 2 parameter constructors Object[] args = {config, JPF.this}; if (newListeners != null) { for (String clsName : newListeners) { try { JPFListener newListener = config.getInstance("listener", clsName, JPFListener.class, argTypes, args); addListener(newListener); logger.info("config changed, added listener " + clsName); } catch (JPFConfigException cfx) { logger.warning("listener change failed: " + cfx.getMessage()); } } } } }
private void initialize() { VERSION = config.getString("jpf.version", VERSION); memoryReserve = new byte[config.getInt("jpf.memory_reserve", 64 * 1024)]; // in bytes try { Class<?>[] vmArgTypes = {JPF.class, Config.class}; Object[] vmArgs = {this, config}; vm = config.getEssentialInstance("vm.class", JVM.class, vmArgTypes, vmArgs); Class<?>[] searchArgTypes = {Config.class, JVM.class}; Object[] searchArgs = {config, vm}; search = config.getEssentialInstance("search.class", Search.class, searchArgTypes, searchArgs); // although the Reporter will always be notified last, this has to be set // first so that it can register utility listeners like Statistics that // can be used by configured listeners Class<?>[] reporterArgTypes = {Config.class, JPF.class}; Object[] reporterArgs = {config, this}; reporter = config.getInstance("report.class", Reporter.class, reporterArgTypes, reporterArgs); if (reporter != null) { search.setReporter(reporter); } addListeners(); config.addChangeListener(new ConfigListener()); } catch (JPFConfigException cx) { logger.severe(cx.toString()); // cx.getCause().printStackTrace(); throw new ExitException(false, cx); } }