# Datenbank wird bei Programmstart als .jar nicht mehr befüllt



## Kern (16. Jan 2014)

Hallo Leute,
ich habe ein Problem mit meinem Java-Projekt und bin langsam wirklich verzweifelt.
Ich suche nun schon seit 2 Wochen in alle mir bekannten Foren, komme aber einfach auf keine Lösung.

Ich greife über mein Programm eine XML-File in einem festen Order innerhalb meines Dateisystems ab, lese die einzelnen Tags aus und schreibe diese anschließend in eine SQL-Datenbank. 

Führe ich das Programm in Eclipse aus funktioniert das auch problemlos. Sobald ich allerdings eine .jar Datei erstelle, um das Programm auch ohne Eclipse ausführen zu können, wird nichts mehr in meine Datenbank geschrieben. 
Ich muss eine .jar erstellen, da das Programm später als Windows-Service laufen soll.
sqljdbc-Treiber ist installiert und auch in der JRE eingefügt.


```
import java.io.*;
import java.sql.*;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.*;
import org.xml.sax.SAXException;

public class xmlZuTxt {
	static String Dateiname = null;
	static String dp = "S:/.../DP/";
	static String in = "S:/.../IN/";
	static String out = "S:/.../OUT/";
	static final String hostname = "DECPC4001\\SQLEXPRESS";
	static final String dbname = "Test"; 
	static final String connectionUrl = "jdbc:sqlserver://" + hostname
			+ ";database=" + dbname + ";integratedSecurity=true;"; 
	static Connection conn = null;
	static boolean v = false;
	static int count = 0;

	public static void main(String[] args) throws IOException {
	try {			
	       for (int i = 0; i < 1; i++) {
        Dateiname = listDir();				
		treiberLaden();
		VerbindungAufbauen();
		Auslesen(Dateiname, i);
		INzuOUT(Dateiname);  }

	} catch (ArrayIndexOutOfBoundsException aioobe) { 
             } catch (IOException ioe) {	}
	}

	public static void Auslesen(String a, int z)throws IOException {

		try {
			VerbindungAufbauen();

			DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
			DocumentBuilder db = dbf.newDocumentBuilder();
			Document doc = db.parse(quellDatei);
			doc.getDocumentElement().normalize();
			NodeList nl = doc.getElementsByTagName(a);

			for (int i = 0; i < nl.getLength(); i++) {

				Node n = nl.item(i);

				if (n.getNodeType() == Node.ELEMENT_NODE) {
					Element e = (Element) n;
					String Heading = n.getNodeName(); 
					String OrderID = e.getElementsByTagName("OrderID").item(i).getTextContent();
					String Info1= e.getElementsByTagName("Info1").item(i).getTextContent();
					String Info2= e.getElementsByTagName("Info2").item(i).getTextContent();					
					String ToolIDs = e.getElementsByTagName("ToolIDs").item(i).getTextContent();

					if (OrderIDPrüfen(OrderID) == 0) {
						// Überprüft ob die OrderID schon vorhanden ist, wenn nicht wird 0 zurückgegeben und diese If-Bedingung ist erfüllt

						ToolIDs = ToolIDs.trim();
						ToolIDs = ToolIDs.replaceAll("\t", "");
						ToolIDs = ToolIDs.replaceAll("\n", "trenn");
						String[] ToolIDfeld = ToolIDs.split("trenn");
						for (int position = 0; position < ToolIDfeld.length; position++) {
							
							if (ToolIDPrüfen(ToolIDfeld[position])) {
									// Sobald eine der ToolIDs schon vorhanden ist, ist die If-Bedingung erfüllt und die Methode wird beendet
								return;
							}
						}
						count = 0;
											for (String s : ToolIDfeld) {
String query = "INSERT INTO Test.dbo.OrderTool(OrderID,ToolID,count) VALUES('"+ OrderIDx + "','" + s + "','" + count + "')";							
		PreparedStatement stm = t.prepareStatement(query);			
       stm.execute();
					stm.close();
							
							count++;
							// count wird erhöht
							// und die Schleife wird erneut durchlaufen
						}
							
						
						PreparedStatement stmt = t.prepareStatement("INSERT INTO Test.dbo.OrderInfo(Heading,Info1,Info2) VALUES ('"+ Heading+ "','"+ Info1+ "','"+ Info2+ "')");	
stm.execute();	
						stm.close();

					
					} else if (OrderIDPrüfen(OrderID) > 0) {
						// Überprüft ob die OrderID schon vorhanden ist, wenn ja wird ein Wert größer 0 zurückgegeben und die If-Bedingung ist erfüllt
						
						ToolIDs = ToolIDs.trim();
						ToolIDs = ToolIDs.replaceAll("\t", "");
						ToolIDs = ToolIDs.replaceAll("\n", "trenn");
						String[] ToolIDfeld = ToolIDs.split("trenn");

						for (int position = 0; position < ToolIDfeld.length; position++) {

							if (ToolIDPrüfen(ToolIDfeld[position])) {
								return;
							}
						}

						count = count + 1;
						for (String s : ToolIDfeld) {

							PreparedStatement stm = t.prepareStatement "INSERT INTO Test.dbo.OrderTool(OrderID,ToolID,count) VALUES('"+ OrderIDx + "','" + s + "','" + count + "')";					
     stm.execute();
							stm.close();

							count++;
						}				
						
						PreparedStatement stmt = t.prepareStatement("INSERT INTO Test.dbo.OrderInfo(Heading,Info1,Info2) VALUES ('"+ Heading+ "','"+ Info1+ "','"+ Info2+ "')");					
stmt.execute();
						stmt.close();
					}
}
			}

		} catch (FileNotFoundException fnfe) {			
		} catch (ParserConfigurationException pce) {	
		} catch (SAXException saxe) {	
		} catch (IOException ioe) {	
		} catch (SQLException sqle) {	
		}
	}

	public static void INzuOUT(String a) {

		File quellDatei = new File(in + a + ".xml"); 
		File zielDatei = new File(out + a + ".xml"); 
		quellDatei.renameTo(zielDatei);
	}

	public static String listDir() {

		String name;
		File dir = new File(dp);
		File[] files = dir.listFiles();
		name = files[0].getName().substring(0,files[0].getName().lastIndexOf(46));	
		return name;
	}

	public static void treiberLaden() throws IOException {

		try {
			Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver"); 										
		} catch (ClassNotFoundException cnfe) { }
	}

	public static void VerbindungAufbauen() throws IOException {

		try {
		conn = DriverManager.getConnection(connectionUrl); 

		} catch (SQLException ex) {
		}
		return;
	}

	public static int OrderIDPrüfen(String w) throws IOException {
			try {
			
			String OrderID = w;
			String query = "SELECT MAX(count) as maxcount FROM Test.dbo.OrderTool where OrderID = '"	+ OrderID + "' group by OrderID";			
	
			Connection t = DriverManager.getConnection(connectionUrl);	
			ResultSet rs = t.createStatement().executeQuery(query); 
			if (rs.next()) {
				count = rs.getInt("maxcount");
			} else {
				count = 0;
			}
			
		} catch (SQLException sqle) {		
		} catch (IOException ioe) {			
		}
		return count;
	}

	public static boolean ToolIDPrüfen(String w)throws IOException {
		try {				
			String ToolID = w;
			String query = "SELECT DISTINCT ToolID  FROM Test.dbo.OrderTool where ToolID = '"+ ToolID + "'";
			Connection t = DriverManager.getConnection(connectionUrl);
			ResultSet rst = t.createStatement().executeQuery(query); 

			if (rst.next()) {
				// ToolID vorhanden
				v = true;

			} else {
				// ToolID nicht vorhanden
				v = false;
			}

		} catch (SQLException sqle) {
		return v;
	}
```
Es tut mir leid das es so viel Code ist aber ich habe wirklich keine Ahnung wo mein Fehler liegt 
Habe die Catch-Zweige geleert um die Menge etwas zu reduzieren. Dürfte ja nicht daran liegen, oder?
Sollte ich irgendwelche Infos vergessen haben oder einfach nur blind sein und ein solches Thema besteht bereits bitte ich vielmals um Entschuldigung. 
Ich hoffe das ich mich einigermaßen verständlich ausgedrückt habe.
Vielen Dank für eure Hilfe.


----------



## VfL_Freak (16. Jan 2014)

Moin,

es werden doch mit Sicherheit Fehlermeldungen angezeigt ...
Welche denn (und wo im Code)?

Gruß
Klaus


----------



## Kern (16. Jan 2014)

Hallo Klaus,
nein gibt es leider nicht...
Das Programm läuft auch mit Aufruf durch die Konsole fehlerfrei durch. 
Lediglich die ausgelesenen Informationen werden nicht in die Datenbank geschrieben.

Gruß Patrick


----------



## VfL_Freak (16. Jan 2014)

Moin,



> Habe die Catch-Zweige geleert um die Menge etwas zu reduzieren.


äh, jetzt nur hier fürs Posten oder auch beim Programmablauf?

Gruß
Klaus


----------



## turtle (16. Jan 2014)

Und du bist sicher mit dem Quellcode, den du hier gepostest hast?

Beim schnellen Überfliegen vermute ich, das da Kompilierungsfehler auftreten müssten.

```
Document doc = db.parse(quellDatei);
```
Sehe nicht woher beispielsweise die Variable quellDatei im Scope der Methode Auslesen bekannt sein soll.


----------



## Kern (16. Jan 2014)

Hallo 

@Klaus: Nur für das Posten hier. Wären ansonsten ca.150 Zeilen mehr gewesen.

@ turtle: Ah mist da hat es mir die letzte Methode nicht mitkopiert. In meinem normalen Code íst da noch: 
	
	
	
	





```
public static void DPzuIN(String a) throws IOException {

		File quellDatei = new File(dp + a + ".xml");
		File zielDatei = new File(in + a + ".xml");
		quellDatei.renameTo(zielDatei);
	}
```
Da wird dann die Quelldatei beschrieben. Sorry
Ansonsten bin ich jetz einen Schritt weitergekommen. Ich habe das ganze Programm in einzelne Methoden aufgesplittet und nochmal(zum gefühlt 100)mal getestet.
Ich kann jetzt definitiv sagen das mein Fehler im Schreiben der Daten in die Datenbank liegt.

```
public class DBVersuch {
	
	static final String hostname = "DECPC4001\\SQLEXPRESS"; 	
	static final String dbname = "Test"; 						
	static final String connectionUrl = "jdbc:sqlserver://"+ hostname + ";database=" + dbname + ";integratedSecurity=true;";  
	static Connection conn = null;
	
	public static void main(String [] args){

		try {
			Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
			conn = DriverManager.getConnection(connectionUrl);	 
				
			} catch (ClassNotFoundException cnfe) {
				cnfe.printStackTrace();
    			} catch (SQLException ex) { 
				ex.printStackTrace();
	
		PreparedStatement stmt = null;
		String OrderID = "666";
		String query = "INSERT into Test.dbo.start(OrderID,ToolID,SeqNum) VALUES('"+ OrderID + "','666','666')";
		
		try {
			stmt = conn.prepareStatement(query);
			stmt.execute();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		
	}
```
Das bedeutet wenn ihr mir helfen könntet dieses CodeStück dazu zu bringen sich in eine .jar umwandeln zu lassen und dann etwas in die Datenbank zu schreiben wären meine Probleme gelöst.
Ich bin freue mich jetzt schon das ihr mir überhaupt helfen wollt. Dafür ein richtig dickes Danke.


----------



## Kern (17. Jan 2014)

Hey Leute,
Ich habe das Programm jetzt mal auf einem anderen Computer ausgeführt und hier bekomme ich eine Fehlermeldung.

java.lang.ClassNotFoundException: com.microsoft.sqlserver.jdbc.SQLServerDriver
        at java.net.URLClassLoader$1.run(Unknown Source)
        at java.net.URLClassLoader$1.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Unknown Source)
        at DBVersuch2.main(DBVersuch2.java:14)

Was sie bedeutet ist klar nur wie ich sie lösen kann stellt mich vor ein Problem.
Vielen Danke für jede Antwort.


----------



## turtle (18. Jan 2014)

> java.lang.ClassNotFoundException: com.microsoft.sqlserver.jdbc.SQLServerDriver


In der Tat ist die Fehlermeldung eindeutig

Wie meinst du, findet die JRE an den JDBC-Treiber?

In Eclipse ist der Classpath gesetzt, so dass er die JAR dafür finden kann. 

Rufst du außerhalb von Eclipse

```
java -jar <DeineJar>
```
dann fehlt im Manifest der Jar-Datei diese Angabe. Wie genau kannst du hier nachlesen.


----------



## Kern (21. Jan 2014)

Hey Leute,
Sorry das ich mich einige Tage nicht gemeldet habe.
Habe versucht das auf die Reihe zu bekommen ohne euch nochmal zu kontaktieren.
Musste jetz jedoch feststellen das ich langsam den Wald vor lauter Bäumen nicht mehr sehe... ;(
Der Link war schon hilfreich aber ich bekomme es nach wie vor nicht hin diese .jar auszuführen
Wenn sich jmd erbarmen könnte mir das als Anleitung für Dummis nochmal zu erklären. 
Vielen vielen Dank.
Kern


----------



## turtle (21. Jan 2014)

Poste doch mal deine MANIFEST.MF und den Namen deiner JAR-Datei, in dem der jdbc Treiber enthalten ist.


----------



## Kern (22. Jan 2014)

Guten Morgen
Meine .jar Datei die den Treiber enthält heißt sqljdbc4.jar.
Aber woher bekomme ich die MANIFEST.MF?
Sehe die nur in Eclipse in den Metainformationen aber ausserhalb komme ich nicht dran.
Viele Grüße und Danke für deine Geduld 
Kern


----------



## turtle (22. Jan 2014)

Ich erstelle aus Eclipse immer eine "normale" JAR Datei.

Da kannst du alle Einstellungen vornehmen und die JAR ausführbar machen.

Insbesondere deine Startklasse UND deinen JDBC-Treiber musst du angeben.

```
Manifest-Version: 1.0
Main-Class: <Deine Startklasse>
Class-Path: sqljdbc4.jar
```

Genaueres kannst du hier nachlesen.


----------



## Kern (22. Jan 2014)

Super!!
Jetz geht alles 
Vielen vielen Dank


----------

