Property-Datei in Stateless-Bean laden

Status
Nicht offen für weitere Antworten.

Fenixx

Aktives Mitglied
Hi zusammen,

ich möchte gerne in einer @Stateless-Bean Property-Dateien, die auf dem Server liegen, gerne auslesen. An ein geeignetes Format dachte ich an XML.
Die Methodendeklaration sollte so aussehen:
Java:
//Der Pfad inkl. Dateiname wird übergeben
public HashMap<String, String> readProperty(String path)
{
//Liest die XML nach den vorkommenden Tags (Schlüssel) und die dazugehörige Information aus
//Wegschreiben in eine HashMap
}

Problematisch sehe ich bei einer @Stateless-Bean, dass ich mir mit dem Pfad nie sicher sein kann, wo ich mich bereits befinde, oder täusch ich mich da?

Gruß
Fenixx
 

HoaX

Top Contributor
Ich sehe da jetz keinen zusammenhang zum Stateless-Bean. Da ich nicht davon ausgehe, dass über die Methode jede beliebige Datei eingelesen werden darf kannst du ja im Code ein Basisverzeichnis definieren und den übergebenen Pfad anhängen, fertig ist der absolute Pfad.
 
M

maki

Gast
Wenn die Property Datei im classpath liegt dann brauchst du keinen absoluten Pfad.
[c]java.io.File[/c] sollte man in AppServern sowieso nicht verwenden.

*verschoben*
 

Fenixx

Aktives Mitglied
Es wird nur ein lesender Zugriff benötigt. Das sollte selbst im Clusterbetrieb funktionieren.
Meine Projektstruktur sieht so aus:
Java:
EJB-Projekt
- src
   - main
      - java
        - com
           -meinpackage
             - MeineEJB
      -resources
         -META-INF
            - MeineXml.xml



Dazu hab ich in meinerEJB folgende Methode gebaut:
Java:
public InputStream loadResourceAsStream(Class rClass, String rsResource)
  {
    ClassLoader cl = rClass.getClassLoader();
    return cl.getResourceAsStream(rsResource);
  }

Der Aufruf:
Java:
loadResourceAsStream(this.getClass(), "MeineXML.xml");

Hier der Fehler:
Java:
Caused by: java.net.MalformedURLException
	at java.net.URL.<init>(URL.java:601)
	at java.net.URL.<init>(URL.java:464)
	at java.net.URL.<init>(URL.java:413)
	at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.setupCurrentEntity(XMLEntityManager.java:650)
	at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.startEntity(XMLEntityManager.java:1315)
	at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.startDocumentEntity(XMLEntityManager.java:1267)
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.setInputSource(XMLDocumentScannerImpl.java:281)
	at com.sun.org.apache.xerces.internal.impl.XMLStreamReaderImpl.setInputSource(XMLStreamReaderImpl.java:204)
	... 5 more

Muss man da etwa noch Ordnerstrukturen hochgehen oder wie sieht das aus?
 
Zuletzt bearbeitet:

FArt

Top Contributor
Vielleicht hat sich das noch nicht rumgesprochen, aber Filezugriffe in einer Enterpriseumgebung (EJB) sind laut Spec verboten. Workarounds dazu anzubieten ist eine mehr als suboptimal und keine Lösung!
Properties kann man über den Klassenpfad einlesen, wenn nötig.

Ich schlage trotzdem vor, Konfigurationen nicht über Properties zu lösen. Konfiguriere dein Bean über den Deploymentdeskriptor oder über einen Service (JBoss z.B. bietet einen Properties-Service).

Die Frage ist wie immer: was willst du erreichen und in welcher Umgebung? Dann kann dir geholfen werden...
 

Fenixx

Aktives Mitglied
Ziel ist Konfigurationseinstellungen wie z.B. Serveradresse zum Berechtigungssystem, Benutzername und Passwort etc. in eine eigens dafür eingerichtete Configdatei wie z.B. XML auszulagern. Dies haben wir vorläufig in dem Code hartkodiert.
Das ist natürlich alles andere als optimal.
Ich muss also in meiner Bean auf irgendeine Art und Weise auf diese Konfigurationseinstellungen zugreifen können, damit der Benutzer beispielsweise auf die Authorisierung überprüft werden kann.
Meine Idee war nun: Den Pfad dynamisch zur Laufzeit auslesen zu können, damit das Projekt später flexibel deployed werden kann.
Ich hatte zunächst auch Bedenken und war mir des Problems schon vorher bewusst.
Dennoch kenne ich keine "optimale" Lösung in dem Fall und war der Überzeugung, dass die Datei in dem Webprojekt auf allen Servern zur Verfügung steht und deshalb das Problem mit den I/O-Operationen laut Spec in den Griff zu kriegen ist.
Ich habe noch gefunden, dass man das auch mit einem Servlet bewerkstelligen kann.

Meine Fragen hierzu: Ist das die "optimale" Lösung? Wenn ja: Wie kann ich in einer Bean auf ein Servlet zugreifen? (Den umgekehrten Weg habe ich in einem anderen Zusammenhang bereits erfolgreich gelöst).
Andernfalls: Wie kann man die Bean über den Deploymentdeskriptor konfigurieren? Ich selbst verwende den Glassfish.
 

FArt

Top Contributor
Wenn die Konfiguration über eine XML Datei (oder Properties-Datei) passieren soll, kann beides über den Classloader geladen werden, wenn die Datei mit depoyt ist. ( Thread.currentThread().getContextClassLoader().getResoruceAsStream() )

Wenn aber EJBs konfiguriert werden sollen, dann würde ich sofort die Werte in den Deploymentdeskriptor des Beans aufnehmen. Siehe J2EE Spec 5.2.1.2 - Declaring of Environmen Entries

Siehe auch: Making EJBs Flexible with Environment Entries

Auch eine ordentliche Lösung: einen Konfigurationsdienst (z.B. eine simple Hashmap) ins JNDI einhängen. Das EJB holt sich die Map und hat schon seine Konfigurationswerte.
 

Fenixx

Aktives Mitglied
Ich hatte dein gepostetes Beispiel ausgetestet, leider ohne Erfolg. Der ausgelesene Wert ist null. Hier mein Code (ich arbeite auf dem Glassfish):

In der Bean:
Java:
@Stateless
public class ConfigSettingServiceBean implements ConfigSettingService
{
  public String getCompanyName()
  {
    String companyName = null;
    try
    {
        // Get naming context.
        Context ictx = new InitialContext();
        Context env = (Context) ictx.lookup("java:comp/env");
        // Get company name
        companyName = (String)env.lookup("companyName");
    }
    catch (Exception e)
    {
    }
    return companyName;
  }
}

Hier der Eintrag von der web.xml:

Code:
  <env-entry>
            <description>
            The name of your company.
            </description>
            <env-entry-name>companyName</env-entry-name>
            <env-entry-type>java.lang.String</env-entry-type>
            <env-entry-value>Acme Explosives</env-entry-value>
  </env-entry>

Es gibt bei mir keine Exception. Lediglich der übergebene Wert(companyName) ist null.
Weißt du vielleicht woran das liegen könnte?

Gruß
 

Fenixx

Aktives Mitglied
Ich habs jetzt in der ejb-jar.xml reingepackt und die entsprechenden Strings mit @Resource annotiert. Funktioniert super.
 
Status
Nicht offen für weitere Antworten.

Ähnliche Java Themen

Neue Themen


Oben