# Bilddateien auch in .jar einlesen können



## モストウォンテッド (4. Dez 2022)

Hallo,
ich habe folgendes Problem: ich habe ein funktionierendes Programm in eine jar Datei umgewandelt, allerdings werden in meinem Programm Bilder eingelesen. Sobald ich jetzt die jar Datei ausführen möchte werden diese nicht mehr eingelesen. Im Compiler funktioniert aber alles ohne Probleme. Ich weiß nicht woran das liegt und wie ich es lösen kann. Hier der Code wie die Bilder aktuell eingelesen werden: 
	
	
	
	





```
img = ImageIO.read(new File("figures/blackbishop.png"));
```

Ich danke schon einmal für jede Hilfe.

Ps: ich weiß das andere Leute diese Frage in ähnlicher Form hier schon einmal gestellt haben, allerdings haben die Tipps die dort gegeben wurden, bei mir nicht funktioniert, deshalb frage ich.


----------



## KonradN (4. Dez 2022)

Du musst Die Datei dann als Ressource mit in die jar Datei packen und dann kannst Du auf die Ressource per getClass().getResource bzw. mit getResourceAsStream zugreifen. (Je nachdem, ob Du da per Stream oder URL zugreifen willst)


----------



## モストウォンテッド (4. Dez 2022)

Also so:

```
img = ImageIO.read(getClass().getResource("figures/blackbishop.png"));
```

weil das funktioniert irgendwie auch nicht
Hinzu kommt jetzt noch diese Fehlermeldung:

```
Exception in thread "main" java.lang.IllegalArgumentException: input == null!
    at java.desktop/javax.imageio.ImageIO.read(ImageIO.java:1358)
```
Die Fehlermeldung kommt egal ob ich es mit Stream oder normal versuche


----------



## KonradN (4. Dez 2022)

Wo liegen denn die Ressourcen genau? Wo liegt die Klasse?

Generell ist es immer gut, die Dokumentation zu lesen. Bei dem Zugriff über getClass wird relativ zum package zugegriffen. Wenn Du also in dem package a.b bist, dann wird auf dem Classpath nach a/b/figures/blackbishop.png gesucht. Daher kann es ggf. schon einfach nur sein, dass Du auf /figures/blackbishop.png zugreifen willst. Aber ohne Details zu kennen ist das nur geraten.
Ebenso kann es ein anderes Problem sein wie z.B.

die Ressource ist nicht im Build Vorgang berücksichtigt worden
Du hast ein Problem mit der Gross-/Kleinschreibung (was im Filesystem ggf. egal war)
...

Ohne Details kann man nur raten oder Daten aus der Dokumentation schreiben. Beides macht relativ wenig Sinn.


----------



## モストウォンテッド (4. Dez 2022)

KonradN hat gesagt.:


> Wo liegen denn die Ressourcen genau? Wo liegt die Klasse?
> 
> Generell ist es immer gut, die Dokumentation zu lesen. Bei dem Zugriff über getClass wird relativ zum package zugegriffen. Wenn Du also in dem package a.b bist, dann wird auf dem Classpath nach a/b/figures/blackbishop.png gesucht. Daher kann es ggf. schon einfach nur sein, dass Du auf /figures/blackbishop.png zugreifen willst. Aber ohne Details zu kennen ist das nur geraten.
> Ebenso kann es ein anderes Problem sein wie z.B.
> ...


ok, ich schau mal. Danke


----------



## モストウォンテッド (4. Dez 2022)

モストウォンテッド hat gesagt.:


> ok, ich schau mal. Danke


Falls ich es nicht im Build vorgang berücksichtigt habe wie kann ich es denn berücksichtigen?


----------



## KonradN (4. Dez 2022)

モストウォンテッド hat gesagt.:


> Falls ich es nicht im Build vorgang berücksichtigt habe wie kann ich es denn berücksichtigen?


Das hänbgt davon ab, was Du zur verwaltung Deines Projektes nutzt.


In maven / gradle ist es üblich, dass Ressourcen unter src/main/resources liegen und damit dann berücksichtigt werden.
Eclipse packt einfach alles in das src Verzeichnis
Bei IntelliJ Projekten kann man ein beliebiges Verzeichnis nutzen - dieses muss dann nur als Ressource Verzeichnis markiert werden.
...


----------



## モストウォンテッド (4. Dez 2022)

Okay ich habe IntelliJ reicht es wenn ich das Verzeichnis ressources nenne oder muss ich etwas bestimmtes machen?


----------



## KonradN (4. Dez 2022)

モストウォンテッド hat gesagt.:


> Okay ich habe IntelliJ reicht es wenn ich das Verzeichnis ressources nenne oder muss ich etwas bestimmtes machen?


Hast Du auch ein IntelliJ Projekt oder arbeitest Du mit Maven oder Gradle? Die Entwicklungsumgebung kann mit vielen Projekten umgehen und hier kommt es auf das zu grunde liegende Projekt an.

Wenn es ein IntelliJ Projekt ist, dann musst Du das Verzeichnis auch als Ressources Verzeichnis markieren (Rechtsklick und dann Mark Directory -> Auswahl, als was das Verzeichnis markiert sein soll.)


----------



## モストウォンテッド (4. Dez 2022)

Also ich habe kein ein IntelliJ Projekt, aber selbst es als Resource Verzeichnis zu markieren hat nichts gebracht. Trotzdem vielen Dank


----------



## KonradN (4. Dez 2022)

Wie wäre es mit Details? Bei einem reinen IntelliJ Projekt wird es schwer, alle Daten zusammen zu tragen, aber paar Bildschirmfotos könnten helfen, um zu sehen, wie Das Projekt aufgebaut ist. Am Anfang wäre es interessant, wie das Projektfenster aussieht mit aufgeklappten Verzeichnissen, so dass die Java Datei und die Ressource Datei zu sehen ist. (Und auch, dass da keine pom.xml, build.gradle und so vorhanden sind).

Dazu dann noch der genaue Code, den Du geschrieben hast um auf die Ressource zuzugreifen.


----------



## モストウォンテッド (4. Dez 2022)

Okay also hier ist einmal das Bildschirmfoto:

Dann hier ist der aktuelle Code mit dem ich arbeite:

```
img = ImageIO.read(new File("figures/blackbishop.png"));
```
ich habe vorher das ganze auch so ausprobiert, hat aber auch nicht funktioniert:

```
img = ImageIO.read(Bishop.class.getResource("figures/blackbishop.png"));
```


----------



## KonradN (4. Dez 2022)

Ok, figures ist der Ressource Ordner. Der Inhalt wird kopiert, d.h. der Ordner figures selbst nicht. Daher wäre es statt /figures/blackbishop.png nur /blackbishop.png

Wichtig ist der führende / - den solltest du nicht vergessen.


----------



## モストウォンテッド (4. Dez 2022)

```
img = ImageIO.read(Bishop.class.getResource("/blackbishop.png"));

 img = ImageIO.read(new File("/blackbishop.png"));
```

Ich habe es jetzt einmal so und einmal so gemacht jedoch funktioniert beides nicht.


----------



## KonradN (4. Dez 2022)

Heisst die Datei auch genau so? Auf dem Bildschirmfoto ist ja der Ordner nicht aufgeklappt. Ansonsten einmal das Projekt bereit stellen, dann kann man im Detail schauen, was falsch ist.


----------



## モストウォンテッド (5. Dez 2022)

Das wäre das Projekt


----------



## KonradN (5. Dez 2022)

Ich habe da jetzt einmal testweise den Code angepasst im Bishop.java:

```
public void paint(Graphics g) {
        Graphics2D g2d = (Graphics2D) g;
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
        BufferedImage img = null;

        try {
            if(this.black){
                img = ImageIO.read(getClass().getResourceAsStream("/blackbishop.png"));

            }else{
                img = ImageIO.read(getClass().getResourceAsStream("/whitebishop.gif"));
            }
            g.drawImage(img, x, y, null);
            if(clicked){
                g.setColor(Color.CYAN);
                g.fillRect(x, y, width, width);
            }

        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }
```

wobei das ohne das AsStream natürlich auch geht:

```
public void paint(Graphics g) {
        Graphics2D g2d = (Graphics2D) g;
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
        BufferedImage img = null;

        try {
            if(this.black){
                img = ImageIO.read(getClass().getResource("/blackbishop.png"));

            }else{
                img = ImageIO.read(getClass().getResource("/whitebishop.gif"));
            }
            g.drawImage(img, x, y, null);
            if(clicked){
                g.setColor(Color.CYAN);
                g.fillRect(x, y, width, width);
            }

        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }
```

Das funktioniert beides.

Das natürlich dann bei allen Figuren, dann Artefakt bauen lassen und siehe da - es läuft.

Also genau so, wie bereits gesagt. Und ohne weitere Anpassungen am Projekt.


----------



## モストウォンテッド (5. Dez 2022)

Ich weiß nicht warum, aber wenn ich die jar in intellij anklicke und ausführe funktioniert es bei mir auch, versuche ich sie allerdings aus dem explorer heraus zu öffnen zeichnet es die Figuren weiterhin nicht.


----------



## KonradN (5. Dez 2022)

Was passiert denn, wenn Du die jar Datei per
java -jar nameDerJarDatei.jar
aus einer Eingabeaufforderung / aus einem Terminal startest?

Doppelklick ist immer ein schlechter Test, da Du ja keinerlei Fehlermeldungen zu sehen bekommst. Und da spielt dann auch viel mehr rein wie z.B. ob Java auf dem Rechner richtig installiert ist und so.


----------



## モストウォンテッド (5. Dez 2022)

Jetzt endlich! Es hat funktioniert, ich habe vergessen, dass ich die Sachen in anderer Reihenfolge zeichne und wollte es nur bei den Bishops testen, obwohl ich vorher die Rooks zeichne🤦‍♂️. Danke für die Geduld! Wirklich danke.


----------



## KonradN (5. Dez 2022)

Kein Problem, gern geschehen!


----------

