Avatar billede hangaard Nybegynder
23. januar 2003 - 14:46 Der er 14 kommentarer og
1 løsning

Class.forName - klassen er fundet, får fejl når jeg bruger den

Hjælp!

Jeg er igang med at lave et taglib som skal kunne bruges i forskellige Java-projekter. Jeg gør brug af Struts til at hente nogle properties fra en property-fil. Hvis et projekt ikke understøtter Struts vil jeg bruge default-værdier i stedet for dem jeg ellers ville have fået fra property-filen. For at kunne styre dette bruger jeg følgende kode:

=== KODE =================================
01 try {
02  Class.forName("org.apache.struts.util.MessageResources");
03  org.apache.struts.util.MessageResources messages = org.apache.struts.util.MessageResources.getMessageResources("dk.tdc.c3utils.properties.language");
04
05  this.mondayShortname = messages.getMessage("mondayShortname");
  .
  .
  .
06  this.januaryName = messages.getMessage("januaryName");
  .
  .
  .
07 } catch(ClassNotFoundException e) {
08  System.out.println("Klasse IKKE fundet");
09  // Brug default-værdier
10}
=== KODE SLUT ============================

Når jeg kører en JSP-side som bruger tagget får jeg en intern server fejl som siger noget med:
java.lang.NoClassDefFoundError: org/apache/struts/util/MessageResources

Ved at udkommentere linie 3 til og med 6 kan jeg konfirmere at Class.forname har smidt en ClassNotFoundException og catch-koden er blevet udført. Derfor må det være linie 3 som giver fejlen - men hvorfor?, da jeg jo forinden har konstateret at klassen findes.

Jeg håber I kan hjælpe mig!

Mvh.
Hangaard
Avatar billede di8leva Nybegynder
23. januar 2003 - 14:52 #1
det er ikke fordi du skal indsette:

<%@ page import="org.apache.struts.util.MessageResources" %>

??
Avatar billede arne_v Ekspert
23. januar 2003 - 14:53 #2
Jeg kan ikke følge din logik.

"Ved at udkommentere linie 3 til og med 6 kan jeg konfirmere at Class.forname har smidt en ClassNotFoundException og catch-koden er blevet udført"

og

"Derfor må det være linie 3 som giver fejlen"

passer da ikke sammen !?!?
Avatar billede di8leva Nybegynder
23. januar 2003 - 14:55 #3
nej det var fejl
glem det....
Avatar billede arne_v Ekspert
23. januar 2003 - 14:55 #4
Umiddelbart lyder det som den jar-fil hvori klassen er defineret
ikke er i classpath for den web-applikation der eksekveres.
Avatar billede arne_v Ekspert
23. januar 2003 - 14:58 #5
Den skal enten være i serverens lib eller i den pågældende
web-applikations lib.
Avatar billede hangaard Nybegynder
23. januar 2003 - 15:02 #6
Jeg har testet koden hvor jeg har undladt at instantiere MessageResources (linie 3), og her får jeg ingen fejl. Samtidig bliver catch-koden udført.
Når jeg så tester koden hvor jeg bruger MessageResources (linie 3) får jeg fejlen og catch-koden når ikke at blive kørt.
Derfor må det være i linie 3 at jeg får min NoClassDefFoundError.
Avatar billede hangaard Nybegynder
23. januar 2003 - 15:04 #7
JAR-filen er med; den kode som giver fejl findes i JAR-filen.
Avatar billede arne_v Ekspert
23. januar 2003 - 15:40 #8
Øh - er din kode og org.apache.struts klasserne i samme jar-fil ??
Avatar billede arne_v Ekspert
23. januar 2003 - 15:59 #9
Og hvordan skal "og her får jeg ingen fejl. Samtidig bliver catch-koden udført"
forståes !?!?

Catch koden bliver kun udført, hvis der sker en fejl.
Avatar billede soelvpil Nybegynder
24. januar 2003 - 19:52 #10
Problemet er, at din kode verificeres, inden den udføres. Her dumper den, fordi den refererer til ukendte klasser.

Så din webcontainer opdager, at "det her kode virker ikke, det burde slet ikke have kunnet kompilere", og nægter at udføre noget af det.

Så det vil heller ikke virke at rette din catch til catch(Throwable e)

I stedet er du nødt til at bruge reflection.

Jeg har ikke checket nedenstående kode, så den virker nok ikke 100%, men ideen er god nok, du får dog brug for at importere java.lang.ref.*:

try {
String className = "org.apache.struts.util.MessageResources";
Class clazz = Class.forName(className);
String methodName = "getMessageRessources";
Class[] argumentTypes = {String.class};
Method method = clazz.getMethod(methodName,argumentTypes);
String ressourcesKey = "dk.tdc.c3utils.properties.language";
Object[] args = {ressourcesKey};
Object messages = method.invoke(null, args);
Class messageClass = messages.getClass();
String name = "getMessage";
Class[] argTypes2 = {String.class};
Method getMessageMethod = messageClass.getMethod(name,argTypes2);
this.mondayShortname = (String)getMessageMethod.invoke(messages,{"mondayShortname"});
this.januaryName = (String)getMessageMethod.invoke(messages,{"januaryName"});
}
catch (Exception e) {
  e.printStackTrace();
}
Avatar billede soelvpil Nybegynder
24. januar 2003 - 19:58 #11
p.s. Hvis jeg var dig, ville jeg stadig hente værdierne fra property-filen, også uden struts, i stedet for at benytte defaultværdier.
Avatar billede soelvpil Nybegynder
24. januar 2003 - 20:07 #12
Hvis du skal benytte dine ressourcer andre steder, end lige i denne klasse, burde du måske overveje om ikke man kunne finde et smart design, så din jsp-side er ldeles uvidende om, om den får sine værdier fra struts, eller fra default-værdier...
Avatar billede hangaard Nybegynder
03. februar 2003 - 14:01 #13
Hej soelvpil,

Jeg er lige kommet hjem fra skiferie, så derfor har jeg ikke reageret på dine indlæg. Det varer lige nogle dage før jeg skal arbejde videre på mit projekt. Jeg vil vende tilbage igen når jeg har afprøvet din kode. Tak for kommentarerne - jeg vil også kigge på det at bruge property-filer selvom struts ikke er tilstede.
Mvh.
hangaard
Avatar billede hangaard Nybegynder
11. februar 2003 - 13:18 #14
Hej soelvpil,
Så er jeg kommet igang med projektet igen. Jeg har ikke afprøvet din løsning, da jeg har valgt en helt anden fremgangsmåde; en proxy-klasse som kalder en Struts-handler klasse hvis Struts-klassen findes ellers kaldes en Property-klasse. De 2 klasser har begge en getValue-metode som på hver deres måde henter properties fra en property-fil (altså bruger jeg det råd du gav mig om ikke at bruge default-værdier).
Tak for hjælpen!

Mvh.
hangaard
Avatar billede soelvpil Nybegynder
11. februar 2003 - 19:38 #15
Det lyder som en god løsning, du har fundet (faktisk var det noget i den retning jeg forestillede mig med bemærkningen om et smart design, så jsp'en var uvidende om eksistensen af struts eller ej).
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester