Как изменить уже скомпилированный файл .class без декомпиляции?

Скачивание и использование декомпилятора Java -jar и -class procyon-decompiler

http-equiv=»Content-Type» content=»text/html;charset=UTF-8″>yle=»margin-bottom:5px;»>Теги:  Java  Декомпилировать  jar  class  орудие труда

Инструмент декомпиляции procyon-decompiler

Друзья, которые изучают Java-разработку, обязательно столкнутся со всевозможными проблемами.Изучение чужого кода — один из способов улучшить свою собственную технологию кода. Но, глядя на бесцветный текст * .class, у меня кружится голова. Да и не компилируется, работоспособность очень низкая.

Итак, я нашел программный декомпилятор Java, но проблема возникла снова. Это программное обеспечение может поддерживать только JDK1.7 и ниже. Итак, я нашел программу, которая отлично решила проблему несовместимости версий.

Во-вторых, использование процион-декомпилятора

Откройте командную строку

1.Win+RОткрытая функция бега

2. Введите «cmd» и нажмите Enter.

3. Затем введите

Формула: java -jarАбсолютный путь проциона-декомпилятора -jar Хотите декомпилировать абсолютный путь к файлу -o Абсолютный путь к выходной папке

Затем вы увидите, что файлы * .jar декомпилированы в кучу файлов java.

Если вы не поняли, читайте дальше.

————————Разделяющая линия————————

Например, это будет декомпилировать файл * .jar. Например, абсолютный путь к procyon-decompiler-0.5.34 равен G:\download

Абсолютный путь к файлу Demo.jar, который я хочу декомпилировать: G:\re\Demo.jar

Абсолютный путь вывода папки формата * .java после декомпиляции равен G:\out

Введите декомпилировать и запустить выполнение в командной строке Введите java -jar G: \ download \ procyon-decompiler-0.5.34.jar -jar G: \ re \ Demo.jar -o G: \ out

Если все еще не поняли, ответьте, я максимально помогу!

Интеллектуальная рекомендация

1. Для реальных сигналов (для понимания): A (ω) является соотношением амплитуды выходного сигнала и амплитуды входного сигнала, называемого частотой амплитуды. Φ (ω) — это разница межд…

Один. вести Многие люди задавали некоторые вопросы о создании проекта Flex + LCDS (FDS) в сообщениях и группах. Из-за операции ее трудно четко объяснить, поэтому я написал простой учебник (я обещал эт…

package com.example.phonehttp; import android.os.Bundle; import android.os.Handler; import android.app.Activity; import android.widget.ScrollView; import android.widget.TextView; public class MainActi…

Он предназначен для реализации подкласса того же родительского класса с родительским классом. Полиморфизм Один и тот же ссылочный тип использует разные экземпляры для выполнения разных операций; Идея …

тема: Объедините два упорядоченных слоя в новый заказанный список и возврат. Новый список состоит из всех узлов двух связанных списков, данных сплавным. Пример: Анализ: два связанных списка состоит в …

Вам также может понравиться

D. Самая ценная строка Пример ввода 2 2 aa aaa 2 b c Образец вывода aaa c На самом деле, будучи задетым этим вопросом, вы должны быть осторожны. После инвертирования строки, если две строки имеют один…

Given a 2D integer matrix M representing the gray scale of an image, you need to design a smoother to make the gray scale of each cell becomes the average gray scale (rounding down) of all the 8 surro…

calc () может быть очень незнакомым для всех, и трудно поверить, что calc () является частью CSS. Поскольку он выглядит как функция, почему он появляется в CSS, поскольку это функция? Этот момент такж…

Основываясь на дереве регрессии, сформированном CART, а также на предварительной и последующей обрезке дерева, код выглядит следующим образом:…

Откат Обновление в режиме онлайн с версии Centos (CentOS Linux версии 7.3.1611 (Core) до CentOS Linux версии 7.5.1804 (Core)) # ошибка соединения yum-ssh после обновления yexpected key exchange group …

17 ответов

Лучший ответ

jd-gui — лучший декомпилятор на данный момент. он может обрабатывать новые функции Java по сравнению с пылящим JAD.

215

DarenW
19 Окт 2013 в 06:20

Как указано @MichaelMyers, используйте

Чтобы получить код сборки JVM. Вы также можете перенаправить вывод в текстовый файл для лучшей видимости.

15

Nilashish C
16 Фев 2018 в 18:51

Вам нужен декомпилятор Java, для этого вы можете использовать инструмент командной строки . Кроме того, Java Decompiler HOW-TO описывает, как можно декомпилировать файл класса.

7

Drew Frezell
17 Сен 2008 в 00:05

То, что вы ищете, — это декомпилятор java. Я рекомендую JAD http://www.kpdus.com/jad.html. Это бесплатно для тех, кто не коммерческое использование и выполняет свою работу.

Примечание: это не сделает код точно таким же, как был написан. то есть вы потеряете комментарии и, возможно, имена переменных, поэтому это будет немного сложнее, чем просто читать обычный исходный код. Если разработчик действительно скрытный, он также запутает свой код, что сделает его еще более трудным для чтения.

2

David Beleznay
17 Сен 2008 в 00:05

Cpuguru, если ваш апплет был скомпилирован с использованием javac 1.3 (или менее), лучшим вариантом будет использование Jad.

К сожалению, последний JDK, поддерживаемый JAD 1.5.8 (14 апреля 2001 г.), — это JDK 1.3.

Если ваш апплет был скомпилирован с помощью более позднего компилятора, вы можете попробовать JD-GUI: этот декомпилятор в процессе разработки, тем не менее, в большинстве случаев он генерирует правильные исходные коды Java для классов, скомпилированных с помощью JDK 1.4, 1.5 или 1.6.

DarenW, спасибо за ваш пост. JD-GUI еще не лучший декомпилятор … но я над этим работаю :)

2

Emmanuel Dupuy
23 Дек 2008 в 20:56

2

Karthikeyan Subramanian
27 Сен 2013 в 14:05

Использование Jad для декомпиляции, вероятно, является лучшим вариантом. Если код не был запутан, результат будет нормальным.

2

Rasmus Faber
25 Окт 2018 в 16:07

Это скомпилированный код, вам понадобится декомпилятор, например JAD: http://www.kpdus.com /jad.html

1

cynicalman
17 Сен 2008 в 00:03

Вам нужно использовать декомпилятор. Другие предлагали JAD, есть другие варианты, JAD — лучший.

Я повторю комментарии, которые вы можете немного потерять по сравнению с исходным кодом. Особенно забавно будет выглядеть, если в коде используются дженерики из-за стирания.

1

Zac Gochenour
17 Сен 2008 в 00:12

Обязательно JAD и / или JADclipse Eclipse plugin.

1

John Gardner
17 Сен 2008 в 00:35

Если файл класса, который вы хотите изучить, является открытым исходным кодом, вы не должны декомпилировать его, а вместо этого прикрепите исходные файлы непосредственно в вашу среду IDE. таким образом, вы можете просто просмотреть код некоторого библиотечного класса, как если бы он был вашим собственным

1

arturh
13 Май 2009 в 14:54

Как было предложено, вы можете использовать JAD для его декомпиляции и просмотра файлов. Чтобы упростить чтение, вы можете использовать плагин JADclipse для eclipse, чтобы напрямую интегрировать JAD в eclipse, или использовать DJ Java Decompiler, который намного проще в использовании, чем JAD из командной строки.

amitwadhwaamitwadhwa
17 Сен 2008 в 00:07

JAD — отличный вариант, если в результате вам нужен читаемый код Java. Если вы действительно хотите вникнуть во внутреннее устройство формата файла , вам понадобится . Он связан с JDK и позволяет «декомпилировать» шестнадцатеричный байт-код в читаемый ASCII. Создаваемый им язык по-прежнему является байт-кодом (не похожим на Java), но он довольно читабелен и чрезвычайно поучителен.

Кроме того, если вы действительно захотите, вы можете открыть любой файл в шестнадцатеричном редакторе и напрямую прочитать байт-код. Результат идентичен использованию .

Daniel Spiewak
17 Сен 2008 в 00:09

Декомпилировать Applet.class не нужно. Исходный код общедоступных классов Java API поставляется с JDK (если вы решите установить его) и лучше читается, чем декомпилированный байт-код. Вы можете найти его в сжатом виде в src.zip (находится в папке установки JDK).

Arno
17 Сен 2008 в 00:45

CFR — еще один декомпилятор java — отличный декомпилятор для современной Java, написанный на i Java 6.

tidbeck
18 Янв 2017 в 16:54

Вы также можете использовать доступные онлайн-декомпиляторы Java. Например, http://www.javadecompilers.com

2

Prachi Sharma
23 Фев 2018 в 14:50

Если вы не против чтения байт-кода, javap должен работать нормально. Это часть стандартной установки JDK.

81

Michael Myers
17 Сен 2008 в 00:08

Обработка конкретных фич языка

Здесь я просто рассмотрела несколько важных конструкций языка и сравнила то, насколько качественно они обрабатываются разными декомпиляторами.

Краткое резюме этого параграфа показано в таблице ниже. При этом надо не забывать, что результаты, показанные jadx, не вполне релевантны. Для jadx в следующей секции проведен отдельный разбор, в котором в качестве подопытного взят Android прект.

Для начала рассмотрим конструкции, с обработкой которых не справился только один из инструментов.

for-each

FullInstructionSequence.java

Fernflower всегда раскрывает конструкции через итераторы. Причем делает он это не вполне корректно.

Например, здесь засоряет внешнюю область видимости, из-за чего может происходить переопределение переменной. К тому же, у итератора не указан параметр типа, что приводит к в четвертой строке:

Тернарный оператор при индексации массива

SSAConstructorSparseEx.java

Стандартная и очень неприятная ошибка Procyon’а. Разобраться, что хотел сказать автор, не имея исходного кода под рукой, — задача не очень тривиальная, особенно в более сложных случаях:

Статическое поле в интерфейсе

IFernflowerPreferences.java

Загадочная ошибка, воспроизводящаяся только при использовании Procyon. Атрибут , указанный вместо в определении , порождает ошибку:

9 best Java Decompiler to be used

There are many best Java Decompiler which provide offline services. You can easily download these applications from the internet in order to get the work done. Here are some of the best java Decompiler on the internet today those are friendly to work with and have a good user interface.

1) JD Project

JD Project is one of the most frequently used best java decompiler offline. It is developed to decompile Java 5 and beyond, which currently goes up to Java 8. It is available for Windows, Mac, and Linux and is the best decompiler for eclipse and IntelliJ as it provides a plugin for each platform separately. This proves to be extremely useful during the debugging process.
It uses the JD- GUI. This is an easy to use and an interactive graphical interface.

2) Cavaj Java Decompiler

This is another great tool for converting bytecodes to Java source code. If you are a Windows user, then Cavaj is the best option available for you out there. It is simple to use and decompiles any given Java class file. One major drawback for this application is that it lacks Syntax Highlighting. It is also not available for Mac and Linux Operating softwares. In short, this is a standalone Windows application that converts bytecodes into class code.

3) DJ Java Decompiler

This is yet another standalone Windows Application. It is available for Windows XP, Windows 2003, Windows Vista, Windows 7, Windows 8, Windows 8.1 and Windows 10. It can easily decompile complex Java applets and binaries to produce accurate source code. There are drag and drop features for smooth working, so you can decompile .class files on your computer’s hard disk or on a network drive that you have connected.

4) JBVD

JBVD stands for Java Bytecode Viewer and Decompiler. It is based on the Javassist open source library. Like the others, this application too is available only for Windows users. It is one of the most powerful bytecode viewer and decompiler. Of course, this program needs Java to be installed on your computer to work JBVD can thus be used both, as a Java viewer and a decompiler.

5) AndroChef Java Decompiler

If you are on the lookout for a Java decompiler to view and analyze bytecode then AndroChef should be your preferred option. It is capable of easily converting Java .class files and applets into Java source code. It is simple and easy to use, however it is only available on the Windows Operating System. With Androchef, you can decompile apk. dex, jar, and java class files.

6) Procyon

It is one of the most popular open source Java decompiler. One of its most amazing features is the ability to deal with Java 8. Procyon can handle all those features which were launched with Java 5 to the latest version to Java. Due to this, Procyon can be used as an alternative where other java versions fail. It can also easily deal with other features such as local classes, annotations, Enum declarations, and Lamdas in Java 8.

7) CFR Decompiler

This is another such decompiler that was developed to deal with the latest features and updates in Java programming. It can easily decompile the latest Java features such as Lamdas and Switch Statement. This means if you are using Java 8, you can be at peace with yourself. The only downside here is that this decompiler is not an open source program. However, it has a command line tool that makes the decompiling process faster and even more efficient.

8) FernFlower

Apart from the decompilers mentioned above, the ones mentioned here are still in nascent stages and are under development. Fernflower is one of those. Fren is an analytical decompiler for Java and has recently been made open sourced. The software renames all the obfuscated symbols and puts them into a JAR file in the end. FrenFlower is used to decompile .class, zip and JAR file extensions.

9) Krakatau

It is an interesting decompiler as it has been written in Python. It is still in the development stage. However, it contains three tools: a decompiler and disassembler for Java class files and an assembler to create class files. However, one major drawback here is that it does not support all Java 8 features.

Conclusion- Which is best Java Decompiler?

If you are looking out for a best Java decompiler then you can try out any of the ones mentioned above. Just download them and try them out. You could share your experience in the comments below and even if you are aware of other amazing decompilers, then you could share those two. I would love to add it to the above list. You can also check out detailed tools section for more content.

Java Decompiler Software
$0

5

Summary

Check these 9 best offline Java decompiler which help you manage the codes and convert it as required. You can download these top Java decompilers and install it on your system.

Класс record из Java 16

Класс record — одна из самых упоминаемых фич новой версии Java. Она позволяет быстро писать иммутабельные POJO-классы, с ней не нужно повторять одинаковые методы: геттеры, toString(), equals() и hashCode().

Напишем старым методом класс Student c двумя полями — именем и названием факультета:

У класса всего два поля, но много бойлерплейтного кода.

Чтобы проверить, как работает класс, сделаем два объекта, выведем их в консоль и сравним:

Так код будет выглядеть в консоли:


Скриншот: Мария Помазкина / Skillbox Media

До того как в Java появился класс record, нам помогал плагин и библиотека Lombok — она позволяет указать аннотациями, какие методы нужно сгенерировать для класса на этапе компиляции. С ней класс может выглядеть так:

@Data генерирует геттеры, сеттеры, equals(), hashCode() и toString(). @RequiredArgsConstructor создаёт конструктор с итоговыми параметрами класса и добавляет аргументы в порядке объявления. Такая запись намного компактнее, но это даётся ценой лишней зависимости и плагина для среды разработки.

Если запустить тестовый код, видно, что формат преобразования в строку отличается, но в остальном всё работает одинаково:


Скриншот: Мария Помазкина / Skillbox Media

Класс record избавляет от бойлерплейтного кода. Для этого не нужны внешние плагины, достаточно встроенных возможностей языка. Чтобы создать класс, нужно указать только два поля — конструктор, геттеры, equals(), hashCode() и toString() уже включены в класс.

Вот как класс выглядит в новой записи. Сэкономили сорок строк:

Запустим тестовый код и увидим тот же результат:


Скриншот: Мария Помазкина / Skillbox Media

У геттеров больше нет приставки get., к методу мы обращаемся по имени переменной:

Если нужна валидация данных, конструктор можно расширить или написать свой:

Расширенный конструктор:

Кастомный конструктор:

При этом стандартный конструктор со всеми параметрами класса остаётся доступным.

У класса record есть ограничения и особенности:

  • все объявленные поля получают модификатор final;
  • все поля класса объявляются в заголовке, дополнительные объявить нельзя:
  • можно объявлять static-поля класса;
  • класс record неявно объявлен как final, поэтому его нельзя наследовать;
  • он не может быть абстрактным и наследовать другие классы;
  • можно добавлять свои конструкторы;
  • для конструктора можно использовать проверку аргументов;
  • можно переопределить стандартные методы — геттеры, toString(), equals() и hashCode();
  • можно добавлять статические и нестатические методы.

Благодаря компактному синтаксису класс records несложно обновлять локально:

Это упрощает код — структура данных хранится в этом же методе, нет необходимости создавать её в другом месте и слишком расширять область видимости.

Подробнее о сервере и Java EE

Сервер приложений Java EE Libercat основан на исходном коде проекта Apache Tomcat, поясняют CNews в Bellsoft. Разработчиками отечественного программного сервера заявлено полное соответствие стандарту Java EE, что гарантирует переносимость приложений, написанных в соответствии со спецификацией, между различными серверами приложений и потенциально снижает издержки при миграции. Клиентам Bellsoft обещает своевременный выпуск обновлений Libercat, включающих оптимизации производительности, устранение уязвимостей и критических дефектов.

Java EE представляет собой набор спецификаций языка Java, описывающих архитектуру платформы для задач средних и крупных предприятий. Сервер приложений Java EE – специальное ПО, которое реализует эти спецификации и позволяет выполнять разработанные в соответствии с ними бизнес-приложения. В концепции трехуровневой архитектуры он выполняет роль «связующего звена» между слоями клиента и данных.

Apache Tomcat – это контейнер Java-сервлетов (программных компонентов, расширяющих сервер) и HTTP веб-сервер, разрабатываемый под наздором Apache Software Foundation. Tomcat написан на языке Java. Исходный код ПО распространяется на условиях свободной лицензии Apache 2.0.

Скорость

Дисклеймер: еще раз замечаю, что это исследование не претендует на какую-либо научность.

Сравнение скорости работы было проведено достаточно топорно: проекты запускались на среднего размера джарниках по несколько раз, после чего выяснялось минимальное время работы.

Здесь приведены результаты для 100 итераций на JAR-файле размером 5.2M (JAR-файл, естественно, состоит только из файлов).

Время в секундах
Fernflower 74
CFR 43
Procyon 74

В следующей таблице — результаты для 15 запусков на JAR-файле в 14M.

Время в секундах
Fernflower 939
CFR 128
Procyon 573

По результатам можно предположить, что в этих декомпиляторах используются алгоритмы с разной асимптотикой. При этом CFR работает стабильно быстрее конкурентов, а на больших входных файлах Fernflower начинает довольно сильно тормозить. Впрочем, 14M — это очень много памяти для архива файлов и в реальности такие проекты попадаются довольно редко.

Запечатанные классы из Java 17

Sealed class дословно переводится как «запечатанный класс». В этом классе нужно сразу объявить список классов-наследников, потому что кроме них наследников быть не может. Это похоже на enum, только в разрезе наследования.

Посмотрим, как это выглядит в коде:

Классы Student, Teacher и Curator должны быть в том же пакете или модуле, что и Person. Кроме этого, у них обязательно должен быть один из модификаторов:

final, если класс запрещён к дальнейшему наследованию:

sealed, если наследование допустимо, но с заранее указанным списком наследников:

non-sealed, когда для класса нужно снять любые ограничения по наследованию:

У интерфейсов тоже может быть модификатор sealed:

С учётом record мы можем имплементировать интерфейс и записать класс Student:

Здесь record по умолчанию final, поэтому ограничения класса sealed соблюдены.

Запечатанные классы помогают установить ограничение на число наследников, когда их набор определён и его не собираются часто менять. Это похоже на перечисление (enum), но sealed class гибче, потому что одни ветки наследования можно открыть для расширения, а другие ограничить только для использования.

Example

  1. Implement the Loader interface:
Loader loader = new Loader() {
    @Override
    public byte[] load(String internalName) throws LoaderException {
        InputStream is = this.getClass().getResourceAsStream("/" + internalName + ".class");

        if (is == null) {
            return null;
        } else {
            try (InputStream in=is; ByteArrayOutputStream out=new ByteArrayOutputStream()) {
                byte[] buffer = new byte;
                int read = in.read(buffer);

                while (read > ) {
                    out.write(buffer, , read);
                    read = in.read(buffer);
                }

                return out.toByteArray();
            } catch (IOException e) {
                throw new LoaderException(e);
            }
        }
    }

    @Override
    public boolean canLoad(String internalName) {
        return this.getClass().getResource("/" + internalName + ".class") != null;
    }
};
  1. Implement the Printer interface
Printer printer = new Printer() {
    protected static final String TAB = "  ";
    protected static final String NEWLINE = "\n";

    protected int indentationCount = ;
    protected StringBuilder sb = new StringBuilder();

    @Override public String toString() { return sb.toString(); }

    @Override public void start(int maxLineNumber, int majorVersion, int minorVersion) {}
    @Override public void end() {}

    @Override public void printText(String text) { sb.append(text); }
    @Override public void printNumericConstant(String constant) { sb.append(constant); }
    @Override public void printStringConstant(String constant, String ownerInternalName) { sb.append(constant); }
    @Override public void printKeyword(String keyword) { sb.append(keyword); }
    @Override public void printDeclaration(int type, String internalTypeName, String name, String descriptor) { sb.append(name); }
    @Override public void printReference(int type, String internalTypeName, String name, String descriptor, String ownerInternalName) { sb.append(name); }

    @Override public void indent() { this.indentationCount++; }
    @Override public void unindent() { this.indentationCount--; }

    @Override public void startLine(int lineNumber) { for (int i=; i<indentationCount; i++) sb.append(TAB); }
    @Override public void endLine() { sb.append(NEWLINE); }
    @Override public void extraLine(int count) { while (count-- > ) sb.append(NEWLINE); }

    @Override public void startMarker(int type) {}
    @Override public void endMarker(int type) {}
};
  1. And call the method «decompile(loader, printer, internalTypeName);»
ClassFileToJavaSourceDecompiler decompiler = new ClassFileToJavaSourceDecompiler();

decompiler.decompile(loader, printer, "path/to/YourClass");

String source = printer.toString();

9 ответов

Вы можете выполнить следующие шаги, чтобы изменить свой класс Java:

  1. Декомпилируйте файл .class, как вы это сделали, и сохраните его как .java
  2. Создайте проект в Eclipse с этим Java-файлом, оригинальным JAR
    как библиотека и все ее зависимости
  3. Измените .java и скомпилируйте
  4. Получите измененный файл .class и поместите его снова в исходный
    JAR.

Используйте редактор байт-кода, например:

Будьте осторожны, потому что вам нужно очень хорошее знание байт-кода Java.

Вы также можете изменить класс во время выполнения с помощью переплетения байт-кода (например, AspectJ).

В JD EClipse Decompiler вы видите декомпилированное представление байтового кода в файле .class. Даже если вы измените текст, это не повлияет на байт-код.

Используйте библиотеку Java java assist для управления байт-кодом Java (файл .class) приложения.

— > Spring, Hibernate, EJB, использующий это для реализации прокси

— > мы можем манипулировать байт-кодом, чтобы выполнить некоторый программный анализ

— > мы можем использовать Javassist для реализации прозрачного кэша для возвращаемых значений метода, перехватывая все вызовы метода и делегируя только супер реализации при первом вызове.

Вы можете изменить код при декомпиляции, но его нужно перекомпилировать в файл , декомпилятор выводит , этот код должен быть перекомпилирован с тем же путем к классам, что и исходный / файл

Насколько мне удалось выяснить, простого способа сделать это не существует. Самый простой способ — на самом деле не преобразовать файл класса в исполняемый файл, а обернуть исполняемый модуль запуска вокруг файла класса. То есть создайте исполняемый файл (возможно, исполняемый файл сценариев для ОС), который просто вызывает класс Java через командную строку.

Если вы хотите, чтобы на самом деле была программа, которая это делает, вам стоит взглянуть на некоторые из автоматических установщиков.

Вот способ, который я нашел:

Вы можете использовать любой декомпилятор, чтобы сначала декомпилировать файл.

Однажды я столкнулся с подобной проблемой, когда у меня не было исходного кода приложения, и мне пришлось внести очень небольшое изменение в файл.

  1. Извлеченный файл класса из банки

  2. Открыл его в декомпиляторе (я использую JD GUI, вы можете легко получить его из многих ресурсов в интернете)
    Вы можете скачать его с здесь

  3. Вы можете просмотреть все файлы в банке с помощью графического интерфейса JD.

  4. внес изменения в файл, который я хотел, и скопировал весь код из этого файла
  5. Создал новый проект в eclipse только с этим классом ( с той же структурой пакета, что и в jar ), предоставил исходный jar в виде библиотеки и все другие зависимости.
  6. Скомпилировал класс, вставил файл .class обратно в папку jar из папки bin моего рабочего пространства
  7. Протестировал мое изменение, отпраздновал его, потягивая чашку кофе:)

Иногда нам нужно собрать один файл из тысячи файлов, чтобы решить проблему. В таком случае можно создать такую ​​же структуру папок, как путь к классу, декомпилировать файл в java или скопировать файл java из исходного кода. Внесите необходимые изменения, скомпилируйте один конкретный файл в класс со всеми зависимостями /классами и, наконец, замените файл класса. Наконец перезапустите контейнер. После того, как война взорвана, файл не будет заменен.

Поддержка и активность проекта

Fernflower

С одной стороны, этот декомпилятор используется в Intellij IDEA, что гарантирует жизнь и поддержку этого проекта.

С другой стороны, Fernflower — часть проекта Intellij IDEA. У самого декомпилятора нет даже отдельного репозитория на гитхабе (только упомянутое выше неофициальное зеркало, ссылка на которое — единственный способ подключить Fernflower к своему проекту как зависимость).

Если судить по репозиторию на гитхабе, активного добавления новых фич в этот проект не наблюдается. Последний коммит в случился 3 месяца назад (состояние на осень 2019). Точнее понять, что происходит с этим проектом, трудно, так как кодовая база является частью репозитория Intellij IDEA.

CFR

Код пишется одним человеком, но релизы происходят регулярно (по нескольку раз в год). На все замечания, отправленные мной автору на почту, он ответил в течение нескольких дней и исправил ошибки в течение недели-двух. Только за время написания этой статьи вышел новый релиз (0.147), в котором починена одна из упомянутых ошибок.

Также этот проект относительно быстро развивается, и поддержка новых фич появляется в нем довольно оперативно.

Procyon

Проект поддерживается, этим летом (2019) даже был новый релиз. Но в этом релизе не было добавлено никаких новых фич, только починены старые баги. В общем, создается впечатление, что проект не забыт, но развиваться он больше не будет.

jadx

Этот декомпилятор постоянно развивается, репозиторий и ишью-трекер на гитхабе очень живые и активные. 20 июня 2019 произошел релиз версии 1.0.0. Новые фичи и поддержка более актуальных версий DVM добавляются.

Количество ошибок при сборке результата декомпиляции

Суть сравнения в том, что все декомпиляторы были запущены на одном проекте, а результаты декомпиляции собраны. Это позволило получить общее представление о том, какие ошибки может допускать каждый из декомпиляторов и насколько вообще адекватен получающийся при декомпиляции код.

В этой секции jadx не рассматривается, так как он бросает 39 исключений при декомпиляции и, следовательно, в принципе не декомпилирует большое количество кода.

Для начала заметим, что есть три класса ошибок: синтаксические (их не выявлено ни одной, хотя еще несколько версий назад в CFR их было несколько); семантические ошибки, связанные с типами (неправильно выведенные параметры у дженериков, ненайденные методы, некорректные приведения типов), и все остальные семантические ошибки.

Причины, по которым ошибки, связанные с выведением типов, выделены в отдельную категорию:

  • декомпиляторы теоретически не способны полностью корректно восстановить типы;
  • эти ошибки встречаются чаще, чем все остальные вместе взятые;
  • они относительно мало влияют на читаемость кода.

К тому же, количество ошибок, связанных с выводом типов, примерно одинаково (хотя CFR все-таки проигрывает соперникам).

Из всего этого можно сделать вывод, что нам гораздо интереснее не связанные с типами ошибки.

Синтаксические Все семантические Связанные с типами Остальные
Fernflower 101 65 36
CFR 82 80 2
Procyon 79 61 16

В коде, сгенерированном с помощью Fernflower, таких ошибок больше всего, причем 34 из 36 — это ошибки вида . Две ошибки у CFR тоже связаны с переопределением переменных. В случае Procyon’а большинство (10 из 16) ошибок происходят из-за того, что переменная типа используется в качестве индекса массива. Это происходит из-за некорректной обработки тернарных операторов (подробнее этот случай рассмотрен в секции ниже).

Отдельно стоит заметить, что CFR — единственный из трех декомпиляторов, улучшивший свои показатели за последние 4 месяца. Раньше у него было 10 ошибок, не связанных с типами и 72 — про типы. Из этого можно предположить, что большое количество «типовых» ошибок у CFR связано с тем, что остальных ошибок у него меньше и, следовательно, больше пространства для неправильного вывода типов.

Результаты

По результатам сравнения можно сказать следующее:

CFR

Обгоняет конкурентов и по читаемости кода (лучше обрабатывает синтаксический сахар типа , и другие, при этом результат содержит меньшее количество семантических ошибок), и по скорости (особенно это заметно на файлах большого размера). Также CFR стабильно развивается и поддерживается разработчиком.

Из минусов — проект относительно молодой, разрабатывается одним человеком и, предположительно, довольно сырой (в одном из релизов произошла небольшая регрессия, которую, правда, быстро исправили; еще полгода назад результирующий код мог содержать синтаксические ошибки).

Procyon

Более надежный и стабильный, но почти не развивается. Из-за этого начал отставать от CFR в смысле поддержки фич Java 9 и старше. Также Procyon до сих пор содержит довольно маргинальные баги (обработка некоторых тернарных операторов и статических полей в интерфейсах).

Fernflower

Не очень подходит для наших задач. Проигрывает конкурентам по скорости и качеству результата (во всяком случае на необфусцированных данных). С другой стороны, Fernflower используется в Intellij IDEA, что дает некоторые гарантии того, что проект не умрет в ближайшем будущем.

jadx

Единственный достойный (если вообще не единственный) декомпилятор, предназначенный для Android. Дает неплохие результаты, но работает нестабильно (иногда декомпилирует байткод в корректный, но абсолютно нечитаемый код). Не поддерживает некоторые фичи языка (например, ) и некоторые инструкции DVM старше 37 версии. Для декомпиляции JAR файлов не подходит в принципе.

P.S. уже после написания этого текста, нашлась вот такая статья: очень подробное сравнение декомпиляторов. Статья формальная, научная, но оценивает декомпиляторы в основном со стороны корректности получающегося кода, не рассматривая такие метрики, как читаемость кода и скорость работы декомпилятора.

Switch-выражения из Java 14

Чтобы получить значение из switch-выражения, раньше приходилось создавать отдельную переменную и постоянно использовать break;. Вот как это выглядело:

В Java 14 появился новый формат записи, который помогает получать результат выбора и записывать выражение компактнее. Если перечислены все возможные варианты, ветка default теперь не нужна:

Но веткой default можно задать сообщение об ошибке:

Если в значение (case) нужно записать выражение, его заключают в фигурные скобки {} и для возврата значения используют ключевое слово yield:

Switch-выражениям не обязательно возвращать определённое значение:

Проект в «М.видео-Эльдорадо» и его промежуточные итоги

Тогда же, в декабре 2020 г., ритейлер зафиксировал увеличение скорости Java-разработки по итогам миграции на Liberica JDK, в том числе за счет применения сверхкомпактных контейнеров на базе Alpine Linux.

В феврале 2021 г. в рамках пресс-конференции «Будущее Java-платформы и итоги 2020 г. от Bellsoft, «М.видео-Эльдорадо» и АРПП «Отечественный софт» руководитель департамента по развитию технологической платформы ритейлера Александр Зеленюк заявил о 18-процентном приросте скорости разработки, позволившем, по его словам, существенно сократить сроки вывода на рынок новых услуг и быстро получать обратную связь о работе микросервисов.

«За два месяца мы разработали и внедрили стратегически важные для группы сервисы «последней мили»: доставка товаров в течение двух часов с помощью такси, доставка и выдача онлайн-заказов клиентам в шаговой доступности от дома, – рассказал Зеленюк. – Мы также реализовали для клиентов возможность бесплатно на такси уехать из магазина домой вместе с покупкой».

Рейтинг
( Пока оценок нет )
Понравилась статья? Поделиться с друзьями:
Все про сервера
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: