Je veux changer la méthode du fichier .class. J'ai installé JD Eclipse Decompiler et ouvert le fichier .class. J'ai ajouté des codes et enregistrer le fichier .class. Mais, le fichier .class ne change pas.
Je ne sais pas comment utiliser le décompilateur. Et si c'est possible, comment changer le fichier .class sans utiliser le décompilateur.
J'utilise Ubuntu.
Cordialement
MODIFIER:
Voici mon code décompilé:
/* */ package org.hibernate.id;
/* */
/* */ import Java.io.Serializable;
/* */ import Java.sql.ResultSet;
/* */ import Java.sql.SQLException;
/* */ import Java.util.HashMap;
/* */ import Java.util.Properties;
/* */ import org.Apache.commons.logging.Log;
/* */ import org.Apache.commons.logging.LogFactory;
/* */ import org.hibernate.HibernateException;
/* */ import org.hibernate.MappingException;
/* */ import org.hibernate.dialect.Dialect;
/* */ import org.hibernate.type.Type;
/* */ import org.hibernate.util.ReflectHelper;
/* */
/* */ public final class IdentifierGeneratorFactory
/* */ {
/* 25 */ private static final Log log = LogFactory.getLog(IdentifierGeneratorFactory.class);
/* */
/* 64 */ private static final HashMap GENERATORS = new HashMap();
/* */
/* 66 */ public static final Serializable SHORT_CIRCUIT_INDICATOR = new Serializable() {
/* */ public String toString() { return "SHORT_CIRCUIT_INDICATOR";
/* */ }
/* 66 */ };
/* */
/* 70 */ public static final Serializable POST_INSERT_INDICATOR = new Serializable() {
/* */ public String toString() { return "POST_INSERT_INDICATOR";
/* */ }
/* 70 */ };
/* */
/* */ public static Serializable getGeneratedIdentity(ResultSet rs, Type type)
/* */ throws SQLException, HibernateException, IdentifierGenerationException
/* */ {
/* 32 */ if (!(rs.next())) {
/* 33 */ throw new HibernateException("The database returned no natively generated identity value");
/* */ }
/* 35 */ Serializable id = get(rs, type);
/* */
/* 37 */ if (log.isDebugEnabled()) log.debug("Natively generated identity: " + id);
/* 38 */ return id;
/* */ }
/* */
/* */ public static Serializable get(ResultSet rs, Type type)
/* */ throws SQLException, IdentifierGenerationException
/* */ {
/* 45 */ Class clazz = type.getReturnedClass();
/* 46 */ if (clazz == Long.class) {
/* 47 */ return new Long(rs.getLong(1));
/* */ }
/* 49 */ if (clazz == Integer.class) {
/* 50 */ return new Integer(rs.getInt(1));
/* */ }
/* 52 */ if (clazz == Short.class) {
/* 53 */ return new Short(rs.getShort(1));
/* */ }
/* 55 */ if (clazz == String.class) {
/* 56 */ return rs.getString(1);
/* */ }
if(clazz == Java.math.BigDecimal.class){
return rs.getBigDecimal(1);
}
/* */
/* 59 */ throw new IdentifierGenerationException("this id generator generates long, integer, short or string78");
/* */ }
/* */
/* */ public static IdentifierGenerator create(String strategy, Type type, Properties params, Dialect dialect)
/* */ throws MappingException
/* */ {
/* */ try
/* */ {
/* 92 */ Class clazz = getIdentifierGeneratorClass(strategy, dialect);
/* 93 */ IdentifierGenerator idgen = (IdentifierGenerator)clazz.newInstance();
/* 94 */ if (idgen instanceof Configurable) ((Configurable)idgen).configure(type, params, dialect);
/* 95 */ return idgen;
/* */ }
/* */ catch (Exception e) {
/* 98 */ throw new MappingException("could not instantiate id generator", e);
/* */ }
/* */ }
/* */
/* */ public static Class getIdentifierGeneratorClass(String strategy, Dialect dialect) {
/* 103 */ Class clazz = (Class)GENERATORS.get(strategy);
/* 104 */ if ("native".equals(strategy)) clazz = dialect.getNativeIdentifierGeneratorClass();
/* */ try {
/* 106 */ if (clazz == null) clazz = ReflectHelper.classForName(strategy);
/* */ }
/* */ catch (ClassNotFoundException e) {
/* 109 */ throw new MappingException("could not interpret id generator strategy: " + strategy);
/* */ }
/* 111 */ return clazz;
/* */ }
/* */
/* */ public static Number createNumber(long value, Class clazz) throws IdentifierGenerationException {
/* 115 */ if (clazz == Long.class) {
/* 116 */ return new Long(value);
/* */ }
/* 118 */ if (clazz == Integer.class) {
/* 119 */ return new Integer((int)value);
/* */ }
/* 121 */ if (clazz == Short.class) {
/* 122 */ return new Short((short)(int)value);
/* */ }
/* */
/* 125 */ throw new IdentifierGenerationException("this id generator generates long, integer, short");
/* */ }
/* */
/* */ static
/* */ {
/* 75 */ GENERATORS.put("uuid", UUIDHexGenerator.class);
GENERATORS.put("hilo", TableHiLoGenerator.class);
GENERATORS.put("assigned", Assigned.class);
GENERATORS.put("identity", IdentityGenerator.class);
GENERATORS.put("select", SelectGenerator.class);
GENERATORS.put("sequence", SequenceGenerator.class);
GENERATORS.put("seqhilo", SequenceHiLoGenerator.class);
GENERATORS.put("increment", IncrementGenerator.class);
GENERATORS.put("foreign", ForeignGenerator.class);
GENERATORS.put("guid", GUIDGenerator.class);
GENERATORS.put("uuid.hex", UUIDHexGenerator.class);
GENERATORS.put("sequence-identity", SequenceIdentityGenerator.class);
}
}
Vous pouvez suivre ces étapes pour modifier votre classe Java:
Utilisez un éditeur de bytecode, comme:
Faites attention car vous avez besoin d'une très bonne connaissance du bytecode Java.
Vous pouvez également changer de classe au moment de l'exécution avec le tissage de code-octet (comme AspectJ).
J'ai ajouté des codes et enregistrer le fichier .class.
Ce que vous voyez dans JD Eclipse Decompiler est une représentation décompilée du code octet dans le fichier .class. Même si vous modifiez le texte, cela n'affectera pas le code d'octet.
lorsque vous décompilez et modifiez le code, vous devez accéder au dossier racine de votre projet Eclipse et vérifier votre classe dans le dossier bin qui se trouve au même niveau que src. ouvrez ensuite le bocal d'origine avec l'outil Zip ( 7Zip est bon pour cela) et placez la classe modifiée dans le même paquet à l'intérieur du bocal.
Utilisez Java assist Bibliothèque Java pour manipuler le bytecode Java (fichier .class) d’une application.
-> Spring, Hibernate, EJB utilisant ceci pour l'implémentation de proxy
-> nous pouvons manipuler le bytecode pour faire une analyse de programme
-> nous pouvons utiliser Javassist pour implémenter un cache transparent pour les valeurs de retour de méthode, en interceptant tous les appels de méthode et en ne déléguant à la super-implémentation que lors du premier appel.
Parfois, nous devons compiler un fichier unique sur un millier de fichiers pour résoudre le problème. Dans un tel cas, il est possible de créer la même structure de dossier comme chemin de classe, de décompiler le fichier en Java ou de copier le fichier Java à partir du code source. Effectuez les modifications requises, compilez un fichier particulier dans la classe avec toutes les dépendances/classes en place et remplacez enfin le fichier de classe. Enfin, redémarrez le conteneur. Une fois que la guerre est éclatée, le fichier ne sera pas remplacé.
Vous pouvez modifier le code lorsque vous le décompilez, mais il doit être recompilé dans un fichier class
, le décompilateur produisant le code Java
. Celui-ci doit être recompilé avec le même chemin de classe que le fichier jar
/class
.
Pour autant que j'ai pu le savoir, il n'y a pas de moyen simple de le faire. Le moyen le plus simple est de ne pas convertir le fichier de classe en exécutable, mais d'enrouler un programme de lancement exécutable autour du fichier de classe. En d’autres termes, créez un fichier exécutable (éventuellement un fichier de script exécutable basé sur le système d’exploitation) qui appelle simplement la classe Java via la ligne de commande.
Si vous voulez réellement avoir un programme qui le fait, vous devriez regarder dans certains des installateurs automatisés là-bas.
Voici un moyen que j'ai trouvé:
[code]
import Java.io.*;
import Java.util.jar.*;
class OnlyExt implements FilenameFilter{
String ext;
public OnlyExt(String ext){
this.ext="." + ext;
}
@Override
public boolean accept(File dir,String name){
return name.endsWith(ext);
}
}
public class ExeCreator {
public static int buffer = 10240;
protected void create(File exefile, File[] listFiles) {
try {
byte b[] = new byte[buffer];
FileOutputStream fout = new FileOutputStream(exefile);
JarOutputStream out = new JarOutputStream(fout, new Manifest());
for (int i = 0; i < listFiles.length; i++) {
if (listFiles[i] == null || !listFiles[i].exists()|| listFiles[i].isDirectory())
System.out.println("Adding " + listFiles[i].getName());
JarEntry addFiles = new JarEntry(listFiles[i].getName());
addFiles.setTime(listFiles[i].lastModified());
out.putNextEntry(addFiles);
FileInputStream fin = new FileInputStream(listFiles[i]);
while (true) {
int len = fin.read(b, 0, b.length);
if (len <= 0)
break;
out.write(b, 0, len);
}
fin.close();
}
out.close();
fout.close();
System.out.println("Jar File is created successfully.");
} catch (Exception ex) {}
}
public static void main(String[]args){
ExeCreator exe=new ExeCreator();
FilenameFilter ff = new OnlyExt("class");
File folder = new File("./examples");
File[] files = folder.listFiles(ff);
File file=new File("examples.exe");
exe.create(file, files);
}
}
[/code]`
Vous pouvez utiliser n’importe quel décompilateur pour décompiler d’abord le fichier.
Une fois, j'avais rencontré un problème similaire où je n'avais pas le code source de l'application et que je devais apporter une très petite modification à un fichier.
Voici ce que j'ai fait:
Extraire le fichier de classe du pot
Je l'ai ouvert dans un décompilateur (j'utilise JD GUI, vous pouvez l'obtenir facilement depuis de nombreuses ressources sur Internet) Vous pouvez le télécharger depuis ici
Vous pouvez réellement afficher tous les fichiers d'un fichier jar à l'aide de l'interface graphique JD.