Changing sakai.properties live (No restart)

It is possible to change some properties live without a restart and have them take effect. For this to work the property has to be read by the code from ServerConfigurationService dynamically (For instance it can't be read just once during init) or it has to be a Spring Bean. You also need access to the server. In future versions of Sakai a property editor might exist for both messages and properties.

 

Make sure to also make the changes to your sakai/sakai.properties or sakai/local.properties files for these to persist after a restart.

 

 

For all of these, the easiest way I've found to do it is to create a directory in the webapps directory of tomcat on a running system "webapps/ROOT" if it doesn't already exist, and create a jsp file there called changeproperty.jsp

Then access this either using curl like 

curl http://localhost:8080/changeproperty.jsp or through the web. If you have a lot of servers, curl is easier.

To Use: For each of these cases, you want to change the values of the variables propname and propvalue to the property name and property value that you want to change.

Afterward just delete this file (and directory if you want?)

Sakai 2.9 and earlier

For Sakai 2.9 and earlier you can call ServerConfigurationService directly

changeproperty.jsp
<%@ page import="org.sakaiproject.component.api.ServerConfigurationService" %>
<%@ page import="org.sakaiproject.component.cover.ComponentManager" %>
<%@ page import="java.util.*" %>

<%
ServerConfigurationService serv = (ServerConfigurationService) ComponentManager.get(ServerConfigurationService.class);
Properties props = (Properties) serv.getClass().getMethod("getProperties",null).invoke(serv,null);

out.println("<pre>");
String propname,propvalue;

propname = "gradebook.class.average.decimal.places";
propvalue = "2";

out.println(propname+":"+props.get(propname));
out.println(props.setProperty(propname, propvalue));
out.println(propname+":"+props.get(propname));
out.println("</pre>");
%>

Sakai 10 and later

For Sakai 10 and later, there BasicConfig items are used.  KNL-968 - Getting issue details... STATUS

 

changeproperty.jsp
<%@ page import="org.sakaiproject.component.api.ServerConfigurationService" %>
<%@ page import="org.sakaiproject.util.BasicConfigItem" %>
<%@ page import="org.sakaiproject.component.cover.ComponentManager" %>
<%@ page import="java.util.*" %>

<%
ServerConfigurationService serv = (ServerConfigurationService) ComponentManager.get(ServerConfigurationService.class);
out.println("<pre>");String propname,propvalue;
//Define properties here

propname="version.sakai";
propvalue = "2.9.3";

out.println("Old value of "+propname+":"+serv.getString(propname));
//Change item
serv.registerConfigItem(BasicConfigItem.makeConfigItem(propname,propvalue,ServerConfigurationService.UNKNOWN));
out.println("New value of "+propname+":"+serv.getString(propname));
out.println("</pre>");
%>

Spring Properties

Spring bean properties in the form of property@id are special and you can still change (most of?) them through reflection against the class since most have predictable getters and setters. Give it a shot!

 

changeproperty.jsp
<%@ page import="org.sakaiproject.component.cover.ComponentManager" %>
<%@ page import="java.util.*" %>

<%
//Enter the property name and the new value here
String propname = "url@org.sakaiproject.sitestats.externalDbDataSource";
String propvalue = "New Value";

String[] s = propname.split("@");
String bean = s[1];
String method = Character.toUpperCase(s[0].charAt(0)) + s[0].substring(1); 
 
String getMethod = "get" + method; 
String setMethod = "set" + method;

//Prints all interfaces
//out.println(compMgr.getRegisteredInterfaces());
Object temp = compMgr.get(bean);
if (temp != null) {
    Object ret;
    ret = temp.getClass().getMethod(getMethod,null).invoke(temp,null); out.println(ret);
    ret = temp.getClass().getMethod(setMethod,String.class).invoke(temp,propvalue); out.println(ret);
    ret = temp.getClass().getMethod(getMethod,null).invoke(temp,null); out.println(ret);
}