Hi all,

I have a question on exporting packages and its handling with derived
classes. Any help appreciated!

In a module mod.x one package "pkgx" is exported containing 2 classes Data
and DataFactory.
Another package "pkgxinternal" is not exported and contains the class
InternalData which is derived from Data.

When the DataFactory returns an instance of Data, another module mod.main
can work with its return value, of course.

When the DataFactory returns an instance of InternalData, then this works
fine, *if* the instance is returned as type Data (i.e. of the exported
package).

But when the DataFactory returns an instance of InternalData (i.e. of the
not-exported package), then something weird comes up:

DataFactory does of coure compile. But class Main in module mod.main does
not:

[1] This works fine (i.e. compiles & runs):
System.out.println("Factory.createInternalData2(): " +
myDataFactory.createInternalData2());
This should call toString (from Object, as neither Data nor InternalData
have overloaded toString)

[2] This does not compile. Compile error is "toString() in Object is defined
in an inaccessible class or interface"
System.out.println("Factory.createInternalData2(): " +
myDataFactory.createInternalData2().toString());
The only difference between [1] and [2] is having added ".toString()" !

[3] This does also not compile. Compile error is "getName() in InternalData
is defined in an inaccessible class or interface"
System.out.println("Factory.createInternalData2(): " +
myDataFactory.getName());
The method getName() in InternalData overloads the method in Data, which
should be visible outside.

Any explanation, why [1] is compiling but not [2] ... and why [3] is also
not compiling? 

I have tested this with b132 (jdk1.9.0_ea-b132-x64_20160822_build5414).

Thx in advance.
Cheers,
Martin

# --- src/mod.x/module-info.java ---------
module mod.x {
    exports pkgx;
}

# --- src/mod.x/pkgx/Data.java ---------
package pkgx;
public class Data {
    public String getName() {
        return "is Data";
    }
}

# --- src/mod.x/pkgxinternal/InternalData.java ---------
package pkginternal;

public class InternalData extends pkgx.Data {
    @Override
    public String getName() {
        return "is InternalData";
    }
}

# --- src/mod.x/pkgx/DataFactory.java --------
package pkgx;

public class DataFactory {
// returns data which is exported in Module mod.x
    public Data createData() {
        return new Data();
    }

// returns data which is not exported from Module mod.x
// (but as type of the exported super class, i.e. as type Data)
    public Data createInternalData1() {
        return new pkginternal.InternalData();         
    }                                                   

// returns data which is not exported from Module mod.x
// i.e. as type InternalData
    public InternalData createInternalData2() {
        return new pkginternal.InternalData();                      
    }
}

# --- src/mod.main/module-info.java --------
module mod.main {
    requires mod.x;
}

# --- src/mod.main/pkgmain/Main.java ---DOES NOT COMPILE BECAUSE OF [2] and
[3] ------
package pkgmain;

import pkgx.*;

public class Main {
  public static void main(String[] args) {
    DataFactory myDataFactory = new DataFactory();

// all OK
   System.out.println("Factory.createData(): " +  
         myDataFactory.createData().getName());
   System.out.println("Factory.createInternalData1().toString(): " + 
         myDataFactory.createInternalData1().toString());
   System.out.println("Factory.createInternalData1(): " + 
         myDataFactory.createInternalData1().getName());

// [1]*does* compile though return type of 
// 'DataFactory.createInternalData2()' is not visible here
   System.out.println("Factory.createInternalData2(): " + 
         myDataFactory.createInternalData2());

// [2] does not compile. error: toString() in Object is 
//     defined in an inaccessible class or interface
// surprise! why is [1] OK while adding toString() is not?
   System.out.println("Factory.createInternalData2().toString(): " + 
         myDataFactory.createInternalData2().toString());

// [3] does not compile. error: getName() in InternalData is 
//     defined in an inaccessible class or interface
// suprise! getName() is overloaded, available in exported class Data

   System.out.println("Factory.createInternalData2().getName(): " +  
       myDataFactory.createInternalData2().getName());
  }
}


Reply via email to