getResourceAsStream επιστρέφει null

Φορτώνω ένα αρχείο κειμένου μέσα από ένα πακέτο σε ένα μεταγλωττισμένο JAR του έργου μου Java. Η σχετική δομή του καταλόγου έχει ως εξής: Η δομή του καταλόγου έχει ως εξής: Η δομή του καταλόγου έχει ως εξής: Η δομή του καταλόγου έχει ως εξής:

/src/initialization/Lifepaths.txt

Ο κώδικας που χρησιμοποιείται για τη φόρτωση του αρχείου είναι:

public class Lifepaths {
    public static void execute() {
        System.out.println(Lifepaths.class.getClass().
            getResourceAsStream("/initialization/Lifepaths.txt"));
    }

    private Lifepaths() {}

    //This is temporary; will eventually be called from outside
    public static void main(String[] args) {execute();}
}

Η εκτύπωση θα εκτυπώνει πάντα null, ανεξάρτητα από το τι χρησιμοποιώ. Δεν είμαι σίγουρος γιατί τα παραπάνω δεν θα λειτουργούσαν, οπότε δοκίμασα επίσης:

  • "/src/initialization/Lifepaths.txt"
  • "initialization/Lifepaths.txt"
  • "Lifepaths.txt"

Κανένα από αυτά δεν λειτουργεί. I've read numerous questions so far on the topic, but none of them have been helpful - usually, they just say to load files using the root path, which I'm already doing. Αυτό, ή απλά να φορτώσω το αρχείο από τον τρέχοντα κατάλογο (just load filename), το οποίο έχω επίσης δοκιμάσει. Το αρχείο μεταγλωττίζεται στο JAR στην κατάλληλη τοποθεσία με το κατάλληλο όνομα.

Πώς μπορώ να το λύσω αυτό;

Λύση

Lifepaths.class.getClass().getResourceAsStream(...) φορτώνει πόρους χρησιμοποιώντας τον φορτωτή κλάσεων του συστήματος, προφανώς αποτυγχάνει επειδή δεν βλέπει τα JARs σας.

Lifepaths.class.getResourceAsStream(...) φορτώνει πόρους χρησιμοποιώντας τον ίδιο φορτωτή κλάσεων που φόρτωσε την κλάση Lifepaths και θα πρέπει να έχει πρόσβαση στους πόρους των JARs σας

Σχόλια (6)

Οι κανόνες έχουν ως εξής:

  1. ελέγξτε τη θέση του αρχείου που θέλετε να φορτώσετε μέσα στο JAR (και έτσι βεβαιωθείτε επίσης ότι έχει πράγματι προστεθεί στο JAR)
  2. χρησιμοποιήστε είτε μια απόλυτη διαδρομή: η διαδρομή ξεκινά από τη ρίζα του JAR
  3. χρησιμοποιήστε μια σχετική διαδρομή: η διαδρομή ξεκινά από τον κατάλογο πακέτων της κλάσης που καλείτε getResource/ getResoucreAsStream

Και δοκιμάστε:

Lifepaths.class.getResourceAsStream("/initialization/Lifepaths.txt")

αντί για...

Lifepaths.class.getClass().getResourceAsStream("/initialization/Lifepaths.txt")

(δεν είμαι σίγουρος αν έχει διαφορά, αλλά το πρώτο θα χρησιμοποιήσει το σωστό ClassLoader/ JAR, ενώ με το δεύτερο δεν είμαι σίγουρος)

Σχόλια (3)

Έτσι, υπάρχουν διάφοροι τρόποι για να λάβετε έναν πόρο από ένα jar και ο καθένας έχει ελαφρώς διαφορετική σύνταξη, όπου η διαδρομή πρέπει να καθοριστεί διαφορετικά.

Η καλύτερη εξήγηση που έχω δει είναι αυτό το άρθρο από το JavaWorld. Εγώ'θα συνοψίσω εδώ, αλλά αν θέλετε να μάθετε περισσότερα θα πρέπει να δείτε το άρθρο.

Μέθοδοι

  1. ClassLoader.getResourceAsStream().

Μορφή: "/"-διαχωρισμένα ονόματα- χωρίς αρχικό "/" (όλα τα ονόματα είναι απόλυτα).

Παράδειγμα: this.getClass().getClassLoader().getResourceAsStream("some/pkg/resource.properties");

  1. Class.getResourceAsStream()

Μορφή: "/"-διαχωρισμένα ονόματα- το κορυφαίο "/" υποδηλώνει απόλυτα ονόματα- όλα τα άλλα ονόματα είναι σχετικά με το πακέτο της κλάσης's

Παράδειγμα: this.getClass().getResourceAsStream("/some/pkg/resource.properties");

Σχόλια (3)