Java: How to Integrate Other Software - java

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.

Related

Having trouble importing packages in java

I'm in the process of a personal project I'm working on, and I'm trying to import packages I've created in Java.
Say that my directory is C:\Users\B\Desktop\gamingResearch\pokemonGames and in that directory I have the files Battle.java, Move.java, and another folder called pokemon. In my header for Battle.java, I have
import pokemonGames.trainerClass.Trainer;
import pokemonGames.pokemon.*;
And I try to compile the class with javac -sourcepath .:/Desktop/gamingResearch/pokemonGames Battle.java
But I still get an error saying
error: package pokemonGames.pokemon does not exist.
I'm running into the same errors in other classes regarding packages that I've made. Is there something that I'm forgetting to do?
Your sourcepath is wrong.
It should be:
-sourcepath /Desktop/gamingResearch
Hope it helps.
If you program in java, you do need to add libraries (like pokemonGames) to your classpath before compiling your application, like already stated in the comment by cricket_007.
To make things slightly simpler, you could use a build tool like gradle or maven or even just use an IDE (like IntelliJ) to build your application. Please note, that I recommend a build tool as well as using an IDE, so that you are able to build your application on other machines with different IDEs.

How do I build a single bundled JAR with all the needed classes to run a Java application?

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).

How to combine library with my jar?

Ok so i wrote a program that makes use of a 3rd party open source library and i want to package it with my program in a single jar. I'm using netbeans 6.8 and everything I've tried java always spit back the error:
java.lang.NoClassDefFoundError: libraryname;
off topic:also i would like to know how to make an executable-jar(exe) through netbeans if it is possible. (ive seen programs that were written in java but were an .exe)
EDIT discovered a plugin for eclipse called FatJar which can do what i want, but i cant find something similar for netbeans, is there such thing?
I'll start off with the obligatory disclaimer: Java executable JARs do not work this way. An executable JAR has a main class defined in the JAR's MANIFEST.MF file, and the MANIFEST also allows the definition of a class path to include libraries that the code in the executable JAR will need. The class path definition in the MANIFEST must enumerate every JAR or folder to put on the class path, relative paths are relative to the location of the executable JAR - not to paths contained inside the executable JAR. Executable JARs are launched with the "-jar" argument to the java executable, and both the java "-cp" flag and the CLASSPATH environment variable are ignored. As for why executable JARs were designed this way, you should be aware of the primary disadvantage of loading classes from JARs contained within JARs, even though the rest of this reply will focus on doing just that.
NOTE: I lost the original sun forum topic that explained it fully, but essentially it is because entries in the top level JAR can be read in a random access manner, but the entire embedded JAR must be read before any entries can be accessed, because the top level JAR might have compressed its entries.
I have used One-Jar successfully in the past, but the structure of the final resulting jar may not be what you expect. Essentially the One-Jar classes are the only non-JARd classes in the final jar; all other code (your code and any dependent library code) is included in the resulting as JAR as JAR files. Your application is JARed as a regular JAR file named "main.jar" in the final JAR's "main" folder. Any libraries your code needs is placed, as JAR files, in the final JAR's "lib" folder. And last but not least the final JAR's MANIFEST.MF file tells One-Jar what your main class is. Execution is a dead simple "java -jar final.jar [args your app uses]". I don't know how to take the next step of converting to an OS-native EXE regarding your off-topic question, but it would probably be best to use a different packaging mechanism than One-Jar anyway. I'm not sure how to go about this with NetBeans, my advice there is to use a build tool to package the final jar. Fortunately One-Jar provides instructions on generating the final jar with Ant, and that should be easily integratable into NetBeans.
I believe the Eclipse FatJar plugin creates a One-Jar executable JAR, so if that plugin seems to do what you want, then One-Jar is the way to do it. Personally, I used a Maven assembly.
There is a caveat - any signed libraries that require (or desire) to take advantage of Java's signed JAR verification may not work this way - Java Cryptographic Extension (JCE) implementations like BouncyCastle are a notable example. I think the reason is that the signature verification runs against the final JAR, not the signed library. Fortunately One-Jar allows the end user to add additional libraries to the classpath, something that is explicitly precluded when running an executable JAR; to workaround this you might be better off delivering the problematic JARs with the final JAR and an OS dependent launch script (.bat, .sh, etc).
I realize that this doesn't achieve exactly what you want, but I'll describe the customary method of distributing a standalone application. If it does meet your needs, you'll find that it's better supported by tools and more readily understood by users, because it follows established conventions.
Put your code in a jar (I'll call it app.jar) along with a META-INF/MANIFEST.MF file with entries like this:
Main-Class: com.y.app.AppMain
Class-path: third-party.jar blort.jar foo.jar
Then, you can throw all of the jars into a directory and run AppMain like this:
java -jar app.jar
If you want, you can put the third-party libraries in a single directory like lib and refer to them in the Class-path attribute using a path relative to the main jar: lib/third-party.jar That helps keep your distribution tidy.
My generic answer to your off-topic question is a (rather lengthy) article: Convert Java to EXE - Why, When, When Not and How. It has lots of links to free and commercial tools, but I have never seen a Netbeans plugin with such functionality, sorry.
To include another jar in your jar, you might find jarjar useful.
Executable jars just have a class defined as 'Main', if I'm not mistaken. This may be useful.
If there's not any concern of repackaging 3rd party jars into your final big jar, then this should be the easiest method.
If there are no licencing issues then the most preffered way is to unjar the actual jar and rejar it with your class files in it, to a new jar.
You can simply use the jar cmd itself for this, no big deal!!
if you use MAVEN, use "maven-shade-plugin" plugin. It will compile jar with all dependencies(3rd party and etc.)

Eclipse Java project folder organization

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.

java cvs,svn file structure

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.

Categories

Resources