Как сменить уже скомпилированный файл .class без декомпиляции?
Я хочу изменить метод .class file. Я установил JD Eclipse Decompiler и открыл файл .class. Я добавил несколько кодов и сохранил файл .class. Но файл .class не меняется.
Я не знаю, как использовать декомпилятор. И если это возможно, как изменить файл .class без использования декомпилятора.
Я использую Ubuntu.
Привет
EDIT:
Вот мой декомпилированный код:
/* */ 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);
}
}
Ответы
Ответ 1
Вы можете выполнить следующие действия, чтобы изменить свой класс java:
- Декомпилируйте файл .class, как вы это сделали, и сохраните его как .java
- Создайте проект в Eclipse с этим java файлом, оригинальным JAR
как библиотека, и все ее зависимости
- Измените .java и скомпилируйте
- Получить измененный файл .class и поместить его снова в оригинал
JAR.
Ответ 2
Используйте редактор байт-кода, например:
http://set.ee/jbe/
Будьте осторожны, потому что вам нужны очень хорошие знания из байт-кода Java.
Вы также можете изменить класс во время выполнения с отражением.
Ответ 3
Я добавил несколько кодов и сохранил файл .class.
Что вы видите в JD EClipse Decompiler - декомпилированное представление байтового кода в файле .class. Несмотря на то, что вы меняете текст, он не будет влиять на код байта.
Ответ 4
когда вы декомпилируете и изменяете код, который вы должны поместить в корневую папку вашего проекта eclipse, и проверьте свой класс в папке bin, которая находится на том же уровне, что и src. затем откройте оригинальную банку с помощью zip-инструмента (7zip для этого хорошо) и поместите модифицированный класс в тот же пакет внутри банки.
Ответ 5
Используйте java assist библиотеку Java для управления байт-кодом Java (файл .class) приложения.
- > Spring, Hibernate, EJB, используя это для реализации прокси-сервера
- > мы можем байт-код манипулировать, чтобы выполнить некоторый программный анализ
- > мы можем использовать Javassist для реализации прозрачного кеша для возвращаемых значений метода, перехватывая все вызовы методов и делегируя только супер-реализацию при первом вызове.
Ответ 6
Вы можете изменить код при его декомпиляции, но его нужно перекомпилировать в файл class
, код декомпилятора выводит java
код, он должен быть перекомпилирован с тем же путём классов, что и исходный jar
/class
файл
Ответ 7
Насколько я смог узнать, нет простого способа сделать это. Самый простой способ - фактически не преобразовать файл класса в исполняемый файл, а обернуть исполняемый пусковой механизм вокруг файла класса. То есть, создайте исполняемый файл (возможно, исполняемый скриптовый файл на основе ОС), который просто вызывает класс Java через командную строку.
Если у вас действительно есть программа, которая делает это, вы должны изучить некоторые из автоматических установщиков там.
Вот как я нашел:
[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]`
Ответ 8
Вы можете использовать любой декомпилятор для декомпиляции файла.
Когда-то я столкнулся с проблемой simillar, где у меня не было исходного кода приложения, и мне пришлось внести очень небольшое изменение в файл.
Ниже приведено то, что я сделал:
-
Извлечен файл класса из jar
-
Открыл его в декомпиляторе (я использую JD GUI, вы можете легко получить его из многих ресурсов в Интернете)
Вы можете загрузить его из здесь
-
Фактически вы можете просматривать все файлы в банке с помощью JD GUI.
- Сделал изменения в файле, который я хотел, и скопировал весь код из этого файла
- Создал новый проект в eclipse только с этим классом (с той же структурой пакета, что и в банке), при условии, что исходная банка является библиотекой и всеми другими зависимостями.
- Скомпилированный класс, ввел файл .class обратно в банку из папки bin моей рабочей области.
- Протестировал мое изменение, отпраздновал его, потягивая чашку кофе:)
Ответ 9
Когда-нибудь нам нужно скомпилировать один файл из тысячи файлов, чтобы устранить проблему. В таком случае можно создать такую же структуру папок, как путь к классу, декомпилировать файл в java или скопировать java файл из исходного кода. Внесите необходимые изменения, скомпилируйте один конкретный файл в класс со всеми зависимостями/классами на месте и, наконец, замените файл класса. Наконец, перезапустите контейнер. Когда война взорвана, файл не будет заменен.