How are these classes able to access the default package (post-compile)? - java

This is taken from the bytecode of Minecraft. Most of the jar's classes are found in the default package, however there is another package, "net.minecraft.client", which has the main class (Minecraft.class) that runs the game loop, sets up OpenGL, etc. I don't have the source, but if I open up Minecraft.class in JD-Gui, it has the following import setup:
package net.minecraft.client;
import aaa;
import aai;
import ajq;
import ajv;
import akf;
import aki;
import aqx;
import aqz;
import ara;
import arb;
... (many more classes from the default package)
public abstract class Minecraft implements Runnable, mc {
...
}
How does this work? Let's say I have a folder with a similar setup (default classes that need to be accessed by other packages) and want to compile it with a batch file. What method of compiling could replicate this result?

This is taken from the source of Minecraft.
I don't think so. (EDIT: The question was edited to make this "bytecode" - which doesn't make much sense, as bytecode isn't Java source code. Anyway...)
How does this work?
It doesn't, fundamentally. The code you're looking at in JD-Gui isn't the original source code - it's code which represents the bytecode as accurately as JD-Gui is able to manage.
I strongly suspect the original source code does use packages, but then uses an obfuscator of some kind to rename the classes and put them in the default package. I strongly suspect this isn't the only kind of change which leaves valid bytecode which couldn't actually be directly compiled from valid source code. (For example, I strongly suspect there are method names which are valid in bytecode but not in source code.)
Let's say I have a folder with a similar setup (default classes that need to be accessed by other packages) and want to compile it with a batch file. What method of compiling could replicate this result?
You wouldn't. You'd have source code set up using packages (as all sane, non-trivial Java code does), compile it and then post-process the bytecode.

Related

Building reverse engineered project

I learn development for android, I would like to see how certain application is built, I also would like to adjust its UI controls positions for sole use.
So, I decompiled the application and try to build it with Eclipse bundle. I got an apk file built, but when I start it it produces the exception "java.lang.RuntimeException: Unable to get provider iching.android.contentprovider.DivinationProvider"
But I see the file src/iching/android/contentprovider/DivinationProvider.java which contains missing class definition:
package iching.android.contentprovider;
import android.content.ContentProvider;
import android.content.ContentValues;
import android.content.Context;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import iching.android.persistence.IChingSQLiteDBHelper;
public class DivinationProvider extends ContentProvider
{
How can I get compiled apk which can't find a class, used in it?
Why does not it find the class declared in properly placed source file?
UPDATE:
I found java compiler was disabled, so bin/classes remain empty on build finish
UPDATE2:
Yep there was a lot of errors when I enabled javac.
I give it a shot to answer your questions but i have to admit its half guessing since i dont see actual results of your decompiling/ running attempts:
0.) Make sure the app (.apk) you have runs as it is (e.g. "it works" as delivered from its producer)
1.) Since decompiling (even in Java) is not trivial as soon as there is complex (or "obfuscated") input data it is very likely the decompiled source will not compile.
=> In 99% of the cases decompiling is used to understand how something work using static code analysis rather than "just run it".
So "the lack of skills" of decompilers CAN lead to what you call "compiled apk which can't find a class, used in it". Mostly however because Class-dependencys were not decompiled correctly.
2.) Because it is not there. It is that simple. Assumed the decompiling worked properly (it looks as it would since you dont have any compile time issues) you are just missing the dependency iching.android.contentprovider. Recheck all of the 3th party librarys are getting attached to your final build-output (i assume a .apk file) correctly. Unfortunately i dont know how you are building your project.

Why do internal classes have to be imported?

In any IDE, when working with a class in a package and I need to use a class from another one, I have to import it. Why doesn't the IDE just automatically import the packages so there is no need to do it manually?
Because sometimes different classes have same 'short' name so the IDE does not know which one you meant. For example if you copy-paste code into your IDE containing Date, it does not know if you meant java.sql.Date or java.util.Date. In these cases the IDE will offer you to choose from all available classes with that name.
First, In Eclipse, you can use Ctrl-SHIFT-O to automatically import anything you need.
From the java package tutorial:
For convenience, the Java compiler automatically imports two entire
packages for each source file: (1) the java.lang package and (2) the
current package (the package for the current file).
The IDE will not import all your packages because 1.
You may not need them, why import them?
More importantly, you can have classes in different packages with the same name, then this will cause name ambiguities.
If a member in one package shares its name with a member in another
package and both packages are imported, you must refer to each member
by its qualified name. For example, the graphics package defined a
class named Rectangle. The java.awt package also contains a Rectangle
class. If both graphics and java.awt have been imported, the following
is ambiguous.
This would cause unnecessary headache making sure you are always referring to the correct package. By importing packages and classes yourself, you can be sure that you are always using the specific class that you intended to.
This is my thought. Think this way,
Suppose you have two classes having the same name in different packages like this, then how does IDE resolve the package import? How does it know which SendFormAction to be imported?
So generally IDE's give you an option to import the packages [cntrl+shift+O in eclipse IDE]
and if there is confusion, it will ask you which one to import.
com.xyz.action [package]
SendFormAction.java
com.abc.action [package]
SendFormAction.java

what is the need for importing libraries multiple times

in most code examples I see people doing this.
import javax.swing.*; // for the frame
import java.awt.*; // for the checkBox and the label
import java.awt.event.*; // for the checkBox listener
If I am correct when we say import java.awt.* it imports everything inside it, so there wont be a need to say import java.awt.event.*; or is there a speed improvement? can anyone also explain what importing a library does, is it importing a simple text class to be included in the source or telling jvm to include the byte code of whatever is imported? so importing in java does nothing but switch the namespace, so I dont have to type long class names?
Forget the term subpackage. Do it quick. It does not exist in java world.
java.awt is a package (namespace), java.awt.event is another one and they have nothing in common. Their names share some characters, but the packages are totally unrelated. The import statements imports a class or some classes from exactly one package (namespace). If you need classes from a different package (namespace), then you have to add another import statement.
BTW, in response to a comment to another answer: You do not have to use import statements. If you don't use them, you simply have to use the fully qualified classnames in your java source file (except: classes from java.lang and the current package are imported automatically). So import could be considered as a convenient way to keep the code readable.
Importing is not required in order to use a class in your source file.
The line...
import java.awt.*;
...doesn't mean that all subpackages will also be imported. You have to explicitly import every package. As an example, importing java.* doesn't give you the entire java library.
For what it's worth, I recommend importing the specific classes only unless you have good reason to use *.
Importing a package doesn't import its subpackages.
Importing is about switching the namespace, too.
If you only had import java.awt.* and you were to use the class java.awt.Outer.Inner, everywhere in your code you have to refer to it as Outer.Inner.
By contrast, when you say import java.awt.Outer.*, you can refer to the inner class as just Inner.
Importing is just a compile time feature, in bytecode you will find only direct references to specific classes, everytime its instance is used.
"import" constructs exist just to eliminate use of full class name everytime.

import command in Java

What exactly is the difference between the following commands:
import javax.swing.JPanel;
and
import javax.swing.*;
If I use second one, compiler will import all files from swing or only the needed ones, will be any difference in size of the executable? thanks in advance
The first one imports only javax.swing.JPanel class.
The second one imports all classes which are present in javax.swing package, excluding the classes in its subpackages, such as the ones in javax.swing.event package, etc.
The import keyword does not literally import the given classes. It basically just points the compiler to the classes which are to be present in the classpath in order to be able to locate the dependency classes and thus successfully compile the code. The size of the compiled class depends on the size of the sole source code (this includes the import statements), it does not include the size of the imported classes.
See also
Java tutorial - Using package members
First of all, in Java you don't produce executables (well, you can, but not directly). At run time, the JVM will load whatever is needed for the program to run from a library that is already on the disk, so your executable won't grow.
Having a catch-all import merely reduces the need to explicitly list everything you are importing. It's actually often discouraged because that could later create conflicts (e.g., what if you were already obtaining x.y.Foo and now there is also w.v.Foo in your w.f.* import).
Some IDEs (such as Eclipse) can fix the latter into the former for you automatically.
There is no difference in terms of execution of your application. Only difference is during the compile time it may be a bit (unnoticeable in most cases) slower. A lot of people prefer the .* over fully qualified packages because of code readability.
I asked this question myself once too and I found this explanation to be pretty good.
The first one will import that specific package but the second one will import all packages in swing. The first one will be smaller because it is only one package.
for example, import java.lang.* will import all the classes that exist in package java.lang (but no subpackages). By all I mean any class we really use in project, nothing what is not required will be imported (so I was taught).

How do I resolve a class/field in a JVM compiler?

I'm making a JVM language. This language has modules (namespaces) and the ability to import java libraries. In the import section the user can import things like "java.io." or "java.concurrent." etc.
How do I know that a "File" reference in the source is in the package java.io and not somewhere else?
Because Java is statically typed the lookup need to be be unambiguous. When you import entire packages (or namespaces) your compiler will need to handle name clashes in those namespaces if the types are used in the source. So you'll need to scan the list of available types to check.
That is why you sometimes see source code with the full class name expanded. e.g. java.util.Date when in import both java.util and java.sql Otherwise the compiler doesn't know which one to use.
Scala has some interesting features about importing from Java packages. You can look at those for inspiration.
If you want to know which classes are in a package you need to list all the class files in the directory for that package in the class path.

Categories

Resources