How to change already compiled .class file without decompile?

158,848

Solution 1

You can follow these steps to modify your java class:

  1. Decompile the .class file as you have done and save it as .java
  2. Create a project in Eclipse with that java file, the original JAR as library, and all its dependencies
  3. Change the .java and compile
  4. Get the modified .class file and put it again inside the original JAR.

Solution 2

Use a bytecode editor, like:

http://set.ee/jbe/

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.

Share:
158,848
Breed Hansen
Author by

Breed Hansen

Updated on December 01, 2021

Comments

  • Breed Hansen
    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
    Breed Hansen over 11 years
    Thanks for reply but i have no knowledge about java bytecode.
  • izaera
    izaera over 11 years
    I 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
    Breed Hansen over 11 years
    Thanks, I understood the idea. But i don't know how i do this?
  • epoch
    epoch over 11 years
    pull 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
    Breed Hansen over 11 years
    That is the my problem. I changed but not effect.
  • Breed Hansen
    Breed Hansen over 11 years
    I can reach .class file's .java file only in Eclipse. So, i don't understood how "class file into the old jar"?
  • Nikolay Kuznetsov
    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
    Breed Hansen over 11 years
    Thanks for detail reply. I want to do this. Is it really impossible? forum.hibernate.org/viewtopic.php?t=964410
  • Breed Hansen
    Breed Hansen over 11 years
    I 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
    izaera over 11 years
    Wouldn'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
    izaera over 11 years
    Then, you have it. Just save it to a Java file, add the modifications in the forum, and do what I proposed.
  • Breed Hansen
    Breed Hansen over 11 years
    I can't save. When I close the .class file, changes are disappears. Because I can't recompile.
  • Antimony
    Antimony over 11 years
    You 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
    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
    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
    Nico Schreiner about 4 years
    Sometimes 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
    Alejandro González over 2 years
    Very useful and up do date answer! Thanks
  • Col-E
    Col-E about 2 years
    And in case the decompiled code isn't recompilable, there is the primary editing function, the assembler: coley.software/Recaf-documentation/use-edit-via-bytecode.htm‌​l