In-Memory Object Accessible for all the users (sessions)

Hi, We are working with Java Actions, which need to work with many files (read only). We have seen that it is not efficient to open the files for every user that executes this Java Action, instead, we would like to create a HashMap with all the files, cache it in memory and make it accessible for all the users (sessions), so the Java Actions only needs to get the files from memory (HashMap). The idea is to create this HashMap as part of the After Startup microflow and then keep it in memory till the Application Server stops. The problem is that I do not know how to create a global variable (java) in a Mendix project. What java file can I modify to create this global variable (HashMap)? If I create a Java Action I only have access to the object that is passed to it, I cannot create variables that will be kept after the Java Actions finishes. Any suggestions?
2 answers

I've had similar scenarios on quite a few occassions. I always handle this by creating a singleton class (IndexHandler) on startup, that you load with an array or hashmap of your in-memory entities. 

You can then create a few java-actions that call methods of this singleton (add entity, getSize, setArray, Search, etc). 

Here is a very simple example that doesn't handle search in the java, but merely returns the searcheable list (I tend to try and keep as much of my logic in Mendix as possible, for easy maintenance by other devs):

import java.util.ArrayList;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Map;

import com.mendix.core.Core;
import com.mendix.core.CoreException;
import com.mendix.logging.ILogNode;
import com.mendix.systemwideinterfaces.core.IContext;
import com.mendix.systemwideinterfaces.core.IMendixObject;

public class IndexHandler {

	private IContext context;
	private static IndexHandler indexHandler;
	private static boolean indexLoaded = false;
	private ArrayList<IMendixObject> searchIndexList;
	private static final ILogNode oLogNode = Core.getLogger("SearchIndex");
	private GregorianCalendar lastChanged;
	public static IndexHandler getInstance(IContext context) throws Exception {
		if(IndexHandler.indexHandler == null)
			IndexHandler.indexHandler = new IndexHandler(context);
		return IndexHandler.indexHandler;
	private IndexHandler(IContext context) {
		this.context = context;
		try {
			searchIndexList = getSearchTable();"IndexHandler singleton loaded");	
			lastChanged = new GregorianCalendar();
		} catch (Exception ex) {
			oLogNode.error("Error loading and setting index file: " + ex);
	public boolean isIndexLoaded() {
		return indexLoaded;
	public int countIndex () {
		return searchIndexList.size();

	private void setIndexLoaded(boolean indexLoaded) {
		IndexHandler.indexLoaded = indexLoaded;
	public ArrayList<IMendixObject> getSearchIndex () {
		return this.searchIndexList;
	public void addToIndex (IMendixObject searchIndex) {
		lastChanged = new GregorianCalendar();
	public void removeFromIndex (IMendixObject searchIndex) {
		lastChanged = new GregorianCalendar();
	public GregorianCalendar getLastChanged() {
		return lastChanged;
	public void forceReIndex () throws CoreException {
		lastChanged = new GregorianCalendar();
		searchIndexList = getSearchTable();
	private ArrayList<IMendixObject> getSearchTable() throws CoreException
	    Map<String,Object> parameters = new HashMap<String, Object>();
	    ArrayList<IMendixObject> outputList = Core.execute(context, "MyApp.SUB_Zoektabel_Build", parameters);
	    return outputList;