Search the FirstSpirit Knowledge Base
Hallo FS-Community,
wir verwenden eine FSM-Bibliothek, um eine JAR-Library in FirstSpirit zur Verfügung zu stellen. Hiervon wird in einem Beanshell-Skript Gebrauch gemacht, um einen Suchagenten aufzurufen (nur zu eurer Info).
Die Konfiguration der Klassen im JAR geschieht mittels Spring (bei uns application.xml). Diese XML-Datei liegt unter dem root-Verzeichnis des JAR:
de/...
ext/...
application.properties
application.xml
Die XML wird normal mit dem Befehl:
ApplicationContext context = new ClassPathXmlApplicationContext("application.xml");
gesucht und auf dem lokalen Testsystem auch gefunden.
Wird das ganze nun als FSM zusammengebaut, in der module.xml benannt und auf FirstSpirit deployed, so wirft er den Fehler:
ERROR 17.02.2011 14:26:40.528 {seID=21516} (de.espirit.firstspirit.server.scheduler.ScriptTaskExecutor): error during script execution : de.espirit.firstspirit.access.script.ExecutionException: Method Invocation de.edeka.internet.b2b.agent.SearchAgentImmobilie.main at line 3
de.espirit.firstspirit.access.script.ExecutionException: Method Invocation de.edeka.internet.b2b.agent.SearchAgentImmobilie.main at line 3
at de.espirit.firstspirit.server.script.BeanshellScriptEngine$BeanshellExecutable.execute(BeanshellScriptEngine.java:120)
at de.espirit.firstspirit.common.ScriptUtil.execute(ScriptUtil.java:88)
...
at de.espirit.common.util.SuspendableThread.run(SuspendableThread.java:36)
Caused by: org.springframework.beans.factory.BeanDefinitionStoreException: IOException parsing XML document from class path resource [application.xml]; nested exception is java.io.FileNotFoundException: class path resource [application.xml] cannot be opened because it does not exist
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:341)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:302)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:143)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:178)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:149)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:212)
at org.springframework.context.support.AbstractXmlApplicationContext.loadBeanDefinitions(AbstractXmlApplicationContext.java:126)
at org.springframework.context.support.AbstractXmlApplicationContext.loadBeanDefinitions(AbstractXmlApplicationContext.java:92)
at org.springframework.context.support.AbstractRefreshableApplicationContext.refreshBeanFactory(AbstractRefreshableApplicationContext.java:130)
at org.springframework.context.support.AbstractApplicationContext.obtainFreshBeanFactory(AbstractApplicationContext.java:467)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:397)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
at de.edeka.internet.b2b.agent.SearchAgentImmobilie.main(SearchAgentImmobilie.java:87)
...
at bsh.This.invokeMethod(Unknown Source)
at de.espirit.firstspirit.server.script.BeanshellScriptEngine$BeanshellExecutable.execute(BeanshellScriptEngine.java:111)
... 16 more
Caused by: java.io.FileNotFoundException: class path resource [application.xml] cannot be opened because it does not exist
at org.springframework.core.io.ClassPathResource.getInputStream(ClassPathResource.java:158)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:328)
... 47 more
Wir haben parallel eine FSM-WebApp, die eine vergleichbare Struktur aufweist. Dort funktioniert das Finden der application.xml einwandfrei.
Die Pfadangebe wurde bereits zu "/applicaiton.xml" geändert, es wurde versucht die XML ins FSM auszulagern und extra in der module.xml anzugeben. Alles mit dem gleichen Effekt: sie wird nicht gefunden!
Vielleicht ist bereits jemand auf das gleiche Problem gestoßen und hat eine Lösung gefunden. Aktuell ist dieses Problem ein ziemlicher Blocker!
Viele Grüße aus Hamburg!
Wahrscheinlich dieses Problem. Bitte mal den dort beschriebenen Workaround ausprobieren. Danke!
Mir ist folgende Info-Ausgabe im Logger ins Auge gefallen:
INFO 01.03.2011 16:23:35.300 {seID=21516} (org.springframework.beans.factory.xml.XmlBeanDefinitionReader): Loading XML bean definitions from file [/www/firstspirit4/application.xml]
Es wird IMMER ab /www/firstspirit4/ (das FS-Installationsverzeichnis) nach der XML gesucht. Variiere ich den Pfad im Code, z.B. auf ClassPathXmlApplicationContext("/www/firstspirit4/application.xml"), so wird beim nächsten Versuch unter dem Pfad "/www/firstspirit4/www/firstspirit4/application.xml" gesucht.
Haben Sie den vorgeschlagenen Workaround mal ausprobiert?
Da hier keine Antwort mehr zu kommen scheint, verweise ich mal auf dieses Posting.
Hallo zusammen!
Nein, wir haben den Workaround aus Zeitgründen nicht umgesetzt. Wir haben (aufgrund der Größe des Unterprojekts Gott sei Dank machbar) komplett auf die Springkonfiguration verzichtet und setzen auf .properties-Files. Zwar unschön, aber es läuft wenigstens.
Viele Grüße aus Hamburg.
Ich habe exakt das gleiche Problem wie initial von NilsH beschrieben. Ich versuche in einem Service Modul den Spring Context zu laden. Dies geschieht in der überladenen init(...) Methode des de.espirit.firstspirit.module.Service:
Ich bekomme die folgende Fehlermeldung:
INFO 08.11.2011 11:19:13.649 (org.springframework.beans.factory.xml.XmlBeanDefinitionReader): Loading XML bean definitions from class path resource [applicationContext-pimImport.xml]
ERROR 08.11.2011 11:19:13.651 (de.espirit.firstspirit.server.module.ServiceManagerImpl): cannot start service 'Modul PIM Import'.'PimImportService'
org.springframework.beans.factory.BeanDefinitionStoreException: IOException parsing XML document from class path resource [applicationContext-pimImport.xml]; nested exception is java.io.FileNotFoundException: class path resource [applicationContext-pimImport.xml] cannot be opened because it does not exist
@Override | |
public void init(ServiceDescriptor arg0, ServerEnvironment arg1) { | |
Logging.logInfo("Initialized PIM import module.", LOGGER); |
//initialize Spring | |
ApplicationContext ctx = new ClassPathXmlApplicationContext( | |
"classpath:applicationContext-pimImport.xml"); |
//get the beans we need here | |
this.pimImportHandler = ctx.getBean("pimImportHandler", PimImportHandler.class); |
if (this.pimImportHandler == null) { | |
this.isRunning = false; | |
this.isInitialized = false; | |
Logging.logError("Could not instantiate PIM import service.", LOGGER); | |
} else { | |
this.isInitialized = true; | |
Logging.logInfo("PIM import service initialized.", LOGGER); | |
} |
} |
I
Leider verstehe ich den von Peter Jodeleit vorgeschlagenen Hinweis auf den workaround nicht. Dort scheint es ein Classloader Problem zu geben nachdem ein eigener Thread aufgemacht wurde. Bei dem Eingangs geschilderten Problem und meinem sieht es aber so aus als ob die application.xml gar nicht gefunden wird obwohl sie im classpath liegt.
Kann hier noch jemand helfen? Vielleicht elaborieren?
Einige Frameworks arbeiten mit "Thread.contextClassLoader", um darüber Resourcen zu laden. Der wird von FirstSpirit aber nicht gesetzt. Das kann man aber im Modul-Code manuell machen, bevor der Framework-Code aufgerufen wird. Bitte aber darauf achten, das dieser auch wieder zurückgesetzt wird, weil sonst ein Memory-Leak entsteht (also am besten in einem try...finally Block).
Das scheint zu klappen:
Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader()); |
//initialize Spring | |
ApplicationContext ctx = new ClassPathXmlApplicationContext( | |
"classpath:applicationContext-pimImport.xml"); |
Danke für die Antwort
und nicht das try { } finally vergessen wie Peter schon schrieb
final ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
try {
Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
final ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:applicationContext-pimImport.xml");
} finally {
Thread.currentThread().setContextClassLoader(null);
}