SQL Server Android App: 'int java.lang.String.length()' on a null object reference

Hallo Leute,

ich stehe hier vor einem Problem. Eine kurze Zusammenfassung zu dem, was ich eigentlich vorhabe:
Ich schreibe eine Android App und möchte mit dieser Reihen von Tabelle A zu Tabelle B übertragen durch einen INSERT INTO Befehl. An sich also nichts spektakuläres. Tabelle A wird über einen SELECT Befehl ausgelesen und die Werte in eine ArrayList und später dann in Strings gespeichert. Die Methode "suchen" funktioniert einwandfrei beim ersten Mal. Bei zweiten Mal passiert nichts. Ich kriege lediglich die Fehlermeldung:
Attempt to invoke virtual method 'int java.lang.String.length()' on a null object reference
Mir ist bewusst, dass irgendwo ein null Wert übergeben wird aber ich weiß nicht genau wo, weil mir keine Zeile angezeigt wird in der Meldung. Verbesserungsvorschläge wären sehr hilfreich.

Anbei ist mein Code, der leicht zensiert wurde.

MFG Detlef_Retlef

Java:
import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.StrictMode;
import android.support.design.widget.TextInputEditText;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.view.View;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;

public class SQLInsertInto extends AppCompatActivity {

    private static String ip = "...";
    private static String port = "...";
    private static String Klasse = "net.sourceforge.jtds.jdbc.Driver";
    private static String database = "...";
    private static String username = "...";
    private static String password = "...";
    private static String url = "jdbc:jtds:sqlserver://"+ip+":"+port+"/"+database;
    private Connection connection = null;
    private TextInputEditText suchleiste;
    private ArrayList<String> A = new ArrayList<>();
    private ArrayList<String> B = new ArrayList<>();
    private ArrayList<String> C = new ArrayList<>();
    private ArrayList<String> D = new ArrayList<>();
    private String eingabestring = null;
    private String aVar;
    private String bVar;
    private String cVar;
    private String dVar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_sql_insert_into);

        suchleiste = (TextInputEditText) findViewById(R.id.suchleiste);

        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.INTERNET}, PackageManager.PERMISSION_GRANTED);

        StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
        StrictMode.setThreadPolicy(policy);
    }


    public void suchen(View view) {
            if (connection != null) {
                Statement statement;
                try {
                    A.clear();
                    B.clear();
                    C.clear();
                    D.clear();
                    getString();
                    statement = connection.createStatement();
                    ResultSet resultset = statement.executeQuery("SELECT A, B, C, D\n" +
                            "FROM Tabelle1 WHERE E = '" + eingabestring + "'");
                    while(resultset.next()) {
                        for (int i = 1; i <= 1; i++) {
                            A.add(resultset.getString(1));
                            B.add(resultset.getString(2));
                            C.add(resultset.getString(3));
                            D.add(resultset.getString(4));
                        }
                    }
                            aVar = A.get(0);
                            bVar = B.get(0);
                            cVar = C.get(0);
                            dVar = D.get(0);
                    
                } catch (SQLException e) {
                    e.printStackTrace();
                }
                try {
                    getString();
                    statement = connection.createStatement();
                    statement.executeUpdate("INSERT INTO Tabelle2\n" +
                            "(A, B, C, D)" +
                            "VALUES ('" + aVar + "', '" + bVar + "', '" + cVar + "', '" + dVar + "')");
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            Intent intent = new Intent(getBaseContext(), SQLInsertInto.class);
            startActivity(intent); }
    }

    private void getString() {
        eingabestring = suchleiste.getText().toString();
    }
}

XML:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="SQLInsertInto">

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="155dp"
        android:layout_marginStart="60dp"
        android:onClick="suchen"
        android:text="Suchen" />

    <android.support.design.widget.TextInputEditText
        android:id="@+id/suchleiste"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="75dp"/>


</RelativeLayout>
 
K

kneitzel

Gast
Also da fällt einiges direkt auf:
SQL Abfragen mit Usereingabe so zusammen zu setzen ist grob fahrlässig und öffnet Tür und Tor für SQL Injection Attacken (und gefährdet die Funktionalität. Gib auch mal ein ' ein beim Suchstring ....)
==> PreparedStatement mit Parameter nutzen: https://docs.oracle.com/javase/tutorial/jdbc/basics/prepared.html

Die for Schleife mit i=1 und i<=1 ist so unnötig und kann weg.

Wenn a,b,c und d zusammen gehören, dann würde ich da eine eigene Klasse für schreiben.

Statt die Werte zu lesen und dann zu schreiben könntest du direkt ein SELECT ... INTO ... durchführen.

Was den Fehler angeht: der Stacktrace sollte Dir doch genau aufzeigen, wo der Fehler auftritt. So auf Anhieb sehe ich nicht, wo der Fehler her kommen könnte.
 
Also da fällt einiges direkt auf:
SQL Abfragen mit Usereingabe so zusammen zu setzen ist grob fahrlässig und öffnet Tür und Tor für SQL Injection Attacken (und gefährdet die Funktionalität. Gib auch mal ein ' ein beim Suchstring ....)
==> PreparedStatement mit Parameter nutzen: https://docs.oracle.com/javase/tutorial/jdbc/basics/prepared.html

Die for Schleife mit i=1 und i<=1 ist so unnötig und kann weg.

Wenn a,b,c und d zusammen gehören, dann würde ich da eine eigene Klasse für schreiben.

Statt die Werte zu lesen und dann zu schreiben könntest du direkt ein SELECT ... INTO ... durchführen.

Was den Fehler angeht: der Stacktrace sollte Dir doch genau aufzeigen, wo der Fehler auftritt. So auf Anhieb sehe ich nicht, wo der Fehler her kommen könnte.
Danke für die schnelle Antwort. Wenn ich die for-Schleife weglasse wird überall "null" eingetragen in der Datenbank. Mit ihr wird alles korrekt übertragen.
Die restlichen Tipps werde ich mal ausprobieren.

MFG Detlef_Retlef
 
K

kneitzel

Gast
Nur die äußere for Schleife sollte web, nicht der Inhalt. Der Inhalt wird zum Inhalt der while Schleife.

Damit sollte sich an dem Ablauf nichts ändern, denn die for Schleife wird ja genau ein Mal ausgeführt und das hast du ja auch, wenn der Code in der for Schleife einfach nur da stehen würde ...

Und was auch noch auffällt: du schließt nichts. Alles was (Auto)Closable ist solltest Du nach der Benutzung schließen. Bei dir wäre das Statement und Resultat am Ende zu schließen. Mein Tipp wäre hier try with resources zu nutzen.
 
Nur die äußere for Schleife sollte web, nicht der Inhalt. Der Inhalt wird zum Inhalt der while Schleife.

Damit sollte sich an dem Ablauf nichts ändern, denn die for Schleife wird ja genau ein Mal ausgeführt und das hast du ja auch, wenn der Code in der for Schleife einfach nur da stehen würde ...

Und was auch noch auffällt: du schließt nichts. Alles was (Auto)Closable ist solltest Du nach der Benutzung schließen. Bei dir wäre das Statement und Resultat am Ende zu schließen. Mein Tipp wäre hier try with resources zu nutzen.

Wenn ich abfragen lasse, ob ein '-Zeichen enthalten ist in der Suchleiste, und es dann blockiere, sollte es doch vorerst sicher sein oder? Öffnen kann man es ja dann nicht mehr. Ist es möglich innerhalb eines '...' einen verschachtelten Befehl einzubauen? Also z.B.:

... WHERE E = 'SELECT * FROM ... usw' (So in etwa. Ich bin nur ein SQL-Anfänger)

Ich würde es erst gerne zum laufen bringen und mich dann zu einem späteren Zeitpunkt in die PreparedStatements reinlesen.
 
K

kneitzel

Gast
Verschachtelte SQL Abfragen sind möglich, aber natürlich nicht in ', weil das dann ein Literal wäre.

SELECT * from SomeTable WHERE someField IN (SELECT aField FROM OtherTable)

Das wäre so ein Beispiel einer verschachtelten SQL Anweisung.
 
Verschachtelte SQL Abfragen sind möglich, aber natürlich nicht in ', weil das dann ein Literal wäre.

SELECT * from SomeTable WHERE someField IN (SELECT aField FROM OtherTable)

Das wäre so ein Beispiel einer verschachtelten SQL Anweisung.

Ich habe jetzt mal testweise ein PreparedStatement geschrieben. Dieses Mal als UPDATE und es funktioniert sogar. Jedoch erkenne ich da keinen Unterschied in Punkto Sicherheit gegenüber meiner ersten Version.

Anbei der Code:

Code:
public void suchen(View view) {
if (connection !=null) {
            try {
                PreparedStatement updateTabelle1 = connection.prepareStatement(
                        "UPDATE Tabelle1 SET A = ? WHERE B = 'Irgendwas'");
                getString();
                updateTabelle1.setString(1, eingabestring);
                updateTabelle1.executeUpdate();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
}
 
K

kneitzel

Gast
PreparedStatement kennt Parameter. Schau Dir diese doch noch einmal an (z.B. in dem Link, den ich dazu gepostet habe).
 

mihe7

Top Contributor
Jedoch erkenne ich da keinen Unterschied in Punkto Sicherheit gegenüber meiner ersten Version.
Deine Version baut den SQL-String selbst zusammen, z. B.
Java:
"UPDATE Tabelle1 SET A = '" + eingabe + "' WHERE B = 'Irgendwas'"
Wenn ich als Benutzer Deiner Software nun folgendes eingebe: X', B='Y, dann wird aus Deinem String: "UPDATE Tabelle1 SET A='X', B='Y' WHERE B = 'Irgendwas'". Oops.

Das nennt sich SQL-Injection und neuer Code, der so etwas zulässt, sollte mit Zuchthaus bestraft werden :)
 
Deine Version baut den SQL-String selbst zusammen, z. B.
Java:
"UPDATE Tabelle1 SET A = '" + eingabe + "' WHERE B = 'Irgendwas'"
Wenn ich als Benutzer Deiner Software nun folgendes eingebe: X', B='Y, dann wird aus Deinem String: "UPDATE Tabelle1 SET A='X', B='Y' WHERE B = 'Irgendwas'". Oops.

Das nennt sich SQL-Injection und neuer Code, der so etwas zulässt, sollte mit Zuchthaus bestraft werden :)
Hehe
Ich arbeite mittlerweile schon mit PreparedStatements. Aber das obige kann man auch einfach umgehen, wenn man keine '-Zeichen erlaubt im Suchfeld.
 
K

kneitzel

Gast
Also wie @LimDul schon schrieb: Das ist nur ein offensichtlicher Angriff.

Generell ist es so, dass es extrem viele Angriffsvektoren gibt. Und da sollte man sich auf gewisse Experten verlassen, die sich da intensiv mit beschäftigen. Daher macht es durchaus Sinn, sicherheitsrelevante Dinge zu nutzen, die bewährt sind und die von Experten begutachtet wurden.

Aber hier geht es auch noch um ganz andere Dinge: Die Darstellung von Werten als Zeichenkette ist problematisch.
a) Ungenauigkeiten bei der Darstellung: 17.001 / 17,001 - was für Zahlen sind das? Es gibt das Tausender-Trennzeichen und es gibt das "Komma" für nicht ganze Zahlen. Je nach Regionalisierung sind das unterschiedliche Dinge. Beim Datum kommen noch mehr Schreibweisen hinzu. Diese Regionalisierung kann schnell Probleme bereiten, wenn Du z.B. auf einem Gerät mit deutschen Settings arbeitest, aber der Server auf einem System mit US Settings läuft.
b) Wie stellst Du ein Byte Array dar? Oder die Übergabe einer Tabelle? Es gibt also durchaus Datentypen, die nicht so einfach darstellbar sind.

Also es gibt Best Practices und das ist eine ganz wichtige. Und das mit dem Zuchthaus ist natürlich übertrieben, aber mach sowas im beruflichen Umfeld und du würdest Konsequenzen erfahren fürchte ich....

Daher: schau dir den Link noch einmal im Detail an. Speziell auf die ? im SQl Query und dann die setInt / setString Aufrufe, die danach folgen, achten.
 

mihe7

Top Contributor
Aber das obige kann man auch einfach umgehen, wenn man keine '-Zeichen erlaubt im Suchfeld.
Wozu, wenn es einen einfachen und "sicheren" Weg gibt?

SQL-Injection ist auch heute noch ein Problem. Selbst SAP bleibt davon nicht verschont: https://www.cvedetails.com/cve/CVE-2016-6818/

100 %-ig sicher kann man sich nie sein (hat der JDBC-Treiber evtl. einen Bug?) Aber alles ist besser als eine Frickellösung, die Eingaben des Benutzers in einen SQL-String selbst einbaut. Das ist als ob der Maurer die Ziegel mit dem Uhu-Klebestift zusammenklebt.

Und das mit dem Zuchthaus ist natürlich übertrieben
Geringfügig :) Wobei man sagen muss, dass durch solche Scherze großer Schaden entstehen kann und die Frage ggf. wird, ob hier grobe Fahrlässigkeit unterstellt werden muss.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
A Java DB Server lässt sich nicht starten Datenbankprogrammierung 3
U SQL Server mit Java verbinden Datenbankprogrammierung 5
D Oracle Gateway oder Relay-Server Datenbankprogrammierung 5
Thallius MySQL JDBC auf Linux Server zu mySQL DB auf anderem Linux Server wirft Access denied Datenbankprogrammierung 5
C Derby/JavaDB Auf Variable aus Link in java server page zugreifen Datenbankprogrammierung 4
platofan23 MySQL Java Programm findet Treiber für mySQL auf Debian-Server nicht? Datenbankprogrammierung 11
F MySQL Verbindung zum SQL-Server Datenbankprogrammierung 27
J Datenbank VPS Server Datenbankprogrammierung 3
L Oracle Daten von einem Server zum andere kopieren Datenbankprogrammierung 24
K MySQL LAN-MySQL Server mit XAMPP Datenbankprogrammierung 2
V HSQLDB detached entity passed to persist: server.Employee Datenbankprogrammierung 4
I Es kann keine Verbindung zum Server aufgebaut werden Datenbankprogrammierung 12
B Derby/JavaDB Client-Server-Architektur mit Datenbank Datenbankprogrammierung 6
X MySQL Verbindungdsaufbau MySql auf Ubuntu-Server Datenbankprogrammierung 10
M MySQL Verbindung zum Server aufbauen ohne DB ansprechen Datenbankprogrammierung 2
C Derby auf Server Datenbankprogrammierung 6
ruutaiokwu sql server t-sql: try/catch bei ALTER TABLE ? Datenbankprogrammierung 4
ruutaiokwu sql server 2008 stored procedures automatisiert vergleichen Datenbankprogrammierung 2
ruutaiokwu sql server constraints priorität? Datenbankprogrammierung 3
ruutaiokwu sql server werte swappen beim update-vorgang mit unique-constraints..? Datenbankprogrammierung 2
D Daten von einem Server in eigenem Java-Programm benutzen Datenbankprogrammierung 6
W MySQL -Server Einstellung -- Zugriff übers lokale Netzwerk Datenbankprogrammierung 1
cover1012 Derby/JavaDB Verbindung mit FTP-Server Datenbankprogrammierung 13
N MySQL Datenbank-Server in *.jar packen? Datenbankprogrammierung 6
L Mit Java Desktop Anwendung auf Mysql Server auf Webspace verbinden Datenbankprogrammierung 11
F h2 als server Datenbankprogrammierung 3
V MySQL MsSql ohne Server nutzen? Datenbankprogrammierung 2
S MySQL Server Informationen abfragen Datenbankprogrammierung 6
F MSSQL-Server Verbindung Datenbankprogrammierung 5
DStrohma MS SQL Server 2005 + Java: Immer nur eine aktive Verbindung erlaubt? Datenbankprogrammierung 5
D MySQL Client - Server: Client verabschiedet sich sobald ich Variablen im SQL Statement verwende Datenbankprogrammierung 9
A MS Sql Server 2008 - Verbindungsproblem Datenbankprogrammierung 3
E Nach Server wechsel Datenbank fehler ?!? Datenbankprogrammierung 3
J Oracle oder SQL-Server Datenbankprogrammierung 18
J Server Datenbankprogrammierung 3
C SQL Server Treiber [DBNETLIB] Datenbankprogrammierung 14
A Client-Server anwendung sofort aktualisieren Datenbankprogrammierung 7
T Hsqldb: java.lang.NoClassDefFoundError: org/hsqldb/Server Datenbankprogrammierung 2
E MSSQL-Server connection aufbau sehr langsam Datenbankprogrammierung 2
W Problem bei Insert mit JDBC auf MS-SQL-Server 2005 Datenbankprogrammierung 7
0x7F800000 MS-SQL Server 2008 Wie benutzt man da NATURAL JOIN / INNER JOIN USING? Datenbankprogrammierung 3
M Problem mit ResultSet bei SQL Server 2005 Datenbankprogrammierung 6
D Bean: server internal error Datenbankprogrammierung 5
Landei MsSql Express Server 2008 Datenbankprogrammierung 8
G MSSQL Server SELECT Abfrage funktioniert nicht Datenbankprogrammierung 4
M [gelöst] Problem mit SQL Server. Statements... Datenbankprogrammierung 4
A Java JDBC Programm bringt auf Unix Server Fehlermeldung Datenbankprogrammierung 4
K JDBC MS SQL SERVER Datenbankprogrammierung 6
J MS sql Server 2005 Treiber Datenbankprogrammierung 9
G jdbc grundlegende verbindung zu sql server geht nicht Datenbankprogrammierung 9
thE_29 Byte auslesen mit MS SQL Server Datenbankprogrammierung 4
sparrow Hibernate in non-EE Server/Client-App (Topic geändert) Datenbankprogrammierung 10
G Suchen von Zahlen in einem Textfeld / SQL Server Datenbankprogrammierung 1
G update sperren bei client/server anwendung Datenbankprogrammierung 7
T JDBC und Client/Server Datenbankprogrammierung 12
G SQL Server Connection Datenbankprogrammierung 12
G Access Zugriff, DB auf Server, Applet Datenbankprogrammierung 4
R Unknown initial character set index . received from server Datenbankprogrammierung 5
M HSQLDB Server Problem Datenbankprogrammierung 2
K INSERT INTO bei Windows 2005 SQL Server Standard Edition . Datenbankprogrammierung 2
F Zwischen Datenbanken wählen auf SQL-Server Datenbankprogrammierung 4
G Insert in MS SQL Server Db funktioniert nicht richtig Datenbankprogrammierung 16
G Datenbank ohne Server Datenbankprogrammierung 28
G DB-Server schmiert ab Datenbankprogrammierung 6
D Datenbankzugriff auf MS SQL Server 2000 funktioniert nicht Datenbankprogrammierung 3
S SQLite oder RDBMS als Datei(nicht Client/Server) Datenbankprogrammierung 5
J Hibernate + Spring + SQL Server => Performanceprobleme :( Datenbankprogrammierung 4
G JDBC Verbindung zu MySQL-Server auf lokalem Rechner Datenbankprogrammierung 5
O Datenbankzugriff "ohne" Server ? Datenbankprogrammierung 9
D Datenbank zugriff über Client/Server Datenbankprogrammierung 4
G Problem mit Suchen Statement Java und MS-SQL-Server Datenbankprogrammierung 9
thE_29 Microsoft SQL Server 2000 Datenbankprogrammierung 2
A DTS Export/Import MS-SQL Server 2000 Datenbankprogrammierung 3
A help me !(entitybean + sql server) Datenbankprogrammierung 2
R Invalid parameter bindings bei MS SQL Server Datenbankprogrammierung 2
G Fehlermeldung beim Zugriff auf SQL-Server-DB Datenbankprogrammierung 3
R JAVA-Prog auf Datenbank-Server zugreifen Datenbankprogrammierung 3
D SQLite Datenbank in Android Studio (Java) durchsuchen Datenbankprogrammierung 3
W MYSQL Datenbank Login Android Datenbankprogrammierung 3
T Android Studio & Firebase Datenbankprogrammierung 2
L MySQL Android zu externer MySQL Datenbank verbinden Datenbankprogrammierung 5
A Android Datenbank einbeziehen Datenbankprogrammierung 6
P Android - MsSQL Datenbankprogrammierung 6
Juelin Java und MySQL MariaDB - WHERE-Klausel Datenbankprogrammierung 17
P Reicht finally nicht um DB connections zu schließen in (altem) Java? Datenbankprogrammierung 4
TheSkyRider MySQL Datenbankzuordnung in Verbindung mit Java Datenbankprogrammierung 7
TH260199 Java-Programm. Probleme bei der Umsetzung von einer Kontaktverwaltung. Datenbankprogrammierung 7
S Das printen der Ausgabe des Oracle-SQL-Statements in der Java-Eclipse-Konsole funktioniert nicht Datenbankprogrammierung 6
Zrebna Wie mittels Hibernate eine Join-Tabelle als eigene Java-Klasse erstellen? Datenbankprogrammierung 5
Zrebna Noobfrage: Konvertierung von SQL-Datentyp 'timestamp with time zone' in Java-Datentyp Datenbankprogrammierung 3
Zrebna Lediglich interne DB-Verbindungen (Connections) auslesen - mittels Java Datenbankprogrammierung 4
berserkerdq2 Was genau muss ich bei date eingeben, wenn ich in Java eine Spalte definiere, die date ist? Datenbankprogrammierung 1
berserkerdq2 Was kann passieren, wenn ich in java einstelle, dass der Fremdschüssel ein Attribut ist, welches selber kein Primärschlüssel ist? Datenbankprogrammierung 4
berserkerdq2 Foreign key einstellen java Datenbankprogrammierung 4
nikgo Java SQL Ausgabe in Liste o.ä. abspeichern um mit dem Ergbnis "zu arbeiten"? Datenbankprogrammierung 5
S Datenbankprogrammierung in Java unter NetBeans 12 funktioniert nicht! Datenbankprogrammierung 1
Beginner22 Zugriff auf Datenbank aus Java über mariadb Datenbankprogrammierung 3
S ODBC Treiber in Java Editor einbinden Datenbankprogrammierung 3
H Oracle Resize eines Images in Java und Rückgabe des Image als BLOB an die Oracle Datebank Datenbankprogrammierung 14
H Java Class zum komprimieren von Jpeg-Images zum Einbinden in Oracle DB - Bild als blob (in und out) Datenbankprogrammierung 23

Ähnliche Java Themen


Oben