Results 1 to 9 of 9
  1. #1
    JimmyD is offline Member
    Join Date
    Oct 2011
    Location
    New Jersey
    Posts
    44
    Rep Power
    0

    Default Build java classes having circular reference / import

    I am working on some codes that involved a circular reference which gives me a headache to compile. I googled circular reference / import java, the information I found does not really help me to solve the problem. I understand it might be poor design but I am working with codes not written by me or my colleague. Changing the code requires greater effort.

    I wrote a simple test code that isolates the problem. The problem is funny: if I keep class file within the same directory as its source file, it will compile. If I attempt to isolate class file from the .java file, it won't compile. Let me put up my code:

    The directory I am working with is named: C:\java\Testing\testcircular.
    C:\java is added to my CLASSPATH environmental variable.

    I make 2 folders in testcircular called src and com. That's attempting to seperate source code from class files.

    I write 2 simple test classes: called testClass1.java, and testClass2.java . I package testClass1.java into packageA, testClas2 to packageB.

    ================================================== ====
    The code:

    Java Code:
    package Testing.testcircular.src.packageA;
    
    import Testing.testcircular.src.packageB.testClass2;
    
    public class testClass1 {
    	
    	public int a;
    
    	public testClass1()
    	{
    		a = 0;
    	}
    	
    	public void add(testClass2 tc2)
    	{
    		a += tc2.a;
    	}
    
    }

    and

    Java Code:
    package Testing.testcircular.src.packageB;
    
    import Testing.testcircular.src.packageA.testClass1;
    
    public class testClass2 {
    	
    	public int a;
    
    	public testClass2()
    	{
    		a = 1;
    	}
    	
    	public void add(testClass1 tc1)
    	{
    		a += tc1.a;
    	}
    
    }
    I have a simple make.bat file located in C:\java\Testing\testcircular :

    Java Code:
    @echo off
    
    echo compiling packageA
    echo.
    javac src\packageA\*.java
    if not exist com\packageA\nul mkdir com\packageA > nul
    ::move src\packageA\*.class com\packageA
    
    echo.
    echo compiling packageB
    echo.
    javac src\packageB\*.java
    if not exist com\packageB\nul mkdir com\packageB > nul
    ::move src\packageB\*.class com\packageB
    
    javac *.java >nul

    And I have a simple test client that tests whether the classes are working correctly:

    Java Code:
    import Testing.testcircular.src.packageA.testClass1;
    import Testing.testcircular.src.packageB.testClass2;
    
    public class test {
    
    	public static void main(String[] args)
    	{
    		testClass1 tc1 = new testClass1();
    		testClass2 tc2 = new testClass2();
    		
    		System.out.println("Initial tc1 = " + tc1.a);
    		System.out.println("Initial tc2 = " + tc2.a);
    		
    		for (int i = 0; i < 50; i++)
    		{
    			tc1.add(tc2);
    			System.out.println("tc1 = " + tc1.a);
    			tc2.add(tc1);
    			System.out.println("tc2 = " + tc2.a);
    		
    		}
    	
    	}
    
    }

    (Note if working properly, the test client will print the Fibonacci sequence.

    ================================================== ==========


    Now here is the problem: note that in make.bat, I commented out the move statement. So the .class file is left in the src folder. Accordingly, the package statement in the codes bears "package ***.src.packageA" . Now that compilation works, and the test client works fine.

    HOWEVER, if I un-comment the move statement in make file, and change every occurrence of "src" into "com" in the codes, the compilation doesn't work. Could someone help to explain why and offer a solution?

  2. #2
    kjkrum's Avatar
    kjkrum is offline Senior Member
    Join Date
    Apr 2011
    Location
    Tucson, AZ
    Posts
    1,058
    Rep Power
    5

    Default Re: Build java classes having circular reference / import

    Lots of things wrong here.

    First, your classes are in Testing.testcircular.src.* packages, but then you move the class files to testing/testcircular/com. No wonder the compiler can't find them there.

    Say your directory structure looks like this:

    Java Code:
    java
       testcircular
          src
          bin
    src and bin should should both have directory structures inside them corresponding to your package names. You should only be running javac once, and when you do, src should be in your classpath and bin should not (or else javac may find classes in bin and not recompile your changes). If you simply compile the main class of your program, javac will descend into the src tree and compile everything needed, automatically resolving circular references. Then you can copy all the class files to the bin tree, and run your main class with bin in your classpath.

    Also, see the link in my sig for naming conventions. Naming things the way you do makes your code hard to follow.
    Get in the habit of using standard Java naming conventions!

  3. #3
    JimmyD is offline Member
    Join Date
    Oct 2011
    Location
    New Jersey
    Posts
    44
    Rep Power
    0

    Default Re: Build java classes having circular reference / import

    Thanks kjkrum for the reply! I wasn't being accurate when I describe my directory structure. I didn't mess it up though. I did have folders in src.

    The structure looks like this:

    Java Code:
    C:\java\Testing
         testcircular
                com
                      packageA
                              testClass1.class
                      packageB
                              testClass1.class
    
                src
                      packageA
                              testClass1.java
                      packageB
                              testClass1.java
    When you say "You should only be running javac once", could you please show me how to run javac in this case?


    P.S. Thank you so much for the awesome link. I am reading it.

  4. #4
    kjkrum's Avatar
    kjkrum is offline Senior Member
    Join Date
    Apr 2011
    Location
    Tucson, AZ
    Posts
    1,058
    Rep Power
    5

    Default Re: Build java classes having circular reference / import

    That would be the correct directory structure if testClass1 was in the package packageA, not Testing.testcircular.src.packageA. You could run javac like this:

    Java Code:
    cd c:\java\Testing\testcircular\src
    javac -cp . packageA\testClass1.java
    This would compile both testClass1 and testClass2, because the compiler would see the reference to packageB.testClass2 and automatically look for $CLASSPATH/packageB/testClass2.java.
    Get in the habit of using standard Java naming conventions!

  5. #5
    JimmyD is offline Member
    Join Date
    Oct 2011
    Location
    New Jersey
    Posts
    44
    Rep Power
    0

    Default Re: Build java classes having circular reference / import

    I see. However, the code I put up there compiles correctly. I am able to run my make file cleanly. I think the make file is essentially in the same spirit as your 2 step compilation above. because I have C:\java in my CLASSPATH env variable.

    What doesn't work, is if I change every src to com. the error I receive is:

    compiling packageA

    src\packageA\testClass1.java:3: package Testing.testcircular.com.packageB does not exist
    import Testing.testcircular.com.packageB.testClass2;
    ^
    src\packageA\testClass1.java:14: cannot find symbol
    symbol : class testClass2
    location: class Testing.testcircular.com.packageA.testClass1
    public void add(testClass2 tc2)
    ^
    src\packageA\testClass1.java:16: inconvertible types
    found : <nulltype>
    required: int
    a += tc2.a;
    ^
    3 errors

  6. #6
    kjkrum's Avatar
    kjkrum is offline Senior Member
    Join Date
    Apr 2011
    Location
    Tucson, AZ
    Posts
    1,058
    Rep Power
    5

    Default Re: Build java classes having circular reference / import

    Quote Originally Posted by JimmyD View Post
    What doesn't work, is if I change every src to com.
    And I explained why in my first comment. Your directory structure, relative to your classpath, must correspond to your package names.
    Get in the habit of using standard Java naming conventions!

  7. #7
    JimmyD is offline Member
    Join Date
    Oct 2011
    Location
    New Jersey
    Posts
    44
    Rep Power
    0

    Default Re: Build java classes having circular reference / import

    I perhaps only get half of what you mean in your first comment. Let me rephrase my question so you can check my understanding:

    Suppose I want to separate the source code from the class files, how should I do it?

    I can think of 2 naive ways right now:

    1: i code the target direction in source .java files (in my example it would be the "com"), and I compile and move the .class files to those directories.

    2: I leave my source files as the way they are, compile, and then remove the .java files.

    Based on reading your first comment, you seem to imply the 2nd way.

    Quote Originally Posted by kjkrum View Post
    And I explained why in my first comment. Your directory structure, relative to your classpath, must correspond to your package names.

  8. #8
    kjkrum's Avatar
    kjkrum is offline Senior Member
    Join Date
    Apr 2011
    Location
    Tucson, AZ
    Posts
    1,058
    Rep Power
    5

    Default Re: Build java classes having circular reference / import

    1: If you put the classes in a com.* package but they're not in the com/ directory relative to the classpath, they won't compile.

    Classpath trips a lot of people up, but it's not really that complicated. Classpath is simply a directory (or a list of directories) relative to which javac and java look for classes. If your classpath is c:\java, your package name is mypackage, and a class in that package is called MyClass, then the source file must be c:\java\mypackage\MyClass.java and the class file must be c:\java\mypackage\MyClass.class.

    What I'm suggesting is that you can change the classpath between compiling and running. You can make the classpath be c:\java\src when you compile, then move your class files to c:\java\bin and make that the classpath when you run the program.
    Get in the habit of using standard Java naming conventions!

  9. #9
    JimmyD is offline Member
    Join Date
    Oct 2011
    Location
    New Jersey
    Posts
    44
    Rep Power
    0

    Default Re: Build java classes having circular reference / import

    Thank you kjkrum

Similar Threads

  1. Replies: 0
    Last Post: 07-09-2012, 11:00 AM
  2. Replies: 1
    Last Post: 07-02-2012, 07:09 AM
  3. How to reference XMLCatalog from a custom task in a build.xml
    By JavaDeveloperNew in forum Apache Ant
    Replies: 0
    Last Post: 03-27-2012, 11:27 PM
  4. Replies: 6
    Last Post: 09-11-2009, 12:34 AM
  5. Replies: 3
    Last Post: 10-12-2008, 02:49 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •