Quali impostazioni influenzano il layout dei file .class java compilati? Come puoi sapere se due classi compilate sono uguali?

StackOverflow https://stackoverflow.com/questions/644320

Domanda

Ho un'app che è stata compilata con Eclipse integrata " Compila " compito. Quindi ho deciso di spostare la procedura di compilazione nel javac di Ant e il risultato è finito con file più piccoli.

Successivamente ho scoperto che regolando il debuglevel su " vars, lines, source " ho potuto incorporare le stesse informazioni di debug di Eclipse, e in molti casi i file sono rimasti esattamente della stessa dimensione ma il layout interno era diverso. Di conseguenza, non ho potuto usare le firme md5sum per determinare se fossero esattamente la stessa versione.

Oltre alle informazioni di debug, quale può essere la ragione per cui 2 file apparentemente uguali ottengono un layout o una dimensione interna diversa?

E come puoi confrontare i file .class compilati?

È stato utile?

Soluzione

Non esiste un ordine richiesto per cose come l'ordine delle voci costanti del pool (essenzialmente tutte le informazioni sui simboli) e gli attributi per ciascun campo / metodo / classe. Diversi compilatori sono liberi di scrivere nell'ordine che desiderano.

Puoi confrontare le classi compilate, ma dovrai scavare nella struttura del file di classe e analizzarla. Ci sono librerie là fuori per farlo, come BCEL o ASM , ma non sono sicuro al 100% che ti aiuteranno con quello che vuoi fare.

Altri suggerimenti

L'ASM Eclipse plugin ha un comparatore bytecode. Si selezionano due classi, si fa clic con il tasto destro del mouse e si confronta con / a vicenda Bytecode.

Una cosa importante da notare è che Eclipse non utilizza javac. Eclipse ha un proprio compilatore, il JDT , e quindi differenze nel risultato. i file di classe non mi sorprendono. Mi aspetto che non siano testuali, perché sono compilatori diversi.

A causa delle loro differenze, esiste un codice che viene compilato con javac ma non con JDT e viceversa. In genere ho visto le differenze tra i due diventare evidenti nei casi di uso intenso dei generici

Soprattutto, gli slot di stack per le variabili locali possono essere organizzati in modo arbitrario senza modificare la semantica del codice. Quindi, fondamentalmente, non puoi confrontare i file di classe compilati senza analizzarli e normalizzarli - un grande sforzo.

Perché vuoi farlo comunque?

come diceva Michale B, può essere arbitrario.

Lavoro su sistemi che utilizzano dimensioni di file come sicurezza. Se le dimensioni dei file .class cambiano, alla classe non verranno assegnate determinate autorizzazioni.

Normalmente sarebbe facile aggirare, ma abbiamo un controllo abbastanza completo sull'ambiente, quindi in realtà è piuttosto funzionale.

Ad ogni modo, ogni volta che le classi che vengono guardate vengono ricompilate, a quanto pare, dobbiamo ricalcolare le dimensioni.

Un'altra cosa: quando viene compilato il file viene generato un numero chiave speciale. Non ne so molto, ma spesso impedisce alle classi di lavorare insieme. Credo che la procedura sia, compila la classe A e salvala (chiamala a1). compilare nuovamente la classe a (a2). Compilare la classe b contro la classe a2. Prova a eseguire b contro a1. Credo che in questo caso fallirà durante l'esecuzione.

Se potessi saperne di più su quel numero di chiave, potrebbe darti le informazioni che stai cercando.

Per il comparisson puoi decompilare i tuoi file di classe e giocare con i sorgenti generati. Vedi questo .

Eclipse sta eseguendo strumenti per aiutare l'esecuzione nel debugger?

In definitiva, le configurazioni utilizzate probabilmente fanno la differenza. Supponendo che stiano utilizzando le stesse versioni di Java, esistono una serie di opzioni disponibili per la configurazione della compilazione (conformità JDK, compatibilità dei file di classe e una serie di opzioni di informazioni di debug).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top