Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[Server] finde Dateien unter Tomcat nicht.

2 views
Skip to first unread message

Frank Linden

unread,
Oct 11, 2002, 4:10:12 AM10/11/02
to
Liebes Dr.Sommer-Team,

in einem Servlet muss ich eine spezielle PCI-Karte ansprechen, die
Klassen dafuer bestehen bereits. Leider werden im Servlet die
Konfigurationsdateien nicht gefunden ("crbi000.h" und "crgukbf.h").
Kann mir jemand anhand des unten aufgefuehrten Codeschnipsels sagen,
wohin ich die packen muss, damit sie eingelesen werden koennen? Leider
habe ich auf diesen Code nur marginalen Einfluss, ich musste schon
betteln um mir den System.exit mal auskommentieren zu lassen.
Alles, was zum Kartenansprechen benoetigt wird liegt in einem JAR-file
unter libs, die Klassen werden dort gefunden, die Konfigurationsfiles
aber nicht (was als Application jedoch funktioniert). Ich habe die
beiden Files auch schon unter entsprechendem Pfad unter classes
kopiert, funktionierte leider auch nicht. In der FAQ habe ich leider
nichts dazu gefunden und ergoogeln konnte ich mir auch nichts
passendes.

schoenen Dank und ein ebensolches Wochenende,
Frank

Konfig.: Win 2k, Tomcat 4.0.3, JRE 1.3.1

Fehlermeldung:
java.lang.NullPointerException
at java.io.Reader.<init>(Reader.java:64)
at java.io.InputStreamReader.<init>(InputStreamReader.java:89)
at java.io.InputStreamReader.<init>(InputStreamReader.java:61)
at gno.scg.kbm.enums.KBFEnum.<clinit>(KBFEnum.java:41)
[...]

Zeile 41:
r = new BufferedReader(new InputStreamReader(is));


*** KBFEnum.java schnipp ***

private static InputStream is;
private static InputStream is1;
private static Reader r;
private static Reader r1;
private static StreamTokenizer st;
private static StreamTokenizer st1;

private static String fileName = "crbi000.h";
private static String fileName1 = "crgukbf.h";
private static String kbfPath = "/gno/scs/kbm/";
private static String s;

ResourceBundle rb = ResourceBundle.getBundle("gno.scs.kbm.KbfEnum");


static {
try {
Class kbf = Class.forName("java.lang.Object");
is = kbf.getResourceAsStream(kbfPath + fileName);
is1 = kbf.getResourceAsStream(kbfPath + fileName1);
--> r = new BufferedReader(new InputStreamReader(is)); <--
r1 = new BufferedReader(new InputStreamReader(is1));
st = new StreamTokenizer(r);
st1 = new StreamTokenizer(r1);
}
catch (Exception e) {
e.printStackTrace();
System.exit(-1);
}

*** KBFEnum schnapp ***

Patrick Roemer

unread,
Oct 11, 2002, 4:26:37 AM10/11/02
to
Hallo,

Frank Linden wrote:

> private static String kbfPath = "/gno/scs/kbm/";

[...]


> Class kbf = Class.forName("java.lang.Object");
> is = kbf.getResourceAsStream(kbfPath + fileName);

getResourceAsStream() liefert Ressourcen relativ zu den Wurzeln
des Classpath. amit obiges funktioniert, muesste die Datei z.B.
in $WEBAPP_HOME/WEB-INF/classes//gno/scs/kbm liegen.

Da Du ja offensichtlich den absoluten Pfad zur Datei kennst, kannst
Du direkt einen FileReader darauf ansetzen. Dann wuerde ich den Pfad
allerdings nicht fest verdrahten, sondern z.B. als Parameter aus der
web.xml auslesen.

Ansonsten kannst Du das obige Verfahren nutzen und die Datei irgendwo
im Classpath ablegen; oder Du legst sie unterhalb deiner Webapp-Root
ab und nutzt die entsprechenden Methoden aus ServletContext
(getRealPath(), getResource() oder getResourceAsStream()).

Viele Gruesse,
Patrick

Matthias Piehl

unread,
Oct 11, 2002, 7:01:59 AM10/11/02
to
Hallo
-----

>im Classpath ablegen; oder Du legst sie unterhalb deiner Webapp-Root
> ab und nutzt die entsprechenden Methoden aus ServletContext
> (getRealPath(), getResource() oder getResourceAsStream()).
Die Sache mit dem getRealPath() ist sehr brauchbar!

Am besten man legt solche Dateien unter das WEB-INF Verseichnis zum Beispiel
in ein spezielles Verzeichnis (z. B. "/WEB-INF/div").
Der Vorteil ist der, daß man dann nicht mit dem Browser auf solche Dateien
zugreifen kann und mal eben die konfigurationen im klartext durchlesen kann.

Das geht auch bei include Dateien!

Beispiel:
String sPath = config.getServletContext().getRealPath("/") +
"WEB-INF" + File.separator + "div" + File.separator + "myfile.conf";
oder
<%@ include file="/WEB-INF/include/maininclude.jsp" %>

Bis dann also ..............
Matthias


Frank Linden

unread,
Oct 12, 2002, 8:50:49 AM10/12/02
to
Matthias Piehl & Patrick Roemer wrote:

[nuetzlich Tips]

>>im Classpath ablegen; oder Du legst sie unterhalb deiner Webapp-Root
>> ab und nutzt die entsprechenden Methoden aus ServletContext
>> (getRealPath(), getResource() oder getResourceAsStream()).
> Die Sache mit dem getRealPath() ist sehr brauchbar!


Erst einmal Danke fuer Eure Antworten, aber ich habe mich wohl etwas unklar
ausgedrueckt. Auf den Code habe ich naemlich kaum Einfluss, da ich die
Klassen in meinem Servlet benutzen muss. An getRealPath() habe ich auch
schon gedacht, es waere mir allerdings viel lieber, wenn ich die Klassen
unveraendert lassen koennte und dafuer die Konfigurationsfiles in
vielleicht ungewoehliche Orte schieben muss.


>> getResourceAsStream() liefert Ressourcen relativ zu den Wurzeln
>> des Classpath. amit obiges funktioniert, muesste die Datei z.B.
>> in $WEBAPP_HOME/WEB-INF/classes//gno/scs/kbm liegen.

Ich bin mir ziemlich sicher, dass ich dies schon ohne Erfolg ausprobiert
habe, werde mich am Montag aber sofort noch einmal dransetzen.


schoenen Gruss,
Frank

Patrick Roemer

unread,
Oct 12, 2002, 9:53:07 AM10/12/02
to
Hallo,

Frank Linden wrote:

>>>getResourceAsStream() liefert Ressourcen relativ zu den Wurzeln
>>>des Classpath. amit obiges funktioniert, muesste die Datei z.B.
>>>in $WEBAPP_HOME/WEB-INF/classes//gno/scs/kbm liegen.
>
> Ich bin mir ziemlich sicher, dass ich dies schon ohne Erfolg ausprobiert
> habe, werde mich am Montag aber sofort noch einmal dransetzen.

Das haengt auch davon ab, wo diese Klassen liegen - da hatten wir
gerade erst einen Thread zu:

http://groups.google.com/groups?threadm=3DA007AE.7040105%40peuss.de&rnum=1

Wenn die Klassen im classes oder lib der Webapp liegen, sollte es
das eigentlich tun.

Das ist aber wirklich bestenfalls als Workaround zu betrachten.
Ich wuerde eher dazu tendieren, den Fremdcode zu sanieren. Frueher
oder spaeter faellt einem dieses Konstrukt sicher auf den Fuss.

Viele Gruesse,
Patrick

Frank Linden

unread,
Oct 14, 2002, 8:05:18 AM10/14/02
to
Patrick Roemer <sang...@t-online.de> wrote in message news:<ao99ho$jg8$02$1


> Wenn die Klassen im classes oder lib der Webapp liegen, sollte es
> das eigentlich tun.


Seufz. Ich hab jetzt nochmal alles versucht, und sie scheinen nirgends
gefunden zu werden. Mein Baum unter Tomcat sieht folgendermassen aus:

+---bin
+---classes
+---common
+---conf
+---gno
+---lib
+---logs
+---server
+---webapps
| +---examples
| +---formsign
| | +---com
| | +---formsign
| | +---gno
| | +---javax
| | +---opencard
| | \---WEB-INF
| | +---classes
| | | +---formsign
| | | \---gno
| | | \---scg
| | | \---kbm
* * crbi000.h
* * crgukbf.h
| | \---lib
* * KBFPROVIDER.JAR
| | \---gno
| | \---scg
| | \---kbm
* * crbi000.h
* * crgukbf.h


Die Dateien liegen also in classes, lib und im JAR, dass in lib liegt.
So langsam gehen mir dann aber leider die Ideen aus.


> Das ist aber wirklich bestenfalls als Workaround zu betrachten.
> Ich wuerde eher dazu tendieren, den Fremdcode zu sanieren. Frueher
> oder spaeter faellt einem dieses Konstrukt sicher auf den Fuss.

Mit einem Workaround waere ich schon mehr als zufrieden. Auf den Fuss
fiele das dann den Leuten, die den Fremdcode entsprechend anpassen
koennten. Nur die koennen auch eigentlich dran rumfummeln, da die
Funktion in diversen Applications natuerlich auch noch gewaehrleistet
sein muss. Dafuer scheint mir "getRealPath()" dann auch nicht
unbedingt als naheliegenste Moeglichkeit.

Kann es vielleicht sein, dass ich noch irgend eine XML-Datei anpassen
muss bzw. grundlegene Konfigurationen vernudelt habe? Es hat damals ne
Zeit gedauert, ehe ich mein erstes Serlvet nach meinen Wuenschen zum
Laufen bekommen habe.

Frank

Matthias Piehl

unread,
Oct 14, 2002, 8:58:02 AM10/14/02
to
Hallo
------

> | | \---WEB-INF
> | | +---classes
> | | | +---formsign
> | | | \---gno
> | | | \---scg
> | | | \---kbm
> * * crbi000.h
> * * crgukbf.h
Äh ... wenn das deine Struktur ist, dann ist "/gno/scs/kbm" möglicher Weise
in der Tat nicht ausreichend.
Da fehlt dann formsign meine ich.
Eventuell solltest du auch nur an einer Stelle deine Klassen anbieten (also
ohne lib).

Dann noch die Frage:
Was steht überhaupt in der crbi000.h und in der crgukbf.h die deuten fast
auf Headerdateien bei c hin.
Eventuell kann man nicht per = kbf.getResourceAsStream(kbfPath + fileName);
etwas sinnvolles lesen.
Dann wäre klar, das der Folgebefehl probleme macht.

--

Matthias Piehl

unread,
Oct 14, 2002, 9:04:04 AM10/14/02
to
HI
--
Noch was: Hast Du das Ganze mal in einer "normalen" Java-Application
ausprobiert?

Wenn es da geht, dann sollte es auch in einer Web-App gehen.

Patrick Roemer

unread,
Oct 14, 2002, 9:25:24 AM10/14/02
to
Hallo,

Frank Linden wrote:

> Seufz. Ich hab jetzt nochmal alles versucht, und sie scheinen nirgends
> gefunden zu werden. Mein Baum unter Tomcat sieht folgendermassen aus:

> +---webapps
> | +---formsign
> | | \---WEB-INF
> | | \---lib
> * * KBFPROVIDER.JAR

...und in diesem Jar befindet sich die Klasse, innerhalb derer
Class.forName() aufgerufen wird? Und sonst nirgendwo (nicht im
statischen Classpath, in common/lib, etc.)?

> Die Dateien liegen also in classes, lib und im JAR, dass in lib liegt.
> So langsam gehen mir dann aber leider die Ideen aus.

Was ist denn mit Matthias' Vorschlag: Funktioniert es auch in
einer Standalone-App? Wenn ja, hangele Dich einfach mal die
Tomcat-Classloaderhierarchie entlang und lege die Klassen und
die Konfigurationsdateien an den entsprechenden Stellen ab:

http://jakarta.apache.org/tomcat/tomcat-4.1-doc/class-loader-howto.html

> Mit einem Workaround waere ich schon mehr als zufrieden. Auf den Fuss
> fiele das dann den Leuten, die den Fremdcode entsprechend anpassen
> koennten. Nur die koennen auch eigentlich dran rumfummeln, da die
> Funktion in diversen Applications natuerlich auch noch gewaehrleistet
> sein muss. Dafuer scheint mir "getRealPath()" dann auch nicht
> unbedingt als naheliegenste Moeglichkeit.

Vollkommen egal. Idealerweise sollte die Klasse ein Properties-
oder ResourceBundle- oder meinetwegen auch ein URL-Objekt ueber-
geben bekommen und sich nicht drum kuemmern, wo es herkommt. Dann
koennte man sie im Tomcat problemlos mit dem Resultat eines
getRealPath() initialisieren.

Wenn Du diesen Umbau scheust, solltest Du ueberlegen, wenigstens
den Kontext-CL zu verwenden, wie im vom mir angegebenen Thread em-
pfohlen.

Viele Gruesse,
Patrick

Frank Linden

unread,
Oct 15, 2002, 6:38:45 AM10/15/02
to
Ich habe mal einfach alle Antworten hier zusammen verwurschtelt, man
moege mir bitte verzeihen.


> Äh ... wenn das deine Struktur ist, dann ist "/gno/scs/kbm" möglicher Weise
> in der Tat nicht ausreichend. Da fehlt dann formsign meine ich.
> Eventuell solltest du auch nur an einer Stelle deine Klassen anbieten (also
> ohne lib).

Die Darstellnung war nicht so gluecklich glaube ich.
In folgenden Plaetzen waren die beiden Dateien zu finden, und zwar
jeweils aussschliesslich (also alle andern geloescht):

\Apache Tomcat 4.0\common\lib\gno\scg\kbm\crbi000.h
\Apache Tomcat 4.0\common\classes\gno\scg\kbm\crbi000.h
\Apache Tomcat 4.0\webapps\formsign\gno\scg\kbm\crbi000.h
\Apache Tomcat 4.0\webapps\formsign\WEB-INF\lib\gno\scg\kbm\crbi000.h
\Apache Tomcat 4.0\webapps\formsign\WEB-INF\classes\gno\scg\kbm\crbi000.h
\Apache[...]\webapps\formsign\WEB-INF\classes\formsign\gno\scg\kbm\crbi000.h

und dann noch KBFProvider.jar in
\Apache Tomcat 4.0\webapps\formsign\WEB-INF\lib


> [...] die deuten fast auf Headerdateien bei c hin.


> Eventuell kann man nicht per = kbf.getResourceAsStream(kbfPath + fileName);
> etwas sinnvolles lesen.

Es ist wohl richtig, dass die h-Dateien C-Header sind. Das Konstrukt
hat schon bei diversen Applications funktioniert.


> Wenn Du diesen Umbau scheust, solltest Du ueberlegen, wenigstens

> den Kontext-CL zu verwenden, wie im vom mir angegebenen Thread empfohlen.

Oh je, habe jetzt
Class.forName("java.lang.Object")
durch
Thread.currentThread().getContextClassLoader.loadClass("java.lang.Object")
ersetzen lassen, leider mit gleichem Ergebnis.


Das Tomcat Classloader HowTo hat mich auch nicht wirklich
weitergebracht, danach haette es schon laengst gefunden werden
muessen. Ich weiss, dass ich ein schwieriges Problem bin, weil ich
keine neuen Informationen bringen kann. Aber ich bastel da jetzt schon
Tage dran rum, ohne auch nur einen Schritt weiterzukommen. Ich seh
zwar ein, dass Class.forName nicht geschickt waere, aber selbst dieses
eher schlechte Konstrukt haette in meinem Fall ja funktionieren
muessen, wenn ich
http://groups.google.com/groups?threadm=3DA007AE.7040105%40peuss.de&rnum=1
richtig interpretiert habe.

Bin fuer jede Idee offen, werde mich jetzt nochmal auf der
Tomcat-Seite umschauen, ob ein upgrade auf 4.1 helfen koennte.

Frank

Matthias Ernst

unread,
Oct 15, 2002, 6:48:59 AM10/15/02
to
Frank Linden wrote:


> Oh je, habe jetzt
> Class.forName("java.lang.Object")
> durch
>
Thread.currentThread().getContextClassLoader.loadClass("java.lang.Object")
> ersetzen lassen, leider mit gleichem Ergebnis.

Das ist das Problem.

Egal, welchen ClassLoader Du benutzt, java.lang.Object wird durch den
Bootstrap-Classloader geladen und liegt in rt.jar. Deshalb wird Deine
Ressource auch in rt.jar gesucht. Das willst Du nicht.

Nimm lieber Deine eigene Klasse, dann werden die Files auch in den jars in
lib/ und im Directory classes/ gesucht.

static {
...
gno.scg.kbm.enums.KBFEnum.class.getResourceAsStream("/gno/scs/kbm/crbi000.h");
...
}

Matthias

Patrick Roemer

unread,
Oct 15, 2002, 7:19:07 AM10/15/02
to
Hallo,

Frank Linden wrote:

>>Wenn Du diesen Umbau scheust, solltest Du ueberlegen, wenigstens
>>den Kontext-CL zu verwenden, wie im vom mir angegebenen Thread empfohlen.
>
> Oh je, habe jetzt
> Class.forName("java.lang.Object")
> durch
> Thread.currentThread().getContextClassLoader.loadClass("java.lang.Object")
> ersetzen lassen, leider mit gleichem Ergebnis.

Ich dachte eher an

Thread.currentThread().getContextClassLoader().getResourceAsStream("...");

ohne den Umweg ueber ein Klassenobjekt.

Viele Gruesse,
Patrick

Frank Linden

unread,
Oct 17, 2002, 11:22:34 AM10/17/02
to
Patrick Roemer wrote in message news:<3DABF9AB...@imagine.de>...


> Thread.currentThread().getContextClassLoader().getResourceAsStream("...");
> ohne den Umweg ueber ein Klassenobjekt.

Das habe ich versucht, leider auch ergebnislos. Matthias Vorschlag hat
aber Gott sein dank funktioniert, aber auch Dir danke fuer die
Bemuehungen.

Frank

Frank Linden

unread,
Oct 17, 2002, 11:26:48 AM10/17/02
to
Matthias Ernst in news:<aogrqr$mch74$1...@ID-133822.news.dfncis.de>:


> Nimm lieber Deine eigene Klasse, dann werden die Files auch in den jars in
> lib/ und im Directory classes/ gesucht.
>

> gno.scg.kbm.enums.KBFEnum.class.getResourceAsStream("/gno/scs/kbm/crbi000.h");

BINGO. Das wars. Herzlichen Dank!
Jetzt muss ich mich nur noch mit ein paar anderen Files rumschlagen,
die nicht gefunden werden, aber dank Euch hab ich jetzt auch ne Ecke
mehr Einblick.

frohes Schaffen!
Frank

0 new messages