[1126] in java-interest
Re: (Fwd) Re: mutually dependent public classes
daemon@ATHENA.MIT.EDU (Jonathan Payne)
Sat Aug 19 23:19:15 1995
Date: Sat, 19 Aug 1995 15:09:23 -0700
From: jpayne@starwave.com (Jonathan Payne)
To: jsw@cs.brown.edu, pambrose@weblogic.com
Cc: java-interest@java.Eng.Sun.COM, hotjava-interest@java.Eng.Sun.COM
In-Reply-To: <199508192145.RAA13348@transit.cs.brown.edu> (message from Jeff White on Sat, 19 Aug 1995 17:45:58 -0400)
> From: Jeff White <jsw@cs.brown.edu>
> Date: Sat, 19 Aug 1995 17:45:58 -0400
> References: <199508190625.XAA13785@blob.best.net>
> <9508191832.AA11880@flim.starwave.com>
> Reply-To: jsw@cs.brown.edu
> Content-Type: text
> Content-Length: 1181
>
>
> >>>>> "Jonathan" == Jonathan Payne <jpayne@starwave.com> writes:
>
> Jonathan> [I hope it's OK to forward this to the net, but why
>
> of course.
>
> Jonathan> Here's A.java:
>
> Jonathan> class A { B b;
> Jonathan> A() { b = new B(); } }
>
> Jonathan> Here's B.java:
> Jonathan> class B { A a;
> Jonathan> B() { }
> Jonathan> void setA(A a) { this.a = a; } }
>
> Jonathan> A depends on B, and B depends on A:
>
>
> Ok, this works, but try putting them both in the same package.. Just
> put a 'package test;' at the top of A and B.java.
>
> jsw@transit ~/research/java/mutual 1 -> javac A.java
> A.java:5: Class test.B not found in type declaration.
> B b;
> ^
> A.java:8: Class test.B not found in new.
> b = new B();
> ^
> 2 errors
Ah, I see what's going on. Your problem is that your source files are
not in a directory structure which matches their package statements.
When the compiler is looking for class test.B, it looks throughout
your class path, for a source file called:
test/B.java
Your package hierarchy should match your directory structure for the
compiler to be able to find all the files automatically. In your case
your source files were in "."
./A.java
./B.java
but both classes were defined to be in package test. So the compiler
was handed A.java from the command line, but when it looked for class
B, it's really class test.B, so it looked for the file
./test/B.class (or ./test/B.java)
and couldn't find it.
Note, you could have done it by doing:
javac *.java
Then the compiler would have had all the definitions for all the
classes from the command line, and wouldn't have needed to go looking
for them.
But the best way to do this kind of thing is always have a directory
hierarchy which matches the package hierarchy.
And then you can reuse a simple Makefile template like this one for
Solaris (gee, guess what I am working on). As you can see, I have 3
or 4 different packages in this example, and it all just works fine.
I can remove *.class in the entire hierarchy, and then run javac on
backend/containers/News.java, and it just works, recompiling all the
things that it depends on.
# Define the classes including package name.
#
CLASSES=wire/Slug wire/Header \
\
share/League share/Team share/LineInputStream share/Content \
share/Properties share/NamedPrintStream \
share/OnlineService share/TableInfo share/DatabaseInfo \
share/TableModification share/RecordStream \
\
frontend/TableReader frontend/parsers/Parser \
frontend/parsers/baseball/Leaders \
\
backend/containers/Container backend/containers/News
# Set this if you have classes that are coming from someplace out of
# this hierarchy.
#
CLASSPATH=/home/jpayne/java/classes:.
# Don't touch anything else
#
SRC=${CLASSES:%=%.java}
OBJ=${SRC:%.java=%.class}
all: classes
classes: $(OBJ)
clean:
rm -f $(OBJ)
SUFFIXES = .java .class $(SUFFIXES)
%.class: %.java
javac $<
-
Note to Sun employees: this is an EXTERNAL mailing list!
Info: send 'help' to java-interest-request@java.sun.com