Visualizzazione dei risultati da 1 a 7 su 7
  1. #1

    Eseguibile .jar che non si apre

    Ragazzi, so che è un argomento toccato da molti, ma nei post che ho letto non c'è niente che mi abbia aiutato.
    Devo creare un eseguibile, mi pare di aver capito che sia una cattiva idea creare il .exe, ma che basti il .jar .
    Io uso Netbeans, seguendo le indicazioni che ho trovato leggendo ho:
    -cliccato su Clean & build
    -si è creata la cartella dist e il file Rubrica.jar (la mia è un'applicazione che fa da rubrica)
    -clicco 2 volte su Rubrica.jar ma non succede niente di niente.
    Se faccio "apri con" e seleziono "Java(TM) Platform SE Binary", ugualmente non succede niente! La mia è un'applicazione con interfaccia grafica. Che problema c'è? come faccio ad eseguire la mia app senza entrare in Netbeans?
    Grazie a tutti anticipatamente.

  2. #2

    Moderazione

    Le discussioni relative a Java non sono trattate qui, ma nell'apposita sottosezione.

    Provvedo a spostare il thread.
    Amaro C++, il gusto pieno dell'undefined behavior.

  3. #3
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Quote Originariamente inviata da ariannaari Visualizza il messaggio
    Devo creare un eseguibile, mi pare di aver capito che sia una cattiva idea creare il .exe, ma che basti il .jar .
    Se faccio "apri con" e seleziono "Java(TM) Platform SE Binary", ugualmente non succede niente! La mia è un'applicazione con interfaccia grafica. Che problema c'è? come faccio ad eseguire la mia app senza entrare in Netbeans?
    Su come creare jar "eseguibili" ne abbiamo parlato proprio l'altro giorno in questa discussione.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  4. #4
    Grazie per lo spostamento, e scusate. Ho provato a leggere la discussione. Ne ho lette non so quante, ma non riesco proprio a venirne a capo.
    In alcuni casi viene detto che il manifest si genera da solo, in altri che lo devo creare a mano, consigli vari, che ho provato a applicare, ma rimane il fatto che io non riesco a creare un eseguibile funzionante.

    Vi prego, se potete, di rispiegarmi tutto passo dopo passo perchè, evidentemente, non c'ho capito un cavolo.
    Rispiego bene:
    Ho un'applicazione con tante classi, anche messe in cartelle, e ovviamente ho la mia main che si chiama CStartup.java (percorso: C:\rubrica_federico\src\control\Cstartup.java).

    Da Netbeans faccio Clean&Build e l'applicazione funziona. Nella finestra di output ho questo:

    codice:
    ant -f C:\\rubrica_federico clean jar
    init:
    deps-clean:
    Updating property file: C:\rubrica_federico\build\built-clean.properties
    Deleting directory C:\rubrica_federico\build
    clean:
    init:
    deps-jar:
    Created dir: C:\rubrica_federico\build
    Updating property file: C:\rubrica_federico\build\built-jar.properties
    Created dir: C:\rubrica_federico\build\classes
    Created dir: C:\rubrica_federico\build\empty
    Compiling 86 source files to C:\rubrica_federico\build\classes
    warning: [options] bootstrap class path not set in conjunction with -source 1.5
    Note: Some input files use or override a deprecated API.
    Note: Recompile with -Xlint:deprecation for details.
    Note: Some input files use unchecked or unsafe operations.
    Note: Recompile with -Xlint:unchecked for details.
    1 warning
    Copying 258 files to C:\rubrica_federico\build\classes
    compile:
    Created dir: C:\rubrica_federico\dist
    Copying 1 file to C:\rubrica_federico\build
    Copy libraries to C:\rubrica_federico\dist\lib.
    Building jar: C:\rubrica_federico\dist\Rubrica.jar
    To run this application from the command line without Ant, try:
    java -jar "C:\rubrica_federico\dist\Rubrica.jar"
    jar:
    BUILD SUCCESSFUL (total time: 9 seconds)
    Mi sembra cioè che sia stata eseguita con successo, giusto?
    Quindi, vado in C:\rubrica_federico\dist eh ho Rubrica.jar.
    Se faccio il doppio click, non succede nulla!

    Ora, se provo a lanciarla dal prompt dei comandi ho questo errore:
    codice:
    
    C:\rubrica_federico\dist>java -jar "Rubrica.jar"
    Exception in thread "main" java.lang.NullPointerException
            at control.CImmagini.<init>(CImmagini.java:65)
            at control.CImmagini.istanza(CImmagini.java:75)
            at control.CStartup.main(CStartup.java:39)
    Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
            at control.CImmagini.<init>(CImmagini.java:65)
            at control.CImmagini.istanza(CImmagini.java:75)
            at presentation.componenti.backgroundedFittedLayeredPane.<init>(backgrou
    ndedFittedLayeredPane.java:24)
            at presentation.PMAIN.<init>(PMAIN.java:72)
            at control.CStartup$1.run(CStartup.java:32)
            at java.awt.event.InvocationEvent.dispatch(Unknown Source)
            at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
            at java.awt.EventQueue.access$200(Unknown Source)
            at java.awt.EventQueue$3.run(Unknown Source)
            at java.awt.EventQueue$3.run(Unknown Source)
            at java.security.AccessController.doPrivileged(Native Method)
            at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Sour
    ce)
            at java.awt.EventQueue.dispatchEvent(Unknown Source)
            at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
            at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
            at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
            at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
            at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
            at java.awt.EventDispatchThread.run(Unknown Source)
    Sapete dirmi se avete qualche consiglio?

  5. #5
    Ho avuto un problema simile. Ho risolto modificando il codice relativo al caricamento delle immagini. Puoi postarlo?

  6. #6
    Grazie per l'interessamento. Premetto che la gestione delle immagini è particolare, è stata implementata da altre persone che hanno fatto la parte iniziale dell'applicazione (è un progetto d'esame all'uni).
    Le immagini vengono caricate tramite la seguente classe:
    codice:
    package control;
    
    import java.awt.Image;
    import java.io.File;
    import java.io.IOException;
    import java.util.TreeMap;
    import javax.imageio.ImageIO;
    
    
    /**
     *
     * @author Alessandro
     *
     * Classe di FONDAMENTALE importanza per le PRESTAZIONI dell'applicazione. Premesso che:
     * - l'applicazione è composta da IMMAGINI, di due tipi
     *   • A) relative alla grafica ovvero all'interfaccia del programma (icone, pulsanti, sfondi di Panel, ecc.)
     *   • B) contenenti informazioni e dunque prelevate dal DB (locandine degli spettacoli, loghi dei cinema, foto dei cinema)
     * - il tipo A è preponderante rispetto al tipo B, ed inoltre non è il risultato di una query pertanto il suo utilizzo è  CERTO e dunque PREVEDIBILE
     * - ogni componente che utilizza il tipo A prelevava le immagini (nella versione precedente di questa applicazione) attraverso  la libreria ImageIO
     *   ovvero LEGGENDO DA FILE OGNI volta che il componente veniva istanziato
     * - poteva capitare benissimo (vedi schermata PIFOrario)  che 50 istanze dello stesso componente (ad esempio il pulsante per il GIORNO) ogni  volta
     *   che venivano istanziate (50 istanze) leggessero da file, dallo STESSO file!!! (50 letture dallo stesso file)
     * - la lettura da FILE è lenta, anche più di un accesso al DB
     * - l'applicazione risultava molto lenta nel passaggio da una schermata all'altra e nell'interazione con l'utente
     *
     * L'idea che mi è venuta e la conseguente sua realizzazione sono descritte dai seguenti punti:
     * • le immagini utilizzate sono TANTE (attualmente 207 ma potrebbero raggiungere anche 400) e PICCOLE (mediamente 20-30 KB)
     * • perchè non caricarle tutte in RAM all'avvio (30KB x 400 = 12 MB) e renderle disponibili, invece di leggerle da file ogni volta?
     * • per far ciò è necessaria una classe (QUESTA) avente unica istanza che alloca tutto in RAM la prima volta e poi, su richiesta, fornisce  l'imma-
     *   gine desiderata
     * • la struttura dati più consona al nostro caso è una TreeMap <chiave, valore> in cui
     *   - <chiave> = stringa contenente il percorso RELATIVO dell'immagine (ES.: "/presentation/icone/pulsante_avanti.png"), questo per evitarMI di es-
     *     sere costretto ad andare a modificare tutte le classi dove si usava il percorso relativo per individuare l'immagine
     *   - <valore> = l'immagine desiderata
     * • tale struttura dati sfrutta gli algoritmi sugli alberi binari di ricerca (BST)  per restituire un  elemento con getElemento(chiave x)  in tempo
     *   O(logn) dove n è la dimensione dell'input (nel nostro caso n = 400 => t = log400 = circa 9-10 colpi di clock!!!!)
     * • si tratta semplicemente di leggere da file tutte le immagini UNA SOLA VOLTA (avvio del programma). Quali immagini? TUTTE quelle contentute nel-
     *   la cartella /presentation/icone (farò un ciclo per questo)
     * • dal momento che le classi che costruiscono la grafica sono quelle contenute in  presentation.componenti è bastato andare in ciascuna di esse  e
     *   sostituire la lettura da file mediante ImageIO.read(path_relativo) con la chiamata CImmagini.istanza().getImage(path_relativo)
     *
     * NOTA : le prestazioni sono migliorate del 70-80 % (ho eseguito il test con lo strumento "Profile" di Netbeans)
     * NOTA2: "Sì, ma io che cacchio devo fare?" potreste chiedervi a questo punto.
     * - beh le classi che costruiscono la grafica sono già pronte,quindi dovete solo utilizzarle (ES.: new backgroundedButton("/presentation/icone/pul-
     *   sante_avanti.png")
     * - se avete la necessità in  qualunque momento ed in qualunque classe di ottenere un'immagine di tipo A (ovvero quelle in /presentation/icone)  NON
     *   utilizzate ImageIO.read(path_relativo) ma utilizzate CImmagini.istanza().getImage(path_relativo)
     * - se avete la necessità di ottenere un'immagine di tipo B (ovvero quelle del DB) ovviamente potete usare ImageIO
     */
    public class CImmagini
    {
        private static CImmagini unicaIstanza = null;
        private TreeMap<String,Image> icone;
        public CImmagini()
        {
            //istanzio icone
            this.icone = new TreeMap<String,Image>();
            //prelevo la lista (stringhe) dei files presenti nella cartella presentation/icone
            File f = new File(this.getClass().getResource("/presentation/icone").toString().substring(6));
            String[] arrayNomiFiles = f.list();
    
            //inserisco tutte le icone attraverso un ciclo "intelligente" che sfrutta la conoscenza dei files presenti in presentation/icone
            for(int i=0; i<arrayNomiFiles.length; i++)
            {
                try {this.icone.put("/presentation/icone/"+arrayNomiFiles[i], ImageIO.read(getClass().getResource("/presentation/icone/"+arrayNomiFiles[i])));}
                catch (IOException ex) {System.out.print("ERRORE di lettura dell'icona\n");}
            }
        }
    Quindi, per esempio, se mi serve un bottone con un'immagine di background, all'interno delle mie classi chiamo costruttori di questo tipo:
    codice:
    icon = new backgroundedButton("/presentation/icone/r_icona.png");
    In cui la classe backgroundedButton è così definita:
    codice:
    package presentation.componenti;
    import ...[..]
    public class backgroundedButton extends javax.swing.JButton
    {
        private Image img;
        private Image img_PRESSED;
        private Image img_FOCUSED;
        private Image img_FLASH;
        private String localURL;
    
        public backgroundedButton(String localURL)
        {
            this.localURL = localURL;
            //recupero le 3 immagini (abilitato, cliccato e focalizzato) dall'URL relativo passato
            this.img = CImmagini.istanza().getImage(localURL);
            this.img_PRESSED  = CImmagini.istanza().getImage(localURL.substring(0, localURL.length()-4)+"_PRESSED.png");
            this.img_FOCUSED  = CImmagini.istanza().getImage(localURL.substring(0, localURL.length()-4)+"_FOCUSED.png");
            this.img_FLASH = null; //by Anthony
    
            //elimino il contenuto grafico ed il contorno di default del pulsante
            this.setContentAreaFilled(false);
            this.setFocusPainted(false);
            
            //imposto l'immagine di base
            this.setIcon(new javax.swing.ImageIcon(img));
    
            //imposto l'immagine visualizzata quando il mouse clicca sul pulsante
            this.setPressedIcon(new javax.swing.ImageIcon(img_PRESSED));
            
            //imposto l'immagine visualizzata quando il mouse passa sopra il pulsante o quando esso è selezionato
            this.setRolloverEnabled(true);
            this.setRolloverIcon(new javax.swing.ImageIcon(img_FOCUSED));
            this.setSelectedIcon(new javax.swing.ImageIcon(img_FOCUSED));
    
    
            //imposto il puntatore del mouse appropriato per gli oggetti attivi su cui cliccare
            this.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR));
        }
        public void changeImage(String localURL)
        {
            //imposto gli attributi attuali
            this.localURL = localURL;
            
            //leggo l'immagine
            this.img = CImmagini.istanza().getImage(localURL);
            this.img_PRESSED  = CImmagini.istanza().getImage(localURL.substring(0, localURL.length()-4)+"_PRESSED.png");
            this.img_FOCUSED  = CImmagini.istanza().getImage(localURL.substring(0, localURL.length()-4)+"_FOCUSED.png");
            this.img_FLASH = null; 
            //elimino il contenuto grafico ed il contorno di default del pulsante
            this.setContentAreaFilled(false);
            this.setFocusPainted(false);
            
            //imposto l'immagine di base
            this.setIcon(new javax.swing.ImageIcon(img));
            //imposto l'immagine visualizzata quando il mouse clicca sul pulsante
            this.setPressedIcon(new javax.swing.ImageIcon(img_PRESSED));
            
            //imposto l'immagine visualizzata quando il mouse passa sopra il pulsante o quando esso è selezionato
            this.setRolloverEnabled(true);
            this.setRolloverIcon(new javax.swing.ImageIcon(img_FOCUSED));
            this.setSelectedIcon(new javax.swing.ImageIcon(img_FOCUSED));
    
    
            //imposto il puntatore del mouse appropriato per gli oggetti attivi su cui cliccare
            this.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR));
        }
    
        /* il metodo "setBounds" si occupa di posizionare e dimensionare un elemento grafico. Noi creiamo
         * qui una versione "facilitata" di questo metodo che dimensiona AUTOMATICAMENTE il pulsante  se-
         * condo le dimensioni dell'immagine, pertanto in ingresso riceve solo due coordinate          */
        public void setBounds(int x, int y)
        {
            super.setBounds(x,y,img.getWidth(this),img.getHeight(this));
        }
        //metodi aggiunti da Anthony
        public void takeFlashIcon() {img_FLASH  = CImmagini.istanza().getImage(localURL.substring(0, localURL.length()-4)+"_FLASH.png");}
        public void setFlashIcon() {this.setIcon(new javax.swing.ImageIcon(img_FLASH));}
        public void setDefaultIcon() {this.setIcon(new javax.swing.ImageIcon(img));}
    
         .....
        
    }
    Spero davvero tu mi possa aiutare, anche perchè non mi spiego come abbiano fatto i miei colleghi prima a creare l'eseguibile relativo alla loro parte, visto che questo metodo di caricamento l'hanno usato anche loro.
    Grazie ancora.

  7. #7
    Oh che codice interessante! Comunque credo che tu debba intervenire sulla classe che carica le immagini. Intanto, come detto da Andbin in un'altra discussione: "Dal momento che la specifica inizia con '/', allora vuol dire che 'presentation' viene cercata "alla radice" lungo il classpath. Ovvero questa 'presentation' deve poi trovarsi alla radice dentro il jar."
    Sinceramente non ho ancora ben capito cosa intendesse, magari te potrai capirlo meglio . Però ho fatto un tentativo! Ho tolto
    quel "/" all'inizio e invece di fare
    codice:
    this.getClass().getResource(...)

    Ho fatto
    codice:
    ClassLoader.getSystemResource(...)
    . Poi mi sono reso conto che
    nel mio codice l'iniziale del nome della cartella che contiene le immagini non era in maiusolo come doveva. Il codice paradossalmente funzionava uguale, ma il jar no. Corretta l'iniziale del nome della
    cartella il jar ha preso a funzionare. Quindi per ora ti direi di controllare bene i nomi delle cartelle
    ed eventualmente correggerli all'interno del codice e di provare il piccolo codice che ti ho detto..

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.