ResourceFactory.getInstance() NoClassDefFoundError [SOLVED]

Hello,

I try here to add a very simple HTML form to OpenMRS, through a module. Based on what I see in the “referenceapplication” module, this could be done through the Activator class of the module.

I look at the setupHtmlForms() method in the ReferenceApplicationActiviator.java and see that the first thing done is

ResourceFactory resourceFactory = ResourceFactory.getInstance();

That seems to work great, and during debugging, I see that the static method ResourceFactory.getInstance()

/**
	 * This method is a hack to allow our module servlet to access this. Don't count on it.
	 */
	public static ResourceFactory getInstance() {
		if (instance == null)
			new ResourceFactory();
		return instance;
	}

is called correctly.

But I notice some comments in the code :

30 : * Registry for {@link ResourceProvider}s, and provides methods for getting resources. 31 * Since (as of 1.9) there’s no way to wire spring beans to a module servlet, the first instance 32 * of this bean that is instantiated at module startup is statically-accessible. 45 : // hack to allow our module servlet to access this 51 : * This method is a hack to allow our module servlet to access this. Don’t count on it.

However, when I want to call this method in my module example like this :

/**
 * @see ModuleActivator#started()
 */
public void started() {

	try {
		setupHtmlForms();
	}
	catch (Exception e) {
		Module mod = ModuleFactory.getModuleById(OneFieldFormConstants.MODULE_ID);
		ModuleFactory.stopModule(mod);
		throw new RuntimeException("failed to setup the required modules", e);
	}

	log.info("One Field Form Module started");

}

private void setupHtmlForms() throws Exception {
	try {
		ResourceFactory resourceFactory = ResourceFactory.getInstance();
		FormService formService = Context.getFormService();
		HtmlFormEntryService htmlFormEntryService = Context.getService(HtmlFormEntryService.class);

		List<String> htmlforms = Arrays.asList("onefieldform:htmlforms/onefieldform.xml");

		for (String htmlform : htmlforms) {
			HtmlFormUtil.getHtmlFormFromUiResource(resourceFactory, formService, htmlFormEntryService, htmlform);
		}
	}
	catch (Exception e) {
		// this is a hack to get component test to pass until we find the proper way to mock this
		if (ResourceFactory.getInstance().getResourceProviders() == null) {
			log.error("Unable to load HTML forms--this error is expected when running component tests");
		}
		else {
			throw e;
		}
	}
}

The program doesn’t run through ResourceFactory.getInstance() method, but instead to the constructor

public ResourceFactory() {
		// hack to allow our module servlet to access this
		if (instance == null)
			instance = this;
	}

which throws the error :

Exception in thread “Thread-16” java.lang.NoClassDefFoundError: org/openmrs/ui/framework/resource/ResourceFactory at org.openmrs.module.onefieldform.OneFieldFormActivator.setupHtmlForms(OneFieldFormActivator.java:99) at org.openmrs.module.onefieldform.OneFieldFormActivator.started(OneFieldFormActivator.java:71) at org.openmrs.module.ModuleUtil.refreshApplicationContext(ModuleUtil.java:871) at org.openmrs.module.web.WebModuleUtil.refreshWAC(WebModuleUtil.java:962) at org.openmrs.web.Listener.performWebStartOfModules(Listener.java:617) at org.openmrs.web.Listener.performWebStartOfModules(Listener.java:596) at org.openmrs.web.Listener.startOpenmrs(Listener.java:239) at org.openmrs.web.WebDaemon$1.run(WebDaemon.java:42) Caused by: java.lang.ClassNotFoundException: org.openmrs.ui.framework.resource.ResourceFactory at org.codehaus.plexus.classworlds.strategy.SelfFirstStrategy.loadClass(SelfFirstStrategy.java:50) at org.codehaus.plexus.classworlds.realm.ClassRealm.unsynchronizedLoadClass(ClassRealm.java:259) at org.codehaus.plexus.classworlds.realm.ClassRealm.loadClass(ClassRealm.java:235) at org.codehaus.plexus.classworlds.realm.ClassRealm.loadClass(ClassRealm.java:227) at org.mortbay.jetty.webapp.WebAppClassLoader.loadClass(WebAppClassLoader.java:375) at org.mortbay.jetty.webapp.WebAppClassLoader.loadClass(WebAppClassLoader.java:337) at org.openmrs.module.ModuleClassLoader.loadClass(ModuleClassLoader.java:544) at java.lang.ClassLoader.loadClass(ClassLoader.java:358) … 8 more

I don’t really understand the way this object Resource Factory class should be used ? And what the comments means.

Thank you for your help !

In your module’s config.xml, did you set the uiframework module either as required or aware of?

3 Likes

Okay. Right the dependency wasn’t in the config.xml Thank you

i was just hustling with the same problem for three days :smile: Thanks @dkayiwa