How to change already compiled .class file without decompile?
Solution 1
You can follow these steps to modify your java class:
- Decompile the .class file as you have done and save it as .java
- Create a project in Eclipse with that java file, the original JAR as library, and all its dependencies
- Change the .java and compile
- Get the modified .class file and put it again inside the original JAR.
Solution 2
Use a bytecode editor, like:
Be careful because you need a very good knowledge of the Java bytecode.
You can also change the class at runtime with bytecode weaving (like AspectJ).
Solution 3
Recaf is a decompiler GUI that allows you to edit and recompile files. Here is the relevant portion of the manual:
The easiest way to edit bytecode is to edit it as decompiled source. This does not work for highly complex cases and obfuscation, but for most simple edits its all you’ll ever need to do. Simply open the class, make your changes as plain Java code, and save.
Solution 4
I added some codes and save .class file.
What you see in JD EClipse Decompiler is decompiled representation of byte code in the .class file. Even though you change the text it won't affect the byte code.
Solution 5
when you decompile and change the code you have to go on the root folder of your eclipse project and check your class in bin folder wich is on the same level as src. then open you original jar with zip tool ( 7zip is good for that ) and put the modified class in tha same package inside the jar.
Breed Hansen
Updated on December 01, 2021Comments
-
Breed Hansen over 2 years
I want to change .class file's method. I installed JD Eclipse Decompiler and opened the .class file. I added some codes and save .class file. But, .class file is not changing.
I don't know how to use decompiler. And if is it possible, how to change .class file without using decompiler.
I am using Ubuntu.
Regards
EDIT:
Here is my decompiled code:
/* */ 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); } }
-
Breed Hansen over 11 yearsThanks for reply but i have no knowledge about java bytecode.
-
izaera over 11 yearsI don't think you can change any class in runtime with reflection. You need a library to create classes on the fly to do something similar.
-
Breed Hansen over 11 yearsThanks, I understood the idea. But i don't know how i do this?
-
epoch over 11 yearspull the decompiled code into eclipse, resolve dependencies, fix errors, and recompile with eclipse. put the resulting class file into the old jar. alternatively obtain original source code.
-
Breed Hansen over 11 yearsThat is the my problem. I changed but not effect.
-
Breed Hansen over 11 yearsI can reach .class file's .java file only in Eclipse. So, i don't understood how "class file into the old jar"?
-
Nikolay Kuznetsov over 11 years@BreedHansen, why not to generate String instead of BigDecimal? So the answer to your question is: it is almost impossible. Or you have to extract the source code to eclipse and try to generate another class file with your modifications.
-
Breed Hansen over 11 yearsThanks for detail reply. I want to do this. Is it really impossible? forum.hibernate.org/viewtopic.php?t=964410
-
Breed Hansen over 11 yearsI can't save .java file. Actually, i can't save anyway. I saved .class file but when I close and reopen my changes are disappear.
-
izaera over 11 yearsWouldn't it be better to download the source code for the file you want to modify (as it is part of Hibernate), change it, and recompile? You can use my method to recompile or just try to recompile the whole Hibernate (though this can be harder).
-
izaera over 11 yearsThen, you have it. Just save it to a Java file, add the modifications in the forum, and do what I proposed.
-
Breed Hansen over 11 yearsI can't save. When I close the .class file, changes are disappears. Because I can't recompile.
-
Antimony over 11 yearsYou forgot one other option. Disassemble, modify, and reassemble. It works on any classfile, but it requires you to understand bytecode, which I highly doubt the OP does.
-
izaera over 11 years:-O. Now I understand. I was not stating options, but steps in a process. I was suggesting Breed to follow these steps to modify the java class.
-
Breed Hansen over 11 years@izaera, I did it. My new .class file is shown properly. My edit is saved. But I have a problem. I get same error and when I clicked the error link I get this warning "Source not found for org.hibernate.id.IdGeneratorFactory" I can see .class file but it is not shown runtime.
-
Nico Schreiner about 4 yearsSometimes changing java bytecode is easier than getting dependencies right... Especially if you just have to make some minor changes. JBE threw errors in my case but Recaf worked perfectly.
-
Alejandro González over 2 yearsVery useful and up do date answer! Thanks
-
Col-E about 2 yearsAnd in case the decompiled code isn't recompilable, there is the primary editing function, the assembler: coley.software/Recaf-documentation/use-edit-via-bytecode.html