# java SQL JAR - Probleme



## NichtExpert (6. Mrz 2020)

Hallo liebe Community,

ich bräuchte mal etwas Hilfe.
Ich habe mein Java-Programm erfolgreich mit einer HeidiSQL-Datenbank verbunden und erneut als GUI. Dazu habe ich mir ein Frame, etc. erstellt.
Die Verbindung mit der GUI und SQL funktioniert auch. Dazu habe ich ein JTable genommen.
Jetzt möchte ich die Datei als JAR machen, damit ich sie als selbstständiges Programm öffnen kann, damit möchte ich später arbeiten als eigene Datenbank.
Ich habe Sie als JAR umgewandelt, es kommt aber immer als Fehlermeldung eine Message: "com.mysql.cj.jdbc.Driver". Die Ausgabe erfolgt über ein JOptionPane.
Sie soll aber die Daten der SQL-Tabelle ausgeben.
Was mache ich falsch?
Schon mal Vielen Dank und hier mein Code :


```
package datenbank;

import java.awt.EventQueue;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import javax.swing.JOptionPane;
import javax.swing.JFrame;
import javax.swing.JTable;
import javax.swing.JScrollPane;
import javax.swing.RowFilter;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableRowSorter;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;

public class SQL_GUI_Connection_personalie extends JFrame {

    /**
     * Launch the application
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                SQL_GUI_Connection_personalie frame = null;
                try {
                    frame = new SQL_GUI_Connection_personalie();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
                frame.setVisible(true);                                                                                 // Frame sichtbar
            }
        });
    }

    /**
     * Create the Frame
     */
    public SQL_GUI_Connection_personalie() throws SQLException {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);                                                                 // Run beenden
        setBounds(100, 100, 580, 242);                                                             // Frame größe
        setTitle("Tutorial-Beispiel");                                                                                  // Frame Überschrift
        getContentPane().setLayout(null);

        // Scrollpane
        JScrollPane scrollPane = new JScrollPane();                                                                     // ScrollPane erstellt
        scrollPane.setBounds(64, 44, 440, 89);                                                      // Größe Scrollpane
        getContentPane().add(scrollPane);                                                                               // Scrollpane dem getContentpane hinzugefügt

        // Table
        JTable table = new JTable();                                                                                    // Table erstellt
        scrollPane.setViewportView(table);                                                                              // scrollpane dem table (tabelle) hinzugefügt

        // Model for Table
        DefaultTableModel model = (DefaultTableModel)table.getModel();                                                  // Model erstellt
        model.addColumn("ID");                                                                            // Überschrift Table (tabelle-spalten)
        model.addColumn("Firstname");                                                                     // Überschrift table (tabelle-spalten)
        model.addColumn("Lastname");                                                                      // Überschrift table (tabelle-spalten)
        model.addColumn("Sport");                                                                         // Überschrift table (tabelle-spalten)
        model.addColumn("# of years");                                                                    // Überschrift table (tabelle-spalten)
        model.addColumn("vegetarian");                                                                    // Überschrift table (tabelle-spalten)


        JLabel lblFilter = new JLabel("Filter :");                                                                 // label erstellt
        lblFilter.setBounds(158, 147, 72, 14);                                                      // Label Größe
        getContentPane().add(lblFilter);                                                                                // label dem getContentPane zugeordnet

        // Filter
        final JTextField txtFilter = new JTextField();                                                                  // Textfield erstellt
        txtFilter.setBounds(197, 144, 129, 20);                                                     // Textfield erstellt
        getContentPane().add(txtFilter);                                                                                // Textfielf dem GetContentpane zugeordnet

        // Header Sort
        final TableRowSorter<DefaultTableModel> sorter = new TableRowSorter<DefaultTableModel>(model);
        table.setRowSorter(sorter);

        // Button OK
        JButton btnOK = new JButton("OK");                                                                         // button erstellt, Button-Schrift="OK"
        btnOK.addActionListener(new ActionListener() {                                                                  // Befehl, click auf button hinzugefügt
            @Override                                                                                                   //
            public void actionPerformed(ActionEvent actionEvent) {                                                      //
                String expr = txtFilter.getText();                                                                      // String expr = textfield (bekommt text von dort)
                sorter.setRowFilter(RowFilter.regexFilter(expr));                                                       //
                sorter.setSortKeys(null);                                                                               //
            }
        });
        btnOK.setBounds(336, 144, 59, 23);                                                          // Button Größe
        getContentPane().add(btnOK);                                                                                    // Button dem getContnetPane zugeordnet

        Connection connect = null;
        Statement s = null;


        try {
            Class.forName("com.mysql.cj.jdbc.Driver");                                                                  // SQL Treiber

            connect = DriverManager.getConnection("jdbc:mysql://localhost/test","till","Tillerni02");     // Connection zur Datenbank (Pfad + nutzername + passwort der Datenbank)

            s = connect.createStatement();

            String sql = "SELECT * FROM personalie ORDER BY ID";                                                        // Auswahl Tabelle, Anzeigekriterien

            ResultSet rec = s.executeQuery(sql);
            int row = 0;
            while ((rec!=null) && (rec.next()))
            {
                model.addRow(new Object[0]);
                model.setValueAt(rec.getString("ID"), row, 0);                                               // spalten-name der SQL-Tabelle (muss richtig sein, sonst Fehler)
                model.setValueAt(rec.getString("Firstname"), row, 1);                                       // spalten-name der SQL-Tabelle (muss richtig sein, sonst Fehler)
                model.setValueAt(rec.getString("Lastname"), row, 2);                                         // spalten-name der SQL-Tabelle (muss richtig sein, sonst Fehler)
                model.setValueAt(rec.getString("Sport"), row, 3);                                            // spalten-name der SQL-Tabelle (muss richtig sein, sonst Fehler)
                model.setValueAt(rec.getFloat("# of years"), row, 4);                                        // spalten-name der SQL-Tabelle (muss richtig sein, sonst Fehler)
                model.setValueAt(rec.getString("vegetarian"), row, 5);                                       // spalten-name der SQL-Tabelle (muss richtig sein, sonst Fehler)
                row++;
            }

            rec.close();

        } catch (Exception e) {
            // TODO Auto-generated catch block
            JOptionPane.showMessageDialog(null, e.getMessage());
            e.printStackTrace();
        }


        try {
            if (s != null) {
                s.close();
                connect.close();
            }
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}
```


----------



## mihe7 (6. Mrz 2020)

NichtExpert hat gesagt.:


> Ich habe Sie als JAR umgewandelt, es kommt aber immer als Fehlermeldung eine Message: "com.mysql.cj.jdbc.Driver".


Hintergrund dürfte sein, dass sich der JDBC-Treiber nicht im Classpath befindet. Mal drei von vielen Möglichkeiten:

1. ein Uber-Jar erstellen, sprich beide Jars entpacken und dann zu einem zusammenpacken (-> startbar via Doppelklick)
2. die Anwendung unter Angabe des Classpaths und der Main-Class aufrufen (-> startbar mit Batch-File)
3. im Manifest den Classpath angeben und mit java -jar aufrufen (-> startbar via Doppelklick)

Option 1 würde ich persönlich nicht machen. Es gibt aber Leute, denen gefällt das.


----------



## Ullenboom (8. Mrz 2020)

Trotz des kleinen Programms kannst du Spring Boot einführen (https://spring.io/guides/gs/relational-data-access/), auch mit Swing ist das kein Problem und der JDBC-Teil wird kürzer. Du nimmst den JDBC-Treiber in der POM mit auf und machst mvn package und bekommst ein Fat-Jar, was du mit java -jar XXXX direkt starten kannst, oder über Doppelklick.


----------



## Thallius (8. Mrz 2020)

Immer her mit den Atomraketen für die kleinen Spatzen....


----------



## NichtExpert (10. Mrz 2020)

Vielen Dank für die Antworten,
ich werde mir das Ganze mal anschauen


----------



## NichtExpert (10. Mrz 2020)

mihe7 hat gesagt.:


> Hintergrund dürfte sein, dass sich der JDBC-Treiber nicht im Classpath befindet. Mal drei von vielen Möglichkeiten:
> 
> 1. ein Uber-Jar erstellen, sprich beide Jars entpacken und dann zu einem zusammenpacken (-> startbar via Doppelklick)
> 2. die Anwendung unter Angabe des Classpaths und der Main-Class aufrufen (-> startbar mit Batch-File)
> ...



Ich würde glaube ich die 3 variante mit dem Manifest machen.
Die Anderen habe ich mir mal angeschaut und habe NULL ahnung was damit gemeint ist...
Ich weiß aber auch nciht genau, wie das mit dem Manifest geht:
Muss ich das selbst schreiben?
Muss das dann in Out/ artifact hin oder ich habe was von Unterordner gelesen...


----------



## mihe7 (10. Mrz 2020)

NichtExpert hat gesagt.:


> ch weiß aber auch nciht genau, wie das mit dem Manifest geht:
> Muss ich das selbst schreiben?


Das ist von der IDE und dem verwendeten Build-System abhängig (s. z. B. https://netbeans.org/kb/articles/javase-deploy.html) 

Letztlich ist das Manifest eine einfache Textdatei, die im Jar unter /META-INF/MANIFEST.MF abgelegt wird und ein paar Einträge enthält, unter anderem etwas in der Form (Achtung: das ist nicht vollständig)

```
Main-Class: paket.unterpaket.MainKlasse
Class-Path: lib/jdbctreiber.jar
```
Der erste Eintrag sorgt dafür, dass die Jar-Datei ausführbar ist, der zweite, dass die jdbctreiber.jar in einem Verzeichnis lib, das sich auf der gleichen Verzeichnisebene wie die Jar-Datei befindet, gesucht wird.


----------



## NichtExpert (10. Mrz 2020)

mihe7 hat gesagt.:


> Der erste Eintrag sorgt dafür, dass die Jar-Datei ausführbar ist, der zweite, dass die jdbctreiber.jar in einem Verzeichnis lib, das sich auf der gleichen Verzeichnisebene wie die Jar-Datei befindet, gesucht wird.


Genau, habe mir das auch schon angeguckt. In meiner MANIFEST ist aber gar kein "classpath" vorhanden und gefüllt mit mehreren Sachen:

Code Hier:

```
Manifest-Version: 1.0
Ant-Version: Apache Ant 1.8.2
Created-By: 1.8.0_221-b11 (Oracle Corporation)
Built-By: pb2user
Specification-Title: JDBC
Specification-Version: 4.2
Specification-Vendor: Oracle Corporation
Implementation-Title: MySQL Connector/J
Implementation-Version: 8.0.18
Implementation-Vendor-Id: com.mysql
Implementation-Vendor: Oracle
Bundle-Vendor: Oracle Corporation
Bundle-ClassPath: .
Bundle-Version: 8.0.18
Bundle-Name: Oracle Corporation's JDBC and XDevAPI Driver for MySQL
Bundle-ManifestVersion: 2
Bundle-SymbolicName: com.mysql.cj
Export-Package: com.mysql.cj.jdbc;version="8.0.18";uses:="javax.manage
 ment,javax.naming,javax.naming.spi,javax.net.ssl,javax.sql,javax.tran
 saction.xa,javax.xml.parsers,javax.xml.stream,javax.xml.transform,jav
 ax.xml.transform.dom,javax.xml.transform.sax,javax.xml.transform.stax
 ,javax.xml.transform.stream,org.xml.sax",com.mysql.cj;version="8.0.18
 ",com.mysql.cj.protocol;version="8.0.18",com.mysql.cj.protocol.result
 ;version="8.0.18",com.mysql.cj.result;version="8.0.18",com.mysql.cj.p
 rotocol.a;version="8.0.18",com.mysql.cj.protocol.a.authentication;ver
 sion="8.0.18",com.mysql.cj.protocol.a.result;version="8.0.18",com.mys
 ql.cj.protocol.x;version="8.0.18",com.mysql.cj.x.protobuf;version="8.
 0.18",com.mysql.cj.log;version="8.0.18",com.mysql.cj.util;version="8.
 0.18",com.mysql.cj.jdbc.util;version="8.0.18",com.mysql.cj.jdbc.excep
 tions;version="8.0.18",com.mysql.cj.exceptions;version="8.0.18",com.m
 ysql.cj.jdbc.ha;version="8.0.18",com.mysql.cj.jdbc.interceptors;versi
 on="8.0.18",com.mysql.cj.jdbc.integration.c3p0;version="8.0.18";uses:
 ="com.mchange.v2.c3p0",com.mysql.cj.jdbc.integration.jboss;version="8
 .0.18";uses:="org.jboss.resource.adapter.jdbc,org.jboss.resource.adap
 ter.jdbc.vendor",com.mysql.cj.configurations;version="8.0.18",com.mys
 ql.cj.conf;version="8.0.18",com.mysql.cj.conf.url;version="8.0.18",co
 m.mysql.jdbc;version="8.0.18";uses:="com.mysql.cj.jdbc",com.mysql.cj.
 jdbc;version="8.0.18",com.mysql.cj.jdbc.jmx;version="8.0.18",com.mysq
 l.cj.jdbc.result;version="8.0.18",com.mysql.cj.xdevapi;version="8.0.1
 8";uses:="com.google.protobuf,javax.security.auth.callback,javax.secu
 rity.sasl",com.mysql.cj.admin;version="8.0.18",com.mysql.cj.jdbc.admi
 n;version="8.0.18"
Import-Package: javax.net.ssl;javax.crypto;resolution:=optional,javax.
 xml.parsers;javax.xml.stream;javax.xml.transform;javax.xml.transform.
 dom;javax.xml.transform.sax;javax.xml.transform.stax;javax.xml.transf
 orm.stream;org.w3c.dom;org.xml.sax;org.xml.sax.helpers;resolution:=op
 tional,javax.sql;javax.naming;javax.naming.spi;javax.transaction.xa;r
 esolution:=optional,javax.management;resolution:=optional,com.mchange
 .v2.c3p0;version="[0.9.1.2,1.0.0)";resolution:=optional,org.jboss.res
 ource.adapter.jdbc;org.jboss.resource.adapter.jdbc.vendor;resolution:
 =optional,org.slf4j;resolution:=optional,com.google.protobuf;javax.se
 curity.auth.callback;javax.security.sasl;resolution:=optional
```


----------



## mihe7 (10. Mrz 2020)

NichtExpert hat gesagt.:


> In meiner MANIFEST ist aber gar kein "classpath" vorhanden und gefüllt mit mehreren Sachen:


Das ist aber nicht das Manifest Deiner Jar sondern des JDBC-Treibers.


----------



## NichtExpert (10. Mrz 2020)

mihe7 hat gesagt.:


> Das ist aber nicht das Manifest Deiner Jar sondern des JDBC-Treibers.


Jetzt bin ich etwas baff?
Das das das manifest des JDBC-Treibers ist weiß ich ja.
Ich habe aber sonst keinen Anderen...
Dann muss ich den erstellen? Als Textdatei wenn ich das richtig im Kopf habe?


----------



## mihe7 (10. Mrz 2020)

Welche IDE und welches Build-System verwendest Du denn?


----------



## NichtExpert (10. Mrz 2020)

ähhmmm,


mihe7 hat gesagt.:


> Welche IDE und welches Build-System verwendest Du denn?



IntelliJ IDEA Community Edition 2019.2.4 x64


----------



## mihe7 (10. Mrz 2020)

Guckst Du hier: https://stackoverflow.com/questions/1082580/how-to-build-jars-from-intellij-properly

Für Deinen Fall dürftest Du "copy to the output directory and link via manifest" ankreuzen müssen.


----------



## NichtExpert (10. Mrz 2020)

mihe7 hat gesagt.:


> Guckst Du hier: https://stackoverflow.com/questions/1082580/how-to-build-jars-from-intellij-properly
> 
> Für Deinen Fall dürftest Du "copy to the output directory and link via manifest" ankreuzen müssen.



Schaue es mir gleich an, vielen Dank


----------



## NichtExpert (11. Mrz 2020)

mihe7 hat gesagt.:


> Guckst Du hier: https://stackoverflow.com/questions/1082580/how-to-build-jars-from-intellij-properly


Okay, ich habe mir das Ganze mal angeguckt und habe gesehen, dass ich doch schon bereits eine Manifest erstellt hatte und nur nicht gefunden habe.
Sie lag im src Ordner versteckt.
jetzt habe ich glaube nurnoch eine letzte Frage:
Der Classpath, wie genau und ab wo gebe ich dort etwas ein:
1. gebe ich dort den Pfad zur Datei x.jar ein- und falls ja, den internen oder externen (sprich im explorer den, oder den im Programm)?


----------



## NichtExpert (11. Mrz 2020)

Hat sich erledigt, habe es hinbekommen,
Vielen Dank nochmal für die Hilfe


----------



## mihe7 (11. Mrz 2020)

NichtExpert hat gesagt.:


> Hat sich erledigt, habe es hinbekommen,
> Vielen Dank nochmal für die Hilfe


Wenn Du jetzt noch für die Nachwelt festhalten würdest, was Du getan hast, damit es funktioniert, wäre das perfekt


----------



## NichtExpert (11. Mrz 2020)

mihe7 hat gesagt.:


> Wenn Du jetzt noch für die Nachwelt festhalten würdest, was Du getan hast, damit es funktioniert, wäre das perfekt


klar, Im Grunde habe ich n´mich an das Tutorial gehalten [ https://stackoverflow.com/questions/1082580/how-to-build-jars-from-intellij-properly ].

1. Schritt: Click File --> Projekt Structure
2. Schritt: unter Artifacts auf "+" drücken --> Jar --> From Modules with dependencies
3. Schritt: Unter Main-Class die Klasse auswählen, die umgewandelt werden soll.
4. Schritt:  Unter "Directory for Meta-Inf" den Speicherort für Meta-Inf festlegen
(Ich habe immer neue erstellt, und diese am Ende zur Jar dazugelegt, damit ich weiß, dass das zusammengehört)
Das liegt daran, dass ich welche mit JDBC-Treibern hatte und manche ohne,...
5. Schritt: name des Artifacts und der jar-Datei ändern
6. Schritt: Falls benötigt Treiber hinzufügen
7. Schritt: unter Build ---> Build Artifacts und den erstellten Artifact auswählen und "Build" drücken -> damit wird das Artifact im Ordner "out" "Artifact" gespeichert

Von dort aus klappte die Jar
In dem Tutorial steht, man soll noch "Steuerung + Shift + a" drücken und "Edit Configuration" eingeben und auswählen

8. Schritt: Unter "jar-Applikation" habe ich die die erstellte Jar angeklickt und unter "build" das "+" ausgewählt und nochmal build artifact und die jar ausgewählt.


----------



## NichtExpert (11. Mrz 2020)

NichtExpert hat gesagt.:


> klar, Im Grunde habe ich n´mich an das Tutorial gehalten [ https://stackoverflow.com/questions/1082580/how-to-build-jars-from-intellij-properly ].
> 
> 1. Schritt: Click File --> Projekt Structure
> 2. Schritt: unter Artifacts auf "+" drücken --> Jar --> From Modules with dependencies
> ...


Habe vergessen, dass ich dann noch die Meta-inf im selben Ordner wie die Jar abgelegt habe out/artifact/...


----------

