CS 235 - Week 15 Lecture - 2015-12-07
a few words about Java packages and jars
* course text has more info about these
topics:
* more package info: Ch. 4, pp. 152-162
* more jar info: Ch. 10, pp. 495-500
* Java package provides a way to collect/organize
related classes together
* notice: all standard Java packages are inside
the so-called java and javax package
hierarchies
* one benefit of packages
is to organize related classes for
better day-to-day ease of use;
ANOTHER is to help guarantee uniqueness
of class names,
(since a class's "complete" name is
<package_name>.<class_name>
* to help in this regard:
Oracle even recommends using your
organization's/company's/group's
Internet domain name written in
reverse as the package name
* course text author has a domain
horstmann.com,
he'd use package name
com.horstmann
with subpackages such as:
com.horstmann.corejava
com.horstmann.absolutejava
I might put classes related to this
class in a package
edu.humboldt.st10.cs235
edu.humboldt.st10.bigproj
* note that locating classes in packages
is (according to course text p. 154)
an activity of the compiler --
...compiled bytecode contains FULL class
names, including the package!
javax.swing.JPanel not JPanel
* all Java classes ARE in a package --
if a Java class does not have a package
declaration it is considered to belong
to the anonymous default package
(the default package has no package name)
* SO - say you had a class you wanted to
put into a package so other classes
could import it from that package and
use it?
* STEP 1: how do you define a package?
you put a package statement at the top
of your source file, BEFORE the code
that defines the classes:
package <desired_pkg_name>;
(for example, to make a version of class GameDie
desired to be in a package edu.humboldt.st10.cs235,
could put this at the beginning of the source code
file GameDie.java:
package edu.humboldt.st10.cs235;
)
* STEP 2: place this source code file in a subdirectory
with the PROPER NAME, based on that package
name
* for package com.horstmann.corejava,
the code in that package should be
in a subdirectory
com/horstmann/corejava
* for package edu.humboldt.st10.cs235,
it should be in a subdirectory
edu/humboldt/st10/cs235
* STEP 3 - compile and run the package's classes
from the base directory,
(that is, the directory containing the com
directory for com.horstmann.edu,
the directory containing the edu directory
for edu.humboldt.st10.cs235
* how does the JVM (Java Virtual Machine)
locate the .class files for Java classes?
There's a concept of a class path,
a set of directories that JVM
essentially "tacks" the package
names onto, and looks in each for
the .class files...
How do you set the class path?
* you can set it with -classpath
when you javac, java it
* or you can set the CLASSPATH
environment variable for your
operating system (temporarily within your
current shell,
or "permanently" by adding it to a script
that runs when you log in or start up a new shell)
* trying this in class for GameDie.java and GameDieTest.java
* added package command:
package edu.humboldt.st10.cs235;
...to beginning of a copy of GameDie.java
* currently working in my directory /Users/smtuttle;
made subdirectory-tree
edu/humboldt/st10/cs325
...from this directory
mkdir edu
mkdir edu/humboldt
mkdir edu/humboldt/st10
mkdir edu/humboldt/st10/cs325
* copied GameDie.java version with the package
command into subdirectory edu/humboldt/st10/cs325
* while in /Users/smtuttle, compiled GameDie.java using:
javac edu/humboldt/st10/cs235/GameDie.java
* now want to TRY to USE this packaged GameDie class!
...so went to a completely different directory,
(in this lecture's case,
/Users/smtuttle/humboldt/f15cs235/235lectures/235lect15
* made a copy of old Week 1 Lab version (NOT JUnit version!)
of GameDieTest.java, a little command-line application that
JUST exercises GameDie a little bit, in THIS directory
* added, to this copy of GameDieTest.java,
an import statement for GameDie from this new
package:
import edu.humboldt.st10.cs235.GameDie;
* now -- from GameDieTest.java's directory,
/Users/smtuttle/humboldt/f15cs235/235lectures/235lect15
ran:
javac -classpath .:/Users/smtuttle GameDieTest.java
* and then ran:
java -classpath .:/Users/smtuttle GameDieTest
AND IT WORKED, hooray! 8-) I see println results from
rolling GameDie instances cube and dodeca;
* a few words about jars
* jar - acronym, for Java ARchive file
* they are compressed
* this does use a cross-platform archive
format
* jar files make it simpler to distribute
Java programs -- reasonably quickly
with regard to Java applets to browsers
-- and sometimes you can even add security,
in the form of digital signatures;
* jar vcf newJar.jar subdir_name
jar vcf newJar.jar file1 file2 ....
if there is an application amongst those
files, you can make the jar executable...
jar vcfe newJar.jar fullNameOfMainClass <filestoAdd>
* SO: trying this;
running from /Users/smtuttle,
where my edu.humboldt.st10.cs235 package's subdirectory tree starts:
jar vcf st10Lect15.jar edu
* the v above stands for verbose -- here's the output
displayed when I run the above:
added manifest
adding: edu/(in = 0) (out= 0)(stored 0%)
adding: edu/humboldt/(in = 0) (out= 0)(stored 0%)
adding: edu/humboldt/st10/(in = 0) (out= 0)(stored 0%)
adding: edu/humboldt/st10/cs235/(in = 0) (out= 0)(stored 0%)
adding: edu/humboldt/st10/cs235/GameDie.class(in = 637) (out= 398)(deflated 37%)
adding: edu/humboldt/st10/cs235/GameDie.java(in = 1839) (out= 713)(deflated 61%)
* and t option allows you to see the contents of the jar -- if
I now run:
jar tf st10Lect15.jar
...the following is displayed:
META-INF/
META-INF/MANIFEST.MF
edu/
edu/humboldt/
edu/humboldt/st10/
edu/humboldt/st10/cs235/
edu/humboldt/st10/cs235/GameDie.class
edu/humboldt/st10/cs235/GameDie.java
* I should be able to now add this jar to a
classpath, and a class using classes from
a package in that jar will work;
# COPYING the jar to my class's directory
# (just have to know the path it can be reached from,
# I think -- BUT copying here is one way to know
# that, and hopefully shows it CAN be "moved"):
cp st10Lect15.jar /Users/smtuttle/humboldt/f15cs235/235lectures/235lect15
# TEMPORARILY "hid" original package edu.humboldt.st10.cs235
# (by changing edu directory's name) so can (hopefully)
# show I'm using the package from the jar;
# while in /Users/smtuttle
mv edu HIDEedu
# cd'd to /Users/smtuttle/humboldt/f15cs235/235lectures/235lect15
cd /Users/smtuttle/humboldt/f15cs235/235lectures/235lect15
# since have HIDDEN original package, this SHOULD now
# fail -- does it?
javac -classpath .:/Users/smtuttle GameDieTest.java
# YES -- I'll spare you the 5 errors' error messages
# here;
# CAN it compile and run if I put the jar in the classpath
# option?
javac -classpath .:st10Lect15.jar GameDieTest.java
java -classpath .:st10Lect15.jar GameDieTest
AND IT WORKED, hooray! 8-) I see again see println results from
rolling GameDie instances cube and dodeca;
* more about executable jars:
(after class)
recall:
jar vcfe newJar.jar fullNameOfMainClass <filestoAdd>
...should be able to create an executable jar, but (as we saw
in class) not so much for a command-line application...!
BUT: we should be able to try this with a Swing GUI application
such as Week 7 Lab's LayoutTrio.java;
* I copied its source code into a new directory
* compiled it as usual:
javac LayoutTrio.java
* created an executable jar:
(. is a UNIX nickname for the current directory --
keep in mind, LayoutTrio.java contains one public class
which happens to be an application class, with a main method, and
numerous default-visibility and private inner classes,
EACH of which results in a .class file)
jar vcfe trioJar.jar LayoutTrio .
this displays:
added manifest
adding: LayoutTrio$1.class(in = 533) (out= 371)(deflated 30%)
adding: LayoutTrio.class(in = 408) (out= 293)(deflated 28%)
adding: LayoutTrio.java(in = 7386) (out= 2093)(deflated 71%)
adding: LayoutTrioFrame.class(in = 522) (out= 374)(deflated 28%)
adding: LayoutTrioPanel$1.class(in = 188) (out= 151)(deflated 19%)
adding: LayoutTrioPanel$ClearAction.class(in = 831) (out= 473)(deflated 43%)
adding: LayoutTrioPanel$NumButtonAction.class(in = 1246) (out= 649)(deflated 47%)
adding: LayoutTrioPanel.class(in = 2884) (out= 1592)(deflated 44%)
* NOW -- if I double click on trioJar.jar, does LayoutTrio
run?
* YES;
* can I copy it elsewhere, and does it still run when I
double-click on it? (is it directory-dependent?)
* YES;
* ...and I'm posting a link to a copy of trioJar.jar,
so you can see if it works when you download a copy of
it;