my dog learned polymorphism*
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes compilation error Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Murach's Java Servlets and JSP this week in the Servlets forum!
JavaRanch » Java Forums » Certification » Programmer Certification (SCJP/OCPJP)
Bookmark "compilation error" Watch "compilation error" New topic
Author

compilation error

Dan Andrei
Ranch Hand

Joined: Jan 21, 2004
Posts: 92
Given the code:
// default package
import A1.*;
public class TestProtected2 {
public static void main(String arg[]){
System.out.println(new Sub().f());
}
}

package A1;
public class Sub extends TestProtected2 {
protected int f(){return 1;}
}
I get the following errors at compilation:
.\A1\Sub.java:3: cannot resolve symbol
symbol : class TestProtected2
location: class A1.Sub
public class Sub extends TestProtected2 {
^
C:\j2sdk1.4.2_03\JLS2.0\TestProtected2.java:6: f() has protected access in A1.Sub
System.out.println(new Sub().f());
^
2 errors
Tool completed with exit code 1
The second error is expected , but what about the first, I do not understand since TestProtected2 is public…


"Did anyone understand what I have just explained? ... because I did not!"
Vicken Karaoghlanian
Ranch Hand

Joined: Jul 21, 2003
Posts: 522
Dan, both classes won't compile because they totally depend on each other, that is you can't compile TestProtected2 without compiling Sub first and vise-versa.


- Do not try and bend the spoon. That's impossible. Instead, only try to realize the truth. <br />- What truth? <br />- That there is no spoon!!!
Dan Andrei
Ranch Hand

Joined: Jan 21, 2004
Posts: 92
Vicken can you be more clearer...
IF I put both classes in the SAME package leaving Sub non-public it Compiles fine
IF I put them in different packages (the case I posted) I get two erorrs, the second one regarding the access is OK since I try to access through a subclass object in a superclass and so on...
However I don NOT understan why I get he first erorr since TestProtected2 is PUCLIC class so it can be accessed in ALL packages ?
I think you did not notice yhey were in different packages
Vicken Karaoghlanian
Ranch Hand

Joined: Jul 21, 2003
Posts: 522
In order for you to have a clear view of what is happing here, you should know that before a subclass can be compiled its super class must be compiled first (This is usually done automatically by the compiler when you compile the subclass), but in your case this is not what is happening.
Let us try to compile both classes manually:
  • TestProtected2 won't compile because you are importing a package that doesn't exist (A1), Not at least class 'Sub' is compiled.
  • Sub won't compile because you must compile its superclass first (in which case you can't for the reason specified in my first point)


  • I hope my explanation is correct, because i am not that good in the packages field.
    Dan Andrei
    Ranch Hand

    Joined: Jan 21, 2004
    Posts: 92
    I made TestProtected2 empty and I get the same error (this make no sense !!)
    Vicken I did some "digging" and I came up with the following explanation:
    I think it has to do with CLASSPATH setting
    My CLASSPATH was set "current directory" and path to the directory .../A1
    Now first when I was compiling the superclass it compiled since is in the default package.
    Now when I moved to the .../A1 directory to compile class Sub, and tried to compile it gave me an error because now "I lost" the path to the .class of
    TestProtected since now the "current directory" is the same as .../A1 directory.
    To solve the problem I put TestProetected2 in a specific package say B1, pu t in the Classpath and it compiles fine now, even with the imports and everything else.
    OR to have the subclass in the default package NOT the superclass (in the case that you want to use a default package after all)
    Vicken Karaoghlanian
    Ranch Hand

    Joined: Jul 21, 2003
    Posts: 522
    Dan, the CLASSPATH thing crossed my mind, but I didn't think it was the problem (I still don't). You should include it in the CLASSPATH however, but I don't think it is the reason that is preventing you from a successful compile.
    What confuses me here, the part where you can compile the superclass (testprotected2.java)!!! Because this file contains an import statement (import A1.*) that does not exist (at least not before you compile sub.java).
    The CLASSPATH variables indicated where java should search for classes whenever it encounters an import statement.
    The testprotected2.java is not compiling at my side, perhaps I am missing something...hmmm... I don't know.
    If you find something new don't forget to inform me.
    Dan Andrei
    Ranch Hand

    Joined: Jan 21, 2004
    Posts: 92
    First I want to say that I use the j2sdk1..4.2._03 when I compiled the files
    I also want to make some observations to your comment:
    “What confuses me here, the part where you can compile the superclass (testprotected2.java)!!! Because this file contains an import statement (import A1.*) that does not exist (at least not before you compile sub.java).”
    The CLASSPATH variables indicated where java should search for classes whenever it encounters an import statement. “
    From what I know the import statement makes java classes available to a package under an abbreviated name. Public classes are always available by their fully qualified name, assuming that the appropiate class file can be found related to the CLASSPATH variable. Import doesn’t actually makes the class available, is simply saves typing and makes code more readeable.

    As I said in a prevoius post IF TestProtected2 (TP2) is “empty”, like:
    //default package starts here
    import a1.*
    public class TestProtected2 {
    public static void main(String arg[]){
    }
    }
    it compiles , BUT I noticed that if I change the import to a1.Sub instead of a1.* it gives me an error!!!.
    Since these is an inconsistency on the part of the compiler I dropped the import statement and I tried to use qualified access in the TP2 class like new a1.Sub().f(), and I get the same error as in the case for import a1.Sub
    If a drop the import all together and the qualified access I still get the same error:
    .\A1\Sub.java:3: cannot resolve symbol
    symbol : class TestProtected2
    location: class A1.Sub
    public class Sub extends TestProtected2 {
    and in this case (no import at all, and empty TP2 class) I think is clearly classpath related.
    Now if a put TP2 in a distinct package with appropiate CLASSPATH settings it compiles fine.
    Of course this works when I have the initial TP2 setup also (new a1.Sub().f()).
    Interesting is that if a swap the classes, that is put Sub in default package and TP2 in a1 package and TP2 is empty I do not get an error, this also comes to underline the classpath reasoning.
    Now the bottom line to all these is that the difference between getting the files compiled or not is the use of the default package.
    Vicken Karaoghlanian
    Ranch Hand

    Joined: Jul 21, 2003
    Posts: 522
    Sorry but I still insist that the parent won't compile on its own, let me explain the reason.
    Consider your Parent class

    Now this class will compile IF AND ONLY IF there was a sub directory named 'A1' in your class path AND this directory (A1) contains at least one *.java or *.class file in it. I am guessing you put the 'Sub.java' in this directory, right? If so, the import statement is executing successfully -- thus allowing the previous code to compile fine.
    However, adding "new Sub().f()" will generate an error because 'sub.java' is not compiled yet thus we can't create an object of it, right? Good. Now this shows clearly th reason why TestProtected2.java won't compile.
    So let us try to compile 'sub.java'... Oh wait... we can't do that because Sub extends TestProtected2, therefore it needs 'TestProtected2.class' which does not exist.
    As you can see you can't compile any class without compiling the other first, it is an infinite loop.
    Hope I made it clear this time.
    [ February 16, 2004: Message edited by: Vicken Karaoghlanian ]
    Dan Andrei
    Ranch Hand

    Joined: Jan 21, 2004
    Posts: 92
    Your expalnation is OK but you're looking at the runtime scenario in my opinion:
    "However, adding "new Sub().f()" will generate an error because 'sub.java' is not compiled yet thus we can't create an object of it, right?"

    But the loading happens at RUNTIME, WHEN IT ENCOUNTERS new()... it goes and searches the classpath andloads the .class file, we are at compile time here!!!
    change TP2 as follows:
    //default package
    public class TestProtected2 {
    public static void main(String arg[]){}
    void foo(A1.Sub x){}
    /*here is no static access or instantiaiton just declaration and I still get an error*/
    }
    Have you tried on your compiler the case with no default package?
    I also tried the example on an older compiler and I get the same results
    Vicken Karaoghlanian
    Ranch Hand

    Joined: Jul 21, 2003
    Posts: 522
    Originally posted by Dan Andrei:
    But the loading happens at RUNTIME, WHEN IT ENCOUNTERS new()... it goes and searches the classpath andloads the .class file, we are at compile time here!!!

    That is true the class is loaded at Runtime, BUT first the compiler must be satisfied that it can indeed create an instance of the object 'Sub().f()'. This is done at compile-time not Run-time.
    Failing to comply with this rule will generate a compile-time error.
    Check out this code that demonstrate what I was talking about (Both classes in this example are in the same default package -- changing packages won't make it any more different)

    The scenario in my previous post was a compile-time scenario, however I can't say that the runtime-scenario will differ much. More or less they are the same, except that at runtime the class is actually loaded and objects are created.
    Originally posted by Dan Andrei:
    Have you tried on your compiler the case with no default package?
    I also tried the example on an older compiler and I get the same results

    There is no problem with the compiler, I am sure you'll get the same result over and over again every time you compile on a different version of JDK, it is simply a matter of understanding.
    Dan Andrei
    Ranch Hand

    Joined: Jan 21, 2004
    Posts: 92
    your la last example will not compile BECAUSE anotherMethod() is not DEFINED
    which is totally different. Thats why a posted my example before just with a declaration in the method arg list:
    public class TestProtected2 {
    public static void main(String arg[]){}
    void foo(A1.Sub x){}
    /*here is no static access or instantiaiton just declaration and I still get an error*/
    }

    However your explanation for my example was based on CLASS CREATION
    IF I have to agree with your REASONING, would mean that:
    IN A SUPERCLASS YOU CANNOT INSTANTIATE A SUBLCASS OR HAVE A STATIC ACCESS TO It, which in my opinion is wrong...(why then if you put both classes in the same package it works, and runs fine?)
    I went back and looked at some of my code examples and I found a couple resembling this one, the ONLY reason I had no problem was that I did not use one of the packages as default.
    Even here, accidentally I used the default package which in turn "generated" my problem.
    Basically my whole dilema is why it Does not work when using a default package?. I looked in the JVM and JLS and I did not find anything on the topic.
    The reason I asked about the compiler, is that I thought you get compile error in BOTH cases.
    By the way when I tried to compile it using the old compiler JDK1.1(helloooo
    grandpa !) at some point it gave an error message tellig me to change the default package !!!
    Vicken Karaoghlanian
    Ranch Hand

    Joined: Jul 21, 2003
    Posts: 522
    I see where you are going at Dan, you are probably correct too, especially the part you said that the statement "IN A SUPERCLASS YOU CANNOT INSTANTIATE A SUBLCASS OR HAVE A STATIC ACCESS TO IT" is wrong.
    One of the solution for your given scenario is to import the default package, correct?
    If this what you are trying to do, then you'll definitely find this article very very interesting.
    Dan Andrei
    Ranch Hand

    Joined: Jan 21, 2004
    Posts: 92
    “Though Sun isn't disallowing the default package, it is disallowing a class in a named package from using a class in the default package.”
    The above statement is from the article and it explains everything, actually is not import statement, but using the class.
    I admit that I never tried to import the default package. Is strange JLS does not talk about this issue, because is an important one.
    Now, something I want to mention in a previous post but a forgot regarding your example which I copied below:
    import A1.*;
    public class TestProtected2 {

    public static void main(String arg[]){
    System.out.println("Parent");
    }
    }
    ...
    “However, adding "new Sub().f()" will generate an error because 'sub.java' is not compiled yet thus we can't create an object of it, right? Good. Now this shows clearly th reason why TestProtected2.java won't compile. “
    The reason it gives an error is BECAUSE IT CANNOT FIND SUCCESFULLY THE DEFINITION (not because it cannot create a class !!!) FOR Sub…( it looks for Sub DEFINITION in the current file and it cannot find it, looks in the classpath and finds package a1, finds definition of Sub, but also TestProtected2 and here the error comes BECAUSE QUOTE FROM article:
    “Though Sun isn't disallowing the default package, it is disallowing a class in a named package (Sub)from using a class in the default package (TestProtected2).”
    In the beginning it seemed strange to me when I was compiling TP2.java the compiler gave an error in Sub.java saying “unresolved symbol”, now it makes sense

    Vicken I want to thank for taking the time and searching an answer for the “dilema” on the net... a thing I did not (SHAME ON ME!)
    Vicken Karaoghlanian
    Ranch Hand

    Joined: Jul 21, 2003
    Posts: 522
    We all learn from the mistakes we make. My previous posts suffered from significant inconsistencies that you corrected successfully, especially in the last part of your post.
    Your question improved my knowledge in the packages field with a big time, for that I am thankful.
    "A good question is a question that we all learn from."
    The great thing about forums and communities is threads like the one you�ve posted, threads that make you think, threads that make you want to dig� to discover.
    Hope to see more questions like the one you posted� until then, good luck and see you around.
     
    jQuery in Action, 2nd edition
     
    subject: compilation error
     
    Similar Threads
    Please explain this code
    problem on extending a class declared on the same package!!
    protected method not being overridden in diff. package
    class not found
    Possible error in K&B book (resolved - no error)