NOTE: yes, minecraft has a specific coder pack, but it doesn't work for mac or linux (something to do with the python script portability)
While attempting to mod the main java jar file (minecraft.jar) i noticed it has an unusual structure, which im unsure on how to build. It contains all the objects (or the classes which are frequently called) at the top of the [name for structure of jar], and these, when decompiled, didnt belong to any packages. Whereas the files which were executed did belong to packages.
so my question is, how do i structure a jar file like this myself, with an IDE (eclipse/intelliJ)?
I think all you need to do is create some classes in the default package (no package declaration in the .java file).
Related
I have started getting into game programming.
My question is, that when I am working with files, either parsing data, writing to files, etc. Should I be using relative path names, or absolute pathnames, or something else which is better. I've heard about using jar files, but I am not sure
1. how that works
2. if it is a good way to do it.
So when developing a game that will be cross platform, what is the best method for managing files that the program will need to read from and write to.
there are several ways in which you can ship your code as a product. the most common are
packaging everything in one executable jar file.
having a set of folders where you place all necessary resources.
minecraft, for example, is written in java and distributed as a single executable jar file that contains all necessary class files and resources. to run the game (assuming you have java installed) all you need to do is double-click the jar file.
read this short tutorial about how to add a main class to a jar file.
either way, always treat classes and resources in your code as if they're in your classpath. for example, if you have a my.properties file on the root of the source tree then load it by using 'my.properties'. if you put it under a 'conf' folder then use 'conf/my.properties'.
i think it is the safest way not to get lost.
are you using maven?
The jar file is a zip of all your compiled *.class files and your resources. You can safely load your resources and even default data FROM a jar if you package your program, but you can NOT safely write data back to the jar. This detail is answered in depth already at
How can an app use files inside the JAR for read and write?
For information on how to package a jar see
http://docs.oracle.com/javase/tutorial/deployment/jar/
There are a couple of questions on SO that sort of hit this, but I am totally new to Java development and I don't know the correct way to approach this.
I have a C# solution, containing two projects (my app, and a unit test project) and within the app, most things are put into folders eg. Interfaces, Exceptions etc.
I am trying to recreate this in Java / Eclipse, but I don't know how. I ended up with lots of packages, which sounds really bad. I also tried adding a source folder but that ended up being outside of the package.
Could anyone point me in the right direction?
Namely, which of those should I use to represent my unit test project/set of unit tests, and subfolders which exist just for organising stuff.
Edit: It also says use of the default package is not advised. What should I be doing?
Edit 2: Here is what it looks like. Does this look vaguely correct? My original C# solution is on the right.
In a typical java eclipse project, you will have one or more source folders (for example one for app code, one for your unit tests).
Each folder contains a package tree, typically starting with your base package, for example com.mycompany.myapp.
In order to avoid name collisions, packages names are usually start with the domain name of the entity who is the author of the code, starting with the top-level-domain and going backwards (more general to more specific). That way, each class fully qualified name is unique. For example if google creates a class named List, it will be known as com.google.List, and it will not enter in conflict with the existing java.util.List interface.
You can have a unlimited number of packages inside this base package, for example :
com.mycompany.myapp.persistence
com.mycompany.myapp.domain
com.mycompany.myapp.services
com.mycompany.myapp.web
It all depends on your project and the way you want to organize your code and your classes.
At the logical level, packages are named with dots as separator. They contain java classes.
At the physical on disk level, each package is a directory. The java classes are contained in .java files (most frequently one class per file).
In Eclipse a "source folder" is a folder inside your project that is known to Eclipse to contain java source files. It will be compiled included in the output (for example JAR file) when you build your project.
In Eclipse, you usually view them at the logical level, showing packages. When you tell Eclipse to "create a new package", it will create the directory for you. For example, if you tell it to create the com.mycompany.myproject package, it will automatically create a com folder containing a mycompany folder containing a myproject folder.
In java source tree structure must match package structure
so foo.bar package must be laid out in
src/foo/bar
Also default package may not be advised - but you can still use it - better to put things in a package though
In java different project development structure are flowed according to type of project.
So as you are new to java and Eclipse so it's better to install maven plugin and create maven project and choose a archetypes according to your project type like a standalone or web based.
The maven plugin will create the project structure including packages,test packages source folder etc. You can get more about project structure from this
Using the default package may create namespace collisions. Imagine you're creating a library which contains a MyClass class. Someone uses your library in his project and also has a MyClass class in his default package. What should the compiler do? Package in Java is actually a namespace which fully identifies your project. So it's important to not use the default package in the real world projects.
I'm developping several java packages that are then distributed as jar files.
Due to some new requirements, I now have to program several new features in jython; these will probably cover quite a bit of code distributed over a lot of separate jython files.
I would like to continue with the distribution of a single jar file per package. I bit of search provided me with two approaches which are unfortunately both not very good:
1) jythonc: I'm using jython 2.5.1, so jythonc is no longer part of the distribution. Besides, I don't like the restriction this would place on my jython code.
2) Package everything together with the jython.jar file. Unfortunately, this is not possible; all of the people using my code package already have a jython.jar file in their environment (and many of them use different versions). In other words, my package must be distributed without the python core; instead I can rely on it being found in the classpath at the target system.
Now the question remains, is there another way of packaging all my java and jython code within one jar while keeping the jython.jar file untouched?
I finally found a solution for my problem. Maybe this is also of interest for someone else.
Just as a reminder, this is meant for a mixed java/jython package with java on top that will then be delivered to a customer, NOT for a self-contained application.
1) All jython sources are put in a separate folder on the top level within the jar file using the tool "jar" (or any other zip tool); I used the folder "Lib".
2) Access to the jython code from java is done using an object factory class modeled as a singleton (similar to the one described here); access to java from jython works straightforward with just the full package name.
3) In the constructor of the object factory I use
String jarPath = myObjectFactory.class.getProtectionDomain().getCodeSource().getLocation()
.getPath();
to determine the location of the jar file from within the code.
4) I add the "Lib" folder within the jar file to the jython module lookup path using
PySystemState newState = new PySystemState();
newState.path.insert(0,Py.newString(jarPath + java.io.File.separator + "Lib")); Py.setSystemState(newState);
As long as the jython.jar file is included in the classpath, this will work.
I'm working on some Java code in eclipse. Code is contained in a single class called Adder, which in Eclipse is in the package org.processing. The first thing in the class file is the line
package org.processing
Q1) What, exactly is this line doing? Why is there, what's it's role.
The code runs fine in eclipse, however, when I move into the workspace if I go to the src/org/processing/ folder in src, compile with javac Adder.class when I try and run using java Adder I get the following error
java.lang.NoClassDefFoundError: Adder (wrong name: org/processing/Adder)
On the other hand, if I compile from src using
javac org/processing/Adder.java
and I can run it from src using java org.processing.Adder but STILL not from within the processing directory.
Q2) Does this mean that compilation is always relative to directory structure?
Finally, if I remove the package org.processing line from the start are the .class file I can compile and run from within the .class file's directory.
Q3) Why is all this the way it is? I can fully understand enforcing a directory structure for code development, but once you're in bytecode this seems a bit over the top, because now I can (apparently) only run the bytecode from one director (src) using java org.processing.Adder. Now, I'm sure I'm missing the point here, so if someone could point out what it is, that would be great.
The compiler has to be able to find related source code files when compiling. This is why the package and directory structure must agree for source code. Similarly, the JVM must be able to find referenced .class files. So the same directory structure is required at runtime. It's no more complex than that.
Q1) The issue here is that once you got into the folders that represent your package hierarchy, you set that as the working directory. It's gonna look inside of org/processing/Adder for the path org/processing/Adder (essentially looking from the root for org/processing/Adder/org/processing/Adder). You need to call it from the root with the full path. The purpose of packages is A: to organize related classes into groups. And B: Along with A, classes in package Foo.bar can't view private classes in other packages, as they are like internal classes for that package, only the package they're in can use them
Q2) Yes
Q3) The paths are used as a basic structure for the JVM to know where exactly the class files (each containing their bytecode) are. If you change where you call it from, your basically trying to change the location for the JVM to look for the class files, but their true location hasn't changed.
The short answer - Packages help keep your project structure well-organized, allow you to reuse names (try having two classes named Account), and are a general convention for very large projects. They're nothing more than folder structures, but why they're used can burn beginners pretty badly. Funnily enough, with a project less than 5 classes, you probably won't need it.
What, exactly is this line doing? Why is there, what's it's role.
The line
package org.processing
is telling Java that this class file lives in a folder called /org/processing. This allows you to have a class which is fully defined as org.processing.Processor here, and in another folder - let's say /org/account/processing, you can have a class that's fully defined as org.account.processing.Processor. Yes, both use the same name, but they won't collide - they're in different packages. If you do decide to use them in the same class, you would have to be explicit about which one you want to use, either through the use of either import statements or the fully qualified object name.
Does this mean that compilation is always relative to directory structure?
Yes. Java and most other languages have a concept known as a classpath. Anything on this classpath can be compiled and run, and by default, the current directory you're in is on the classpath for compilation and execution. To place other files on the classpath, you would have to use another command-line invocation to your compilation:
javac -sourcepath /path/to/source MainClass.java
...and this would compile everything in your source path to your current directory, neatly organized in the folder structure specified by your package statements.
To run them, as you've already established, you would need to include the compiled source in your classpath, and then execute via the fully qualified object name:
java -cp /path/to/source org.main.MainClass
Why is all this the way it is?
Like I said before, this is mostly useful for very large projects, or projects that involve a lot of other classes and demand structure/organization, such as Android. It does a few things:
It keeps source organized in an easy-to-locate structure. You don't have objects scattered all over the place.
It keeps the scope of your objects clear. If I had a package named org.music.db, then it's pretty clear that I'm messing with objects that deal with the database and persistence. If I had a package named org.music.gui, then it's clear that this package deals with the presentation side. This can help when you want to create a new feature, or update/refactor an existing one; you can remember what it does, but you can't recall its name exactly.
It allows you to have objects with the same name. There is more than one type of Map out there, and if you're using projects that pull that in, you'd want to be able to specify which Map you get - again, accomplished through either imports or the fully qualified object name.
For Q1: The package declaration allows you to guarantee that your class will never be mistaken for another class with the same name. This is why most programmers put their company's name in the package; it's unlikely that there will be a conflict.
For Q2: There is a one-to-one correspondence between the package structure and the directory structure. The short of it is that directories and packages must be the same, excepting the package is usually rooted under a folder called src.
For Q3: Once it's compiled, the class files will probably be in the appropriate folders in a jar file. Your ant or maven tasks will build the jar file so you won't really have to bother with it beyond getting the ant task set up the first time.
as weSuppose that I am creating a Java project with the following classes
com.bharani.ClassOne
com.bharani.ClassTwo
com.bharani.helper.HelperOne
com.bharani.helper.support.HelperTwo
with files put immediately under the folder 'src'
src/ClassOne.java
src/ClassTwo.java
src/HelperOne.java
src/HelperTwo.java
and compile them using the command
$ javac -d classes src/*.java (assuming that classes directory exists)
The compiler compiles these files and put the class files in appropriate sub-directories inside the 'classes' directory like this
classes/com/bharani/ClassOne.class
classes/com/bharani/ClassTwo.class
classes/com/bharani/helper/HelperOne.class
classes/com/bharani/helper/support/HelperTwo.class
Because the spec mandates that the classes should go inside appropriate directory structure. Fine.
My question is this: When I use an IDE such as Eclipse or NetBeans, they create the directory structure for the source code directory ('src' directory here) as well. Why is that? Is it mandatory? Or, is it just a convention?
Thanks.
Mainly convention. It makes sense for the source to mirror the binary structure.
Also, if you have two classes with the same name (but in different packages), how would you store the source if not in different directories?
Keeping the source in just one folder is fine for small projects, but once you have a larger project (hundreds of classes), grouping the source into packages makes things far more manageable.
Is it mandatory?
No
Or, is it just a convention?
Yes, to reflect your package structure in your source tree.
I always thought that Java's package is a little bit broken:
it seems to be hierachical, but it is not.
it is a simple (unique) prefix to define seperate plain namespaces.
I thought it was mandatory, but your experience suggests otherwise. Either way, it's just common sense, right? Large projects have so many source files - why make life more complicated by having different structures for your source and your class files?