IDEA has a great built-in feature - decompiler. It works great.I can copy source code, but I cannot find option to extract all decompiled java classes to java files.
This project has a lot of java classes and packages, so I will be to long to copy this manually.
Does anyone know how to extract to java source files.
Thx
As of August 2017 and IntelliJ V2017.2, the accepted answer does not seem to be entirely accurate anymore: there is no fernflower.jar to use.
The jar file is called java-decompiler.jar and does not include a main manifest... Instead you can use the following command (from a Mac install):
java -cp "/Applications/IntelliJ IDEA.app/Contents/plugins/java-decompiler/lib/java-decompiler.jar" org.jetbrains.java.decompiler.main.decompiler.ConsoleDecompiler
(you will get the wrong Usage command, but it does work).
Follow instructions for IntelliJ JD plugin. Or see an excerpt from the instructions below.
java -jar fernflower.jar [<source>]+ <destination>
+ means 1 or more times
<source>: file or directory with files to be decompiled. Directories are recursively scanned. Allowed file extensions are class, zip and jar.
<destination>: destination directory
Example:
java -jar fernflower.jar -hdc=0 -dgs=1 -rsy=1 -lit=1 c:\Temp\binary\ -e=c:\Java\rt.jar c:\Temp\source\
Be aware that if you pass it a ".jar" file for the source, it will create another ".jar" file in the destination, however, within the new ".jar" file, the files will be .java instead of .class files (it doesn't explode the jar).
UPDATE
People ask me: How do I get the fernflower.jar?
If you have any IntelliJ product installed, chances are that you already have the Fernflower decompiler on your computer. IntelliJ IDEA comes with Java Bytecode Decompiler plugin (bundled) which is a modern extension of Fernflower.
Locate the file in ${IntelliJ_INSTALL_DIR}\plugins\java-decompiler\lib\java-decompiler.jar (example: C:\Program Files\JetBrains\IntelliJ IDEA 2018\plugins\java-decompiler\lib).
Copy it somewhere and rename to fernflower.jar (optional).
This JAR is not executable, so we can't run it using java -jar. However something like this works:
java -cp fernflower.jar org.jetbrains.java.decompiler.main.decompiler.ConsoleDecompiler [<source>]+ <destination>
org.jetbrains.java.decompiler.main.decompiler.ConsoleDecompiler is the class that contains the main method to run the decompiler.
Example:
mkdir output_src
java -cp fernflower.jar org.jetbrains.java.decompiler.main.decompiler.ConsoleDecompiler -hdc=0 -dgs=1 -rsy=1 -lit=1 ./input.jar ./output_src
If you don't have IntelliJ products installed, either download it now (available on jetbrains.com) or make your own decompiler executable from sources (available on Github).
Open an existing project or create a new one.
Go to Project structure settings > Libraries. Add the jar you want to decompile in libraries by clicking the + symbol.
Go to the Project tool window shown on the left. Search for jar name that you added in the previous step. Navigate to the desired class or package.
You can see the decompiled java files for that jar.
You could use one of these (you can both use them online or download them, there is some info about each of them) :
http://www.javadecompilers.com/
The one IntelliJ IDEA uses is fernflower, but it can't handle recent things - like String/Enum switches, generics (didn't test this one personally, only read about it), ...
I just tried cfr from the above website and the result was the same as with the built-in decompiler (except for the Enum switch I had in my class).
Try
https://github.com/fesh0r/fernflower
Download jar from
http://files.minecraftforge.net/maven/net/minecraftforge/fernflower/
Command :
java -jar fernflower.jar -hes=0 -hdc=0 C:\binary C:\source
Place your jar file in folder C:\binary and source will be extracted and packed in a jar inside C:\source.
Enjoy!
The decompiler of IntelliJ IDEA was not built with this kind of usage in mind. It is only meant to help programmers peek at the bytecode of the java classes that they are developing. For decompiling lots of class files of which you do not have source code, you will need some other java decompiler, which is specialized for this job, and most likely runs standalone, like jad, fernflower, etc.
Some time ago I used JAD (JAva Decompiler) to achieve this - I do not think IntelliJ's decompiler was incorporated with exporting in mind. It is more of a tool to help look through classes where sources are not available.
JAD is still available for download, but I do not think anyone maintains it anymore: http://varaneckas.com/jad/
There were numerous plugins for it, namely Jadclipse (you guessed it, a way to use JAD in Eclipse - see decompiled classes where code is not available :)).
I use JD-GUI for extract all decompiled java classes to java files.
Someone had gave good answers. I made another instruction clue step by step.
First, open your studio and search. You can find the decompier is Fernflower.
Second, we can find it in the plugins directory.
/Applications/Android Studio.app/Contents/plugins/java-decompiler/lib/java-decompiler.jar
Third, run it, you will get the usage
java -cp "/Applications/Android Studio.app/Contents/plugins/java-decompiler/lib/java-decompiler.jar" org.jetbrains.java.decompiler.main.decompiler.ConsoleDecompiler
Usage: java -jar fernflower.jar [-<option>=<value>]* [<source>]+ <destination>
Example: java -jar fernflower.jar -dgs=true c:\my\source\ c:\my.jar d:\decompiled\
Finally, The studio's nest options for decompiler list as follows according IdeaDecompiler.kt
-hdc=0 -dgs=1 -rsy=1 -rbr=1 -lit=1 -nls=1 -mpm=60 -lac=1
IFernflowerPreferences.HIDE_DEFAULT_CONSTRUCTOR to "0",
IFernflowerPreferences.DECOMPILE_GENERIC_SIGNATURES to "1",
IFernflowerPreferences.REMOVE_SYNTHETIC to "1",
IFernflowerPreferences.REMOVE_BRIDGE to "1",
IFernflowerPreferences.LITERALS_AS_IS to "1",
IFernflowerPreferences.NEW_LINE_SEPARATOR to "1",
**IFernflowerPreferences.BANNER to BANNER,**
IFernflowerPreferences.MAX_PROCESSING_METHOD to 60,
**IFernflowerPreferences.INDENT_STRING to indent,**
**IFernflowerPreferences.IGNORE_INVALID_BYTECODE to "1",**
IFernflowerPreferences.VERIFY_ANONYMOUS_CLASSES to "1",
**IFernflowerPreferences.UNIT_TEST_MODE to if (ApplicationManager.getApplication().isUnitTestMode) "1" else "0")**
I cant find the sutialbe option for the asterisk items.
Hope these steps will make the question clear.
2022 UPDATE
Like any experienced developer who's being honest, I have to admit it -- I'm lazy. More is less and less is better when it comes to typing. The answers from #naXa and #yan are fine, except for having to open a terminal and type :-(
To decompile a jar right from within intellij, create a reusable JAR Application run configuration:
Copy java-decompiler.jar to a folder in your project (I used lib). Get from:: Windows: C:\Program Files\Intellij\plugins\java-decompiler\lib; or from github (documentation is here)
Copy source jar or class files to same folder
Create a run configuration with settings like these:
Path to JAR: browse to java-decompiler.jar
Program arguments: -hdc=0 -dgs=1 -rsy=1 -lit=1 your.jar lib
Working directory: lib
JRE: 11
In this case, your.jar is the source and lib is the output directory. Save it, run it, and watch it do its thing :-)
Need to do it again with different class files or jars? Duplicate the run config and update Program arguments.
---- package jar (java) jar -cvfM0 test.jar
---Decompile jar(class)>>>>>>>>>jar(java) java -cp "C:\Program Files\JetBrains\IntelliJ IDEA 2020.1\plugins\java-decompiler\lib\java-decompiler.jar" org.jetbrains.java.decompiler.main.decompiler.ConsoleDecompiler -dgs=true C:\ Users\luo\Desktop\sf1\pxks\test.jar C:\Users\luo\Desktop\sf1
Unzip manually
Or use the following command to decompress
find the path
cd..
decompress
jar -xvf test.jar
Reference http://t.csdn.cn/3YLK4
Related
I'm curious about Apache commons-io, why do they include a sources-jar inside the code package. We will not compile the program like so :
javac -cp .;.\lib\commons-io-2.4-sources.jar myCode.java
But we compile it like this :
javac -cp .;.\lib\commons-io-2.4.jar myCode.java
So why do the libraries also include a -sources jar in the download code ? I'm guessing it's for studying the source code, if we want to add/improve ?
The source JAR is so you can read the code is you want to. If you use an IDE, it can know to down load this JAR and if you look at a class in it, it will show your the source. esp useful when debugging a program. If you are not using an IDE, you can unpack the source and read it to understand what it is doing.
The reason the source is not included in the compiled JAR is so it can be easily dropped if all your are doing is running the program e.g. in production.
I have been doing a coding exercise inside the IntelliJ IDEA Community Edition 14 IDE, using OpenJDK.
The project is split over 4 .java files all in the same package.
My end goal is to run this in the terminal/bash (I use System.console().readLine() which doesnt play nicely in the IDE's console).
I've tried navigating to the directory where these 4 files reside (they all reside in the same dir) and tried:
javac -classpath . BibliotecaApp.java Book.java BookManager.java LibraryDB.java
This creates 4 corresponding .class files fine.
The Main is in bibliotecaApp.java/class, so I try run it by:
java BibliotecaApp
But I get the error
Exception in thread "main" java.lang.NoClassDefFoundError: BibliotecaApp (wrong name: com/twu/biblioteca/BibliotecaApp)
Plus about 13 lines of specifics.
Now googling this error seems to be a class path problem, and this is where I get stuck.
From places I've read, usingecho $PATH gives me:
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
This is still from the directory of the .java files above.
That path means nothing to me. I have no idea what it is or what it does, or what even a classpath is! Theres alot of resources out there on setting a classpath, but they aren’t helping me because I don't know what it's meant for.
That was a dead end for me. I tried to create a .jar instead using IDEA's Build Artifacts as seen HERE. It created a .jar file but when I navigate to that directory and try run it via:
java -jar biblioteca_jar
I get
Error: Invalid or corrupt jarfile biblioteca_jar
Another issue is that in the file explorer, the file actually comes out as biblioteca.jar, but ls on that dir shows biblioteca_jar. Is that normal?
The code is on my GitHub if that helps anything
https://github.com/botagar/twu-biblioteca-JohnGeddes
Based on your compiler step, change this
java BibliotecaApp
to
java -cp . BibliotecaApp
Which will add the current directory to the classpath for the java runtime environment. See also the Oracle Technote Setting the Class Path.
A jar file is a kind of zip, and should have a .jar extension. So this
java -jar biblioteca_jar
should probably be
java -jar biblioteca.jar
And you can check if the file is valid with any zip archive reader. Including jar itself,
jar tvvf biblioteca.jar
Edit
Based on your comments below,
cd ~/Documents/ThoughtWorks Uni/TWU_Biblioteca-master/src/
and then
java -cp . com.twu.biblioteca.BibliotecaApp
I'm currently a student at a high school, and I found a game programming competition for a club called FBLA. I had a few questions about the competition, and so I emailed them.
I made a post earlier on Computer Science Stack Exchange, where you can view here.
Now after receiving feedback from the question, someone commented that I should post my next question on this website.
My question is that how would I be able to package a Java JAR file with the native libraries, and then create an EXE out of it, so it will be a stand alone?
In my theory, I would have to create the jar, and put the required native files when a person installs java on their machine, into that JAR file, and then I can use a program such as FatJar or JSmooth.
If I'm wrong, or how I could understand a bit more on how jars are ran, it would help considerably.
Update Nov. 8, 2014
I finally got back around to messing with it, and I downloaded Launch4j. I set up and did everything with it, and I make an executable, which contains all of java's core native files. I uninstalled all of my programs dealing with java, and when I went to run it, it still required java.
Once again to state what I need to happen:
What needs to happen is the executable will be able to run even if there's not any version of Java installed on the judge's computer.
I would reccomend you use launch4j. http://launch4j.sourceforge.net
I've used it for some larger projects and it worked very well.
It can encapsulate your jar, dependencies and even a JRE into a windows in executable. It has a GUI or you can run from the command line.
Checkout Packr, created by libGDX team: https://github.com/libgdx/packr
To make your jar executable, you specify the main class of your application, any extra jar files it may require and so on in the jar's manifest file:
Main-Class: MyAppMain
Class-Path: MyLib.jar
Then you use the jar utility from the Java SDK to package your classes and resource files, specifying the m option and the name of your manifest file:
jar cvfm MyApp.jar MyApp.mf *.class *.gif
This will result in the creation of MyApp.jar. Now, if you type
java -jar MyApp.jar
the Java launcher will read the manifest from MyApp.jar, place that file and MyLib.jar on classpath and invoke the main method from the class MyAppMain.
Now, if your Java app needs native libraries, you also need to specify the java.library.path property pointing to the directory(ies) holding those:
java -Djava.library.path=.\bin -jar MyApp.jar
For more info and alternative solutions, refer to my article.
first off let me start by saying I am completely new to Java, but to give you an idea of how new; I started reading lots of books, examples and so forth and began programming Java using Eclipse about 2 months ago. However, I found a really cool bit of advise about using notepad and the terminal to program instead. Kinda crazy for a newbie to go the hard route, but I love a challenge and I'm serious about learning.
So, In Eclipse I had a really good grasp of how to import, add jars compile etc. When I started using pico and using the terminal (I'm running ubuntu) to compile all went really well, until I wanted to use packages. I've spent two days pulling my hair out because no matter what I do I can't figure it out.
I'm trying to use the acm.jar (which I have many times in Eclipse) however I'm completely lost on how to use it when compiling from the javac in terminal.
So what I'm asking for, is for someone to explain the process getting my jar file to work.
All I'm using to create my java programs is the pico (or notepad) and the javac in the terminal.
To compile and run a java class using external libraries, you have to add that library to the classpath. The classpath is the set of places where the java compiler and the JVM look to find any external libraries/classes that it needs during the process of compiling/executing.
Setting the classpath can be done in 2 ways:
Set an environment variable called CLASSPATH
Set it when your run javac/java
Setting the classpath when running javac/java is done like this:
javac -cp path/to/jar1:path/to/jar2:path/to/jar3:path/to/dirContainingClasses
yourMainClass.java
To run:
java -cp path/to/jar1:path/to/jar2:path/to/jar3:path/to/dirContainingClasses
yourMainClass
: is used as a separator on Linux, for windows use ;
Assuming your source files are in src. Assuming you want your compiled classes to be in classes. Assuming your source files reference classes that are in lib/acm.jar:
javac -cp classes:lib/acm.jar -d classes src/com/foo/bar/MyClass.java
will compile the class com.foo.bar.MyClass and put the generated MyClass.class file in classes/com/foo/bar.
You need the acm.jar file in the classpath. That's what the -cp lib/acm.jar option does. You also need classes in the classpath, because MyClass probably references other classes that you have already compiled and that are in your classes directory.
To run your class, it has to be in the classpath, and acm.jar as well:
java -cp classes:lib/acm.jar com.foo.bar.MyClass
As you see, the classpath contains jar files, and directories containing the folder hierarchy which matches the package hierarchy.
I wouldn't use javac from the command line directly, though. Try using a real build tool, that will build all your classes at once, like Gradle or Ant. Maven is also very popular, but I hate it with passion.
I'm running snow leopard and I just wrote a Java class on eclipse. The eclipse project references a user library which itself points to a bunch of jar files I've got somewhere in the system. When I run the app through eclipse, everything goes smoothly.
Then I export the class as a jar file and try to run it form the terminal by typing:
java - jar myApp.jar
It throws a java.lang.NoClassDefFoundError exception, meaning that it can't find the libraries I try to reference.
Knowing that my user library jar files are in /Users/myname/tempJars, I also tried to either mention the classpath using the -cp option
(java -cp /Users/myname/tempJars -jar myApp.jar) or to directly reference it in the manifest file. Both attempts failed and the error is the same.
These libraries are Java 1.5 libraries, so I thought I should try and reference another java version by mean of the JAVA_HOME environment variable. I built the following script:
export JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/1.5/Home
export PATH=$JAVA_HOME/bin:$PATH
export CLASSPATH=$CLASSPATH:/Users/myname/tempJars
java -jar myApp.jar
Again, no good. I googled how to execute jars in snow leopard, found the 32/64 bit big deal in some places and even tried executing with the -d32 option, but still to no avail.
Since the same code executes just fine in eclipse, I'm pretty convinced it's just a matter of setting up the JVM so that it includes the user libraries correctly.
Could anyone help me with this?
Thanks in advance.
You need to list the JARs themselves out on the classpath, not just the directory containing them. (Listing the directory is for when you have unarchived .class files in the package hierarchy lying around)
You will probably need to do -cp /Users/myname/tempJars/libA.jar:/.../libB.jar
I believe some (but potentially not all) JVMs support wildcards so -cp /Users/myname/tempJars/* or some variant thereof may work.