Du verwendest einen veralteten Browser. Es ist möglich, dass diese oder andere Websites nicht korrekt angezeigt werden. Du solltest ein Upgrade durchführen oder ein alternativer Browser verwenden.
Hi!
Folgende Sachlage:
Ich habe hier einen JBoss AS 7.1.1 und eine Webapplikation (Spring, Hibernate, JSON, JQuery) und nun habe ich die Aufgabe dass gewisse .properties Dateien vom Kunden adaptiert werden wollen. Sprich die .properties nichts in .war sondern ins Filesystem oder dergleichen, hierbei kommt aber hinzu dass die Applikation beim Kunden natürlich in einem Cluster läuft.
Hat hiermit schon jemand Erfahrungen gemacht und kann mir einen Tipp geben?
Natürlich gibt es JBoss Modules (MBean?) jedoch dürfte das auch nicht so ohne weiteres im Cluster funktionieren? Ein shared directory kommt leider auch nicht in Frage somit habe ich noch eine andere Variante in Betracht gezogen, nämlich in der Applikation eine Adminseite zur Verfügung zu stellen wo div. Properties ausgelesen und verändert werden können. Hierbei gibts aber natürlich auch Probleme, nämlich dass beim restart des JBoss dann alle Änderungen an den .properties obsolet, weil nicht mehr vorhanden, wären da der JBoss anscheinend nicht "physisch" deployed? D.h. nach dem restart sind wieder die .properties vom .war die aktuellesten da selbige ja nicht wirklich überschrieben wurden.
Nun habe ich mir gedacht dann lege ich die .properties (jene die vom Kunden änderbar sein sollen sind eh in einem überschaubaren Rahmen) einfach in die Datenbank. Hierbei gibts natürlich wieder das Problem dass manche dieser Properties in der applicationContext.xml vom Spring benötigt werden und ich hierbei sicher nicht auf die Datenbank zugreifen kann?
Die Konfiguration sollte über einen Service geschehen. Vermutlich ist es tatsächlich das einfachste, diese Werte in einer DB zu halten. Von irgendwelchen Workarounds mit Propertiesdateien rate ich ab.
Wäre auch dafür sie in der Datenbank abzulegen, nur wie kann ich dann in der applicationContext.xml darauf zugreifen? Habe im Netz ein paar uralt Beispiele gesehen, kann mir aber nicht vorstellen dass es da nicht eine aktueller Art der Verwendung gibt?
Sprich wie kann ich die Properties aus der Datenbank hier hinzufügen:
Du musst nur eine Implementierung von PropertyPlaceholderConfigurer implementieren (evtl. davon ableiten), die Properties aus deiner alternativen Quelle (z.B. DB) ermittelt.
org.springframework.beans.factory.BeanInitializationException: Could not load properties; nested exception is java.io.IOException: org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC Connection; nested exception is java.sql.SQLException: Connections could not be acquired from the underlying database!
at org.springframework.beans.factory.config.PropertyResourceConfigurer.postProcessBeanFactory(PropertyResourceConfigurer.java:87)
at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:681)
at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:656)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:446)
at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:384)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:283)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:111)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4135)
at org.apache.catalina.core.StandardContext.start(StandardContext.java:4630)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1045)
at org.apache.catalina.core.StandardHost.start(StandardHost.java:785)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1045)
at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:445)
at org.apache.catalina.startup.Embedded.start(Embedded.java:825)
at org.codehaus.mojo.tomcat.AbstractRunMojo.startContainer(AbstractRunMojo.java:558)
at org.codehaus.mojo.tomcat.AbstractRunMojo.execute(AbstractRunMojo.java:255)
at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:101)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:209)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:84)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:59)
at org.apache.maven.lifecycle.internal.LifecycleStarter.singleThreadedBuild(LifecycleStarter.java:183)
at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:161)
at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:320)
at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:156)
at org.apache.maven.cli.MavenCli.execute(MavenCli.java:537)
at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:196)
at org.apache.maven.cli.MavenCli.main(MavenCli.java:141)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:290)
at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:230)
at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:409)
at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:352)
Caused by: java.io.IOException: org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC Connection; nested exception is java.sql.SQLException: Connections could not be acquired from the underlying database!
at com.myproject.persistence.JdbcPropertyPlaceholderConfigurer.loadProperties(JdbcPropertyPlaceholderConfigurer.java:73)
at org.springframework.core.io.support.PropertiesLoaderSupport.mergeProperties(PropertiesLoaderSupport.java:161)
at org.springframework.beans.factory.config.PropertyResourceConfigurer.postProcessBeanFactory(PropertyResourceConfigurer.java:78)
... 36 more
Caused by: org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC Connection; nested exception is java.sql.SQLException: Connections could not be acquired from the underlying database!
at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:80)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:382)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:456)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:460)
at com.myproject.persistence.JdbcPropertyPlaceholderConfigurer.loadProperties(JdbcPropertyPlaceholderConfigurer.java:57)
... 38 more
Caused by: java.sql.SQLException: Connections could not be acquired from the underlying database!
at com.mchange.v2.sql.SqlUtils.toSQLException(SqlUtils.java:106)
at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool.checkoutPooledConnection(C3P0PooledConnectionPool.java:529)
at com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource.getConnection(AbstractPoolBackedDataSource.java:128)
at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:111)
at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:77)
... 42 more
Caused by: com.mchange.v2.resourcepool.CannotAcquireResourceException: A ResourcePool could not acquire a resource from its primary factory or source.
at com.mchange.v2.resourcepool.BasicResourcePool.awaitAvailable(BasicResourcePool.java:1319)
at com.mchange.v2.resourcepool.BasicResourcePool.prelimCheckoutResource(BasicResourcePool.java:557)
at com.mchange.v2.resourcepool.BasicResourcePool.checkoutResource(BasicResourcePool.java:477)
at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool.checkoutPooledConnection(C3P0PooledConnectionPool.java:525)
... 45 more
Ich glaub die Bean "dataSource" gibts zu dem Zeitpunkt noch gar nicht?
Davon würde ich ausgehen. Die Properties werden in der Initialisierungsphase gesetzt. Da kann man mit den Beans natürlich noch nicht arbeiten. Regel den Zugriff direkt, ohne Springbeans, die gerade erst mal initialisiert sind.
Davon würde ich ausgehen. Die Properties werden in der Initialisierungsphase gesetzt. Da kann man mit den Beans natürlich noch nicht arbeiten. Regel den Zugriff direkt, ohne Springbeans, die gerade erst mal initialisiert sind.
Das Problem liegt hierbei aber dass die Datenbank Sachen (url,driver,user,pwd) in einem separaten .properties File liegen und auf selbiges kann ich aber, zu dem Zeitpunkt, anscheinend auch noch nicht zugreifen. Hatte folgendes probiert:
Ok bin wohl ein wenig durcheinander gekommen. Oben extende ich ja von PropertyPlaceholderConfigurer und versuche dann selbige Bean dem PropertyPlaceholderConfigurer hinzuzufügen - kann nicht funktionieren.
Was ist nun die bessere Herangehensweise, soll ich quasi PropertyPlaceholderConfigurer überschreiben (wie soll ich das umsetzen, will ja paar properties aus der DB und ein paar von anderen .properties Dateien; weiters sollen die geladenen Properties natürlich in der applicationContext.xml schon verfügbar sein damit mir die Platzhalter "${xyz}" überschrieben werden.
Oder soll ich versuchen dem PropertyPlaceholderConfigurer einfach meine Klasse, welche die properties aus der DB holt, unter locations hinzuzufügen? Nur wovon muss da meiner Klasse erben?
Prinzipiell kannst du glaube ich beides machen. Ich denke du kannst mehrere PlaceholderConfigurer anbieten, die dann der Reihe nach ihre Arbeit verrichten. So lange die dort hinterlegten Properties disjunkt sind, ist das gar kein Thema, sonst ersetzt halt der erste.
Aber du kannst auch mit einer Ableitung dafür sorgen, dass ein Configurer alle Properties aus verschiedenen Quellen ersetzt.
Könntest du mal bitte bissl konkreter werden, ich stehe hier einfach an. Oben genannter Code funktioniert einfach nicht..
Du meinst ich kann einfach den bisherigen PlaceholderConfigurer so lassen und darunter einfach noch einen (Also eine weitere bean) definieren welcher dann mein JdbcPlaceholderConfigurer ist? Den anderen Weg schaffe ich nicht weil ich nicht weiß von welcher Klasse ich ableiten muss damit der Compiler nicht meckert
<property name="properties">
<props>
<prop key="irgendeine.url">${irgendeine.url}</prop>
<!-- Hier gibt es dann ein Problem, und zwar wird dann ${irgendeine.url} als value herangezogen
und nicht der tatsächliche Wert welcher zuvor in JdbcPropertyPlaceholderConfigurer geladen wurde. Die properties aus den .properties werden erkannt. -->
</props>
</property>
</bean>[/XML]
Also mit oben genannter Konfiguration werden beide PlaceholderConfigurer durchlaufen, es wird auch alles schön aus der DB geladen nur wenn ich dann aus der Bean appProperties ein Property rausholen möchte welches aus der DB ist dann wird der Platzhalter retouniert und nicht der Wert, sprich der Platzhalter wird von Spring nicht überschrieben..
**EDIT**
Hab das Problem gefunden! Das PlaceholderPrefix habe ich im Konstruktor geändert auf "#", angesprochen habe ich es aber mit "$"..