"We are back" « oc.at

[Java] Denkfehler bei static-Variablen?

prayerslayer 27.03.2008 - 09:36 1543 12
Posts

prayerslayer

Oar. Mh.
Avatar
Registered: Sep 2004
Location: vorm Sucher
Posts: 4073
jaa, ich bins wieder :D

so. zuerst - als es nur eine mögliche DB für mein java-prog gab - hab ich die die verbindungsdaten (db-name, server, user, pw...) in eine eigene klasse DBConfig geschrieben. das hat so ausgesehen:

Code: PHP
public static final String DB_NAME="JSTW";
public static final String DB_USER = "NIKP";
public static final String DB_SERVER = "XNIKP";
public static final String DB_URL = "jtds:jdbc:sqlserver://";

und wenn ich eine connection gebraucht habe, hab ich einfach die attribute hergenommen, hat super funktioniert.

jetzt bin ich draufgekommen, dass es schon nice wäre, wenn man das ändern könnte *g* ich schreib also die zugangsdaten in eine xml-datei, les diese aus, bevor eine verbindung zur DB benötigt wird und _überschreibe_ gewisse attribute in der DBConfig (bei denen ich dann natürlich das final weggelassen hab).

Code: PHP
public static String DB_NAME="JSTW";
public static String DB_USER = "NIKP";
public static String DB_SERVER = "XNIKP";
public static final String DB_URL = "jtds:jdbc:sqlserver://";

beim laden hab ich dann:

Code: PHP
Document doc = builder.parse(xmlFile);
DBConfig.DB_SERVER = doc.getElementsByTagName("db-server").item(0).getTextContent();

und so weiter.

irgendwann rufe ich dann eine funktion in der klasse DBAccess auf
Code: PHP
DBAccess.checkIfUserExists(username);

die sich eine connection aus dem pool holt.
Code: PHP
Connection knexon = dbpool.getConnection();

nur scheint das programm das überschreiben zu ignorieren :eek: hab ich einen denkfehler was static-variablen betrifft oder passt was anderes nicht? gibt's eventuell eine bessere lösung, die hier kommt mir ein wenig gepfuscht vor... :(

tia!
Bearbeitet von prayerslayer am 27.03.2008, 12:00

Triple-X

Addicted
Avatar
Registered: Feb 2001
Location: Pregarten (OÖ)
Posts: 485
Wenn ich das hier (http://java.sun.com/docs/books/jls/....doc.html#10931) richtig verstehe, dann darf einer final Variable nur einmal ein wert zugewiesen werden.

Und du weist ja schon bei der Definition der Variable einen Wert zu.

Ich hoffe ich habe jetzt keinen kompletten Blödsinn geschrieben :)

prayerslayer

Oar. Mh.
Avatar
Registered: Sep 2004
Location: vorm Sucher
Posts: 4073
Zitat von Triple-X
Wenn ich das hier (http://java.sun.com/docs/books/jls/....doc.html#10931) richtig verstehe, dann darf einer final Variable nur einmal ein wert zugewiesen werden.

genau, das mach ich bei der deklaration und danach nie wieder ;)

gibt übrigens ein update: das überschreiben von den static-variablen funktioniert doch, aaber in meiner getConnection() funktion in der klasse fürs connection pooling (DBConnectionPool) nimmt er die alten werte. OBWOHL die funktion erst NACH dem überschreiben aufgerufen wird.

irgendwas grobes passt da nicht, aber ich hab weder eine lösung noch weiß ich, was :(

Nico

former person of interest
Registered: Sep 2006
Location: -
Posts: 4082
kriegst du denn keine fehlermeldung(en) ?

prayerslayer

Oar. Mh.
Avatar
Registered: Sep 2004
Location: vorm Sucher
Posts: 4073
nö, woher auch? es funktioniert ja, er nimmt nur die alten (quasi die standardwerte in der DBConfig) werte her, die ja die richtigen sind...

ich hab hier mal das wichtigste von den 3 DB-klassen gezippt. was im hauptprogramm passiert, steht eh im ersten post.

hth :(
db-files_121253.zip (downloaded 129x)
Bearbeitet von prayerslayer am 27.03.2008, 10:22

Nico

former person of interest
Registered: Sep 2006
Location: -
Posts: 4082
aso. na das programm verwendet ja die daten wie sie gesetzt wurden bevor du sie verwendest. wenn du den wert einer konstanten einer anderen konstanten zuweist bleibt ja die "alte" kopie auch wenn du die referenz (Klasse) veränderst.
does that help?

btw: wie schaut die datei auf wo du veränderst und aufrufst im ganzen?
Bearbeitet von Nico am 27.03.2008, 12:30

prayerslayer

Oar. Mh.
Avatar
Registered: Sep 2004
Location: vorm Sucher
Posts: 4073
Zitat von Nico
aso. na das programm verwendet ja die daten wie sie gesetzt wurden bevor du sie verwendest. wenn du den wert einer konstanten einer anderen konstanten zuweißt bleibt ja die "alte" kopie auch wenn du die referenz (Klasse) veränderst.
does that help?

habs jetzt 3x gelesen, aber verstehs nicht, sorry :) du meinst, dass das programm die standardwerte nimmt, OBWOHL die eine funktion, die NICHT static ist, erst NACH dem überschreiben der werte aufgerufen wird?

das hab ich auch schon gemerkt. aber wenn das normales verhalten ist, kann mir das wer erklären? für mich ist das derb unlogisch...

btw wenn wer eine best practice oder auch irgendeine andere funktionierende lösung anzubieten hat: her damit :)
Bearbeitet von prayerslayer am 27.03.2008, 11:10

gue

Addicted
Avatar
Registered: Feb 2003
Location: Linz
Posts: 400
Öhm rufst du zwischendurch zufällig releaseConnection() auf? Sprich du erzeugst ein paar Connections mit den alten Zugangsdaten, gibst sie wieder in den Pool und jetzt wunderst du dich, warum du mit getConnection() Connections mit den alten Daten kriegst? :D
Mein Tipp: Wenn du neue Konfigurationsdaten einliest, rufst du DBConnectionPool.getInstance().clear() auf, die folgendes macht:
Code:
public synchronized void clear() {
    // ... alle Connections schließen
    connections.clear();
}
...oder (was noch besser wäre): Du kübelst die statischen Felder von DBConfig und machst es zu einer Klasse mit gettern für DB-Name, etc. So ein Objekt könntest du dann an DBConnectionPool.setConfig(DBConfig newConfig) übergeben und erzeugt wird so ein DBConfig Objekt mit statischen Erzeugern, á la DBConfig config = DBConfig.getDefaultConfig() oder DBConfig newConfig = DBConfig.readConfig(Document doc); (dazu machst du den Konstruktor von DBConfig am besten private).
DBConnectionPool.setConfig kann dann (falls nötig) den Connection pool leeren etc.

prayerslayer

Oar. Mh.
Avatar
Registered: Sep 2004
Location: vorm Sucher
Posts: 4073
Zitat von gue
Öhm rufst du zwischendurch zufällig releaseConnection() auf? Sprich du erzeugst ein paar Connections mit den alten Zugangsdaten, gibst sie wieder in den Pool und jetzt wunderst du dich, warum du mit getConnection() Connections mit den alten Daten kriegst? :D

oi... lol :D vielen dank für auflösung und tipps :)

//hab jetzt deine 2. variante verbaut, funktioniert perfekt. danke, selbst wär ich darauf - denk ich - nie gekommen! :)

--solved
Bearbeitet von prayerslayer am 27.03.2008, 11:58

Nico

former person of interest
Registered: Sep 2006
Location: -
Posts: 4082
kommt ca auf das was ich meinte, nur das du es nicht selbst geschrieben hast :p

prayerslayer

Oar. Mh.
Avatar
Registered: Sep 2004
Location: vorm Sucher
Posts: 4073
Zitat von gue
Öhm rufst du zwischendurch zufällig releaseConnection() auf? Sprich du erzeugst ein paar Connections mit den alten Zugangsdaten, gibst sie wieder in den Pool und jetzt wunderst du dich, warum du mit getConnection() Connections mit den alten Daten kriegst? :D

nein, jetzt weiß ich wieder! ich hab die neuen daten ja eigentlich gesetzt, bevor zum ersten mal ein getConnection() aufgerufen wird. das hat mich so verwirrt.

aber jetzt funktionierts eh. wenns mir trotzdem wer erklären kann, was ich falsch gemacht hab, wäre ich dankbar :)

gue

Addicted
Avatar
Registered: Feb 2003
Location: Linz
Posts: 400
Vermutlich hast du ConnectionPool nicht neu kompiliert, nachdem du die Variablen von static final auf static geändert hast (und nein, das muss man sonst nicht immer machen aber static finals werden als Konstanten angesehen und in das verwendende Classfile importiert (es wird keine Referenz auf die deklarierende Klasse erzeugt)).

prayerslayer

Oar. Mh.
Avatar
Registered: Sep 2004
Location: vorm Sucher
Posts: 4073
Zitat von gue
Vermutlich hast du ConnectionPool nicht neu kompiliert, nachdem du die Variablen von static final auf static geändert hast

doch, ich kompilier ständig neu... und ein testoutput nach dem ändern hat mir auch gezeigt, dass die änderungen übernommen worden sind --> final können die variablen nicht mehr gewesen sein. war es das, was du mir sagen wolltest?

allerdings bin ich mir nicht sicher, ob die netbeans bei "run main project" alle klassen kompilieren oder nur die mit änderungen. bei beiden varianten hätte die klasse aber dabei sein müssen.
Kontakt | Unser Forum | Über overclockers.at | Impressum | Datenschutz