I have recently learnt how to program in java, I was looking at some open source programs from sourceforge.net and after downloading these programs I don't understand the file structure most of the programs follow. Pretty much every program has src,bin,lib etc folders, how do I know the standard way of organizing my program. Is there any book or resource which explains this? also how do I compile this source code once I have downloaded it, to make a jar file from it
thanks
src is (usually) what it sounds like: source code
bin is (usually) shell scripts related to the product
lib is (usually) external dependencies needed for compilation
Most projects document how they build: look for a README or grok the project website. These days for a Java-centric project I would expect Ant or Maven.
What you have downloaded is actually a distribution version of the program. The directories as listed by carej are kind of a convention, mainly derived from how things are usually done on a Unix system.
Most projects supply some manual on how to build. This can be tricky if not all libraries (jars) used by the program are supplied in the distribution. Some of the Apache Commons project do it like this, thus forcing the user to download dependencies seperately.
If you just want to use the program try to find a binary version. This will usually consist of jars, scripts and documentation. Source distributions are useful if you want to look at the source and/or make modifications.
Related
For context, I don't work a lot with Java, but need to create a Java maven package to provide a simple java wrapper around a cdylib (dll and so files). The dll size is relatively large, and I've seen some posts that there's issues loading DLLs from and to the running JAR if it's just a file that's included in the JAR archive.
So I'm curious if the Java devs out there expect Java maven packages to behave a certain way where DLLs/large-resources are concerned? Is there an expectation it would handle attempting to download the larger dependencies at runtime and just provide settings to override/control that behavior? Or should I just document it as needing those files and where to find them for package consumers?
If there's an expectation they would come bundled in a JAR, I also have yet to find any examples of how to create platform specific package builds from a shared codebase, only changing resources in Gradle, and would welcome any help on how to do that.
I am trying to veer away from writing most of my Java code in Eclipse and I'm coming up with small projects for myself to work on in order to a. become a better Java programmer and b. learn how to organize my applications (in both terms of code and directory structure).
I noticed that I make plenty of small, incremental changes to classes then to recompile and run my whole application. I'm slightly familiar with Makefiles from a course I took in C++, and I'm less familiar with Build Systems (Maven, Ant). Regarding this mater, here are a few things I'd appreciate help with:
First of all, is there a way that I can write a little file that separates where my .class files are saved during javac *.java?
Say I want to put all my .class files in a /bin folder
In that file, is there a command I can write to simplify the javac *.java and java [class name here...] process?
I know that this process is relatively simple already, but what I want to know is can I write something that will allow me to run commands along the lines of myExec build (compile and save all my java files) myExec run (run my application)
Finally, is there a simple Build System that I can/should learn to use that will allow me to accomplish this? Or am I confusing the point of a Build System.
Look at Maven or Gradle, it automatically separates the source file and class files.
Manual build script writing is waist of time really.
I've always been impressed by the StackOverflow hive mind, and was hoping you could point me in the right direction here.
I've taken some courses in Java programming, and understand how to write a fairly complex Java program. However, I've never learned how to integrate others' software into my own programs.
For a new project, I'd like to integrate a part-pf-speech tagger and chunker into my code, but have no idea how to "load" these programs (if load is the correct term).
I'm certainly not looking for step-by-step instructions, but rather a guide for how to go about this sort of issue. If anyone could get me started in the right direction, I would greatly appreciate it.
Thanks,
Adam
It looks like the externals you want to use are themselves in Java. This means you're in luck - you can use pure java language features to make it work.
There are two things to it:
1) your source files that interact directly with the external libraries have to be imported, or otherwise you'll have to refer to them using the fully qualified classname.
Importing is done with the import statement. These statements should appear right before your class declaration, like so:
import foo.*; //import all classes from the package foo
import foo.bar.Baz; //import only the Baz class from the package foo.bar
public class MyClass {
Baz myBaz = null; //declare a member of type Baz class from package foo.bar
foo.bar.BazBaz myBazBaz = null; //by using a fully qualified classname, I didn't need to write an import statement for foo.bar.BazBaz
}
2) when you compile your sources, the java compiler needs to know where to look for classes you referenced in your source. This is done via the classpath.
The classpath can be a list of just .class files (compiled java classes), but also .jar files (java archives) and .zip files. Typically a project will package all classes it needs in one or more .jar files.
The location of these classes have no bearing on the way you interact with them in java code. It's the compiler's job to read these jars and class files and locate the classes you referred to in your code. If the compiler can't locate the classes you're referring to, you will get a compile time error and you can't compile your program.
You can specify the classpath as an argument to the java compiler command line (http://docs.oracle.com/javase/6/docs/technotes/tools/windows/javac.html#options). However, this becomes unwieldy very rapidly.
Instead, you should use a build tool like ant to do this work for you. The best way to get started is to read this page: http://ant.apache.org/manual/index.html.
From there, go to "Using apache ant" and then to "Writing a simple build file" in its entirety, they explain how to set up the classpath very well there.
You'll need their classes on your classpath when compiling, and again when running your program.
It appears that those projects distribute both src and jars. Grab the jars, and make them available on your classpath. Once your classpath is set up you'll need to import any specific classes/packages that you're using.
See this tutorial on managing the classpath. It covers the basics for command-line compilation/execution; if you're using a particular build system or IDE then the instructions will vary.
Also note the specific instructions at the second link for making data files available. For this they're also using the classpath.
Configure your build path to include the .jar files.
If you're using Eclipse, you would right click on the project file in the Project Explorer, then select Configure Build Path. Finally, add external archive (the ones you've downloaded). Now those functions will be readily available in your program.
Or a more robust way is to create a folder called "lib" in your eclipse project and include all jar files in there. Then from the Configure Build Path window you select those jar files in the lib folder. This makes it easy to share projects with other programmers regardless if they are on Windows or Linux (when adding external jar it saves the absolute path so if something on C:\ will not be found on someone else's PC) Also provides nice integration of dependency libraries on source code managers like GIT, CVS and SVN.
Well typically Java libraries are distributed as a JAR file. Then in your program, you can simply import the new packages and use the provided API.
When you compile and run, you have to make sure that the libraries are included in your class path so they know where to look for the packages.
I'm going to deploy a Java application with a custom launcher, and I need to have all the classes needed for my app in a single jar file so I don't have to deploy the entire Java SE libraries with it.
I was thinking of using some pre-existent ant tasks to create a target that recursively searches all my compiled classes files for its dependencies. After all the dependencies have been determined it would extract the needed class files from their JAR's, copy it along with my classes to an output directory and make a single jar from it.
If there's no such thing avaliable out of box, I can create one myself, but I need to know how references to other classes are stored in .class files. It could be much easier if there's some kind of java library like .NET's Mono.Cecil/System.Reflection that exposes an high level API for inspecting/manipulating Java.
Since I'm new to Java, I'm having some trouble in finding what is needed to acomplish those things. Can someone give me some direction?
Unfortunately, you cannot ship only part of Java SE - that will breach the license agreement. If you use Java SE, then all of Java SE must be available.
The simplest way to achieve this is to use an Ahead Of Time compiler. These take care of packaging only the classes you need, and adhere to the JDK license agreement by making the "unused" parts of the JDK available via optional download.
For example, Excelsior JET is a good AOT compiler and will package just the classes you need. It's not free for commercial use, although open source projects can apply for a free license grant.
Alternatively, you may simply assume that the user has the JRE already since it's installed on over 90% of desktops, and in cases where the JRE is not available, have your installer download one for the user. AdvancedInstaller has a free edition that will accomplish this.
After all the dependencies have been
determined it would extract the needed
class files from their JAR's, copy it
along with my classes to an output
directory and make a single jar from
it.
As an easy solution, if you use Eclipse IDE you use the following solution:
Under the Java project properties (right click):
Export... => Export as Runnable JAR
The exported JAR will have all its dependencies packed into it.
alt text http://www.ubuntu-pics.de/bild/97131/selection_016_mg6IDm.png
Here is one suggestion I found on the web:
<jar destfile="${build-abc}/abc.jar" duplicate="fail" index="true">
<zipfileset src="${compile-lib}/demo.jar" includes="**/*.class"/>
</jar>
This should add the dependencies to the jar (as shown with demo.jar). You still have to adapt the manifest file so that the added jars appear on the classpath.
This doesn't solve the 'Java SE' classes problem - you'll have to bundle a jre in the installer package or depend on an existing one on the target system.
You won't have to deply Java SE classes, as they already are in the customer JRE.
If your dependencies are expressed ion a common way (through Maven or Ivy) i guess it's quite easy to find an equivalent of maven uberjar task ... which will do what you want to do, but in a more simple way (as it simply repacks all jars in one big jar).
I am coming to Java and Eclipse from a C#/Visual Studio background. In the latter, I would normally organize a solution like so:
\MyProjects\MyApp\MyAppsUtilities\LowerLevelStuff
where MyApp would contain a project to build a .exe, MyAppsUtilities would make an assembly DLL called by the .exe, and LowerLevelStuff would probably build an assembly containing classes used by the higher-level utilities DLL.
In Eclipse (Ganymede, but could be convinced to switch to Galileo) I have:
\MyProjects\workspace\MyApp
When I create my initial project. There is an option to put source and build files in same folder, but I have .java files created on a path that is reflective of my package hierarchy:
\MyProjects\workspace\MyApp\src\com\mycompany\myapp\MyApp.java
My question is this: when I create subprojects (is that the right Java/Eclipse term?) for .jar files that will be analogous to the above MyAppsUtilities and LowerLevelStuff assembly DLLs in .NET, can (should) I organize the folders equivalently? E.g.:
\MyProjects\workspace\MyApp\src\com\mycompany\myapp\myapputilities\MyAppsUtilities.java
What is the standard/right way to organize this stuff, and how is it specifcally done in the IDE?
Think of Java source code packages as one big hierarchical namespace. Commercial applications typically live under 'com.mycompany.myapp' (the website for this application might be 'http://myapp.mycompany.com' although this is obviously not always the case).
How you organize stuff under your myapp package is largely up to you. The distinction you make for C# between executable (.exe), DLL's and low-level classes does not exist in the same form in Java. All Java source code is compiled into .class files (the contents of which is called 'bytecode') which can be executed by a Java Virtual Machine (JVM) on many platforms. So there is no inherent distinction in high-level/low-level classes, unless you attribute such levels via your packaging. A common way of packaging is:
com.mycompany.myapp: main class; MyApp (with a main method)
com.mycompany.myapp.model: domain model classes; Customer, Order, etc.
com.mycompany.myapp.ui: user interface (presentation or view) code
com.mycompany.myapp.service: services within your application, i.e. 'business logic'
com.mycompany.myapp.util: helper classes used in several places
this suggests a standalone Java app, it might be different if it is a webapp using one of the many frameworks.
These packages correspond to a directory hierarchy in your project. When using Eclipse, the root of such a hierarchy is called a 'source directory'. A project can define multiple source directories, commonly a 'main' and a 'test' source directory.
Example of files in your project:
src/test/java/com/acme/foo/BarTest.java
src/main/java/com/acme/foo/Bar.java
lib/utilities_1_0.jar
And inside utilities_1_0.jar:
com/acme/foo/BarUtils.class
BarUtils.class this is a compiled java class, so in platform independent bytecode form that can be run on any JVM. Usually jarfiles only contain the compiled classes although you can sometimes download a version of the jar that also contains the source (.java) files. This is useful if you want to be able to read the original source code of a jar file you are using.
In the example above Bar, BarTest and BarUtils are all in the same package com.acme.foo but physically reside in different locations on your harddisk.
Classes that reside directly in a source directory are in the 'default package', it is usually not a good idea to keep classes there because it is not clear to which company and application the class belongs and you can get name conflicts if any jar file you add to your classpath contains a class with the same name in the default package.
Now if you deploy this application, it would normally be compiled into .class files and bundled in a .jar (which is basically a fancy name for a .zip file plus some manifest info).
Making a .jar is not necessary to run the application, but handy when deploying/distributing your application. Using the manifest info you can make a .jar file 'executable', so that a user can easily run it, see [a].
Usually you will also be using several libraries, i.e. existing .jar files you obtained from the Internet. Very common examples are log4j (a logging framework) or JDBC libraries for accessing a database etc. Also you might have your own sub-modules that are deployed in separate jarfiles (like 'utilities_1_0.jar' above). How things are split over jarfiles is a deployment/distribution matter, they still all share the universal namespace for Java source code. So in effect, you could unzip all the jarfiles and put the contents in one big directory structure if you wanted to (but you generally don't).
When running a Java application which uses/consists of multiple libraries, you run into what is commonly referred to as 'Classpath hell'. One of the biggest drawbacks of Java as we know it. (note: help is supposedly on the way). To run a Java application on the command line (i.e. not from Eclipse) you have to specify every single .jar file location on the classpath. When you are using one of Java's many frameworks (Maven, Spring, OSGi, Gradle) there is usually some form of support to alleviate this pain. If you are building a web application you would generally just have to adhere to its layering/deployment conventions to be able to easily deploy the thing in the web container of your choice (Tomcat, Jetty, Glassfish).
I hope this gives some general insight in how things work in Java!
[a] To make an executable jar of the MyApp application you need a JDK on your path. Then use the following command line in your compile (bin or target) directory:
jar cvfe myapp.jar com.mycompany.myapp.MyApp com\mycompany\myapp
You can then execute it from the command line with:
java -jar myapp.jar
or by double-clicking the jar file. Note you won't see the Java console in that case so this is only useful for applications that have their own GUI (like a Swing app) or that may run in the background (like a socket server).
Maven has a well thought out standard directory layout. Even if you are not using it Maven directly, you can think of this as a defacto standard. Maven "multi module" projects are a fair analogy to the .net multiple assembly layout that you described.
Typically you would create related/sub projects as different Projects in Eclipse.
There are two things you need to clarify before this question can be answered:
Which source code repository will you use?
Which build system will you use to automatically build artifacts outside of Eclipse?
The answers will strongly influence your options.
We have opted for "one Eclipse project pr component" which may be either a library or a finished runnable/executable jar. This has made it easy to automate with Hudson. Our usage of CVS is also easier, since single projects do not have multiple responsibilities.
Note, each project may contain several source folders separating e.g. test code from configuration from Java source. That is not as important as simplifying your structure.