I have a question concerning default packages in Java.
It is written in Java SE 8 specification:
An implementation of the Java SE platform must support at least one
unnamed package. An implementation may support more than one unnamed
package, but is not required to do so. Which compilation units are in
each unnamed package is determined by the host system.
see section 7.4.2 in the JLS.
I.e. it is possible to have more than one unnamed package.
As I understand Oracle implementation of Java 8 SE has only one unnamed package.
Do you know, is this feature is implemented somewhere?
Or do you have any idea how it could be implemented?
It looks like they leave the details of implementing the feature up to Java implementors.
But there is no any of such implementation yet.
Note:
Of cource we can have several source folders: src1, src2, ..., srcN but all of them share the same default package.
See, for example, https://docs.oracle.com/javase/tutorial/java/package/createpkgs.html
Related
I am not sure if I got it right: java.base is the underlying base module from all other modules and contains all the base stuff from them, like a superclass from a class. And java.se is the module which contains the whole JDK, like a subclass (which contains the basic functionality and more specific stuff)
java.base is the base module; every other module implicitly or explicitly depends on it:
If the declaration of a module does not express a dependence on the java.base module [...] then the module has an implicitly declared dependence on the java.base module.
(Java Language Specification 17 §7.7.1)
java.se "defines the API of the Java SE Platform" (per documentation). It roughly (?) comprises all the classes which were present in Java SE before modularization, except being separated now in different modules, e.g. java.desktop or java.sql. It does not include JDK specific modules (such as jdk.javadoc). A Java runtime might not necessarily provide all of these modules; for example you could use jlink to create a Java runtime which only contains the modules you need (at the minimum java.base).
The Java API specification can also be helpful for understanding the content of modules and their relations:
java.base
java.se
Your comparison with a class (module java.base) and its subclass (module java.se) works in this case because java.se acts kind of like an 'aggregator' module which itself does not contain or export any packages but only has indirect exports through requires transitive. See this question for why the java.se module exists. Although normally you would not declare a dependency on java.se because that defeats the purpose of making custom small runtime images; instead you would only declare dependencies on the specific modules you really need, e.g. java.logging.
Such aggregator modules are rather uncommon though. In most cases modules will rather be used for grouping related packages, and restricting access to internal implementations. However, in these cases services defined by one module and the corresponding service provider being implemented and declared by another module are similar to your analogy.
I'm working now together with others in a grails project. I have to write some Java-classes. But I need access to an searchable object created with groovy. It seems, that this object has to be placed in the default-package.
My question is: Is there a way to access this object in the default-package from a Java-class in a named package?
You can’t use classes in the default package from a named package.
(Technically you can, as shown in Sharique Abdullah's answer through reflection API, but classes from the unnamed namespace are not in scope in an import declaration)
Prior to J2SE 1.4 you could import classes from the default package using a syntax like this:
import Unfinished;
That's no longer allowed. So to access a default package class from within a packaged class requires moving the default package class into a package of its own.
If you have access to the source generated by groovy, some post-processing is needed to move the file into a dedicated package and add this "package" directive at its beginning.
Update 2014: bug 6975015, for JDK7 and JDK8, describe an even stricter prohibition against import from unnamed package.
The TypeName must be the canonical name of a class type, interface type, enum type, or annotation type.
The type must be either a member of a named package, or a member of a type whose outermost lexically enclosing type is a member of a named package, or a compile-time error occurs.
Andreas points out in the comments:
"why is [the default package] there in the first place? design error?"
No, it's deliberate.
JLS 7.4.2. Unnamed Packages says: "Unnamed packages are provided by the Java SE platform principally for convenience when developing small or temporary applications or when just beginning development".
In fact, you can.
Using reflections API you can access any class so far. At least I was able to :)
Class fooClass = Class.forName("FooBar");
Method fooMethod = fooClass.getMethod("fooMethod", String.class);
String fooReturned = (String)fooMethod.invoke(fooClass.newInstance(), "I did it");
Use jarjar to repackage the jar file with the following rule:
rule * <target package name>.#1
All classes in the default package of the source jar file will move to the target package, thus are able to access.
You can use packages in the Groovy code, and things will work just fine.
It may mean a minor reorganization of code under grails-app and a little bit of a pain at first, but on a large grails project, it just make sense to organize things in packages. We use the Java standard package naming convention com.foo.<app>.<package>.
Having everything in the default package becomes a hindrance to integration, as you're finding.
Controllers seem to be the one Grails artifact (or artefact) that resists being put in a Java package. Probably I just haven't figured out the Convention for that yet. ;-)
just to complete the idea:
From inside default-package you can access objects resided in named packages.
I have my old codebase which currently uses java8.
I am migrating my codebase to use jdk9-ea. But it looks like all the sun.font classes are now not available like the way they used to be earlier
error: package sun.font does not exist
More specifically i am using
CompositeFont
Font2D
FontDesignMetrics
FontManager
FontManagerFactory
SunFontManager
and more..
A feature of the module system is that it allows library developers to strongly encapsulate implementation details due to the new accessibility rules. In a nutshell, most types in sun.* and com.sun.* packages will no longer be accessible. This is in line with Sun and later Oracle stating that these packages are not meant for public consumption.
A workaround is to export these packages at compile and launch time with a command line flag:
--add-exports java.desktop/sun.font=ALL-UNNAMED
This exports the package sun.font from the module java.desktop to all modules including the unnamed module, which is the one that collects all classes on the class path.
what is the default package and default class in java?
i checked on the internet but couldn't find a concrete answer. So please reply for my question.
There's no such thing as "default class". "Default package" is another word for the "unnamed package" described in the Java Language Specification section 7.4.2
If you don’t explicitly package your classes or interfaces, In that case, they’re
packaged in a default, no-name package. This default package is automatically imported in
the Java classes and interfaces defined within the same directory on your system.
A class from a default package can’t be used in any named packaged class, regardless
of whether they are defined within the same directory or not.
I'm working now together with others in a grails project. I have to write some Java-classes. But I need access to an searchable object created with groovy. It seems, that this object has to be placed in the default-package.
My question is: Is there a way to access this object in the default-package from a Java-class in a named package?
You can’t use classes in the default package from a named package.
(Technically you can, as shown in Sharique Abdullah's answer through reflection API, but classes from the unnamed namespace are not in scope in an import declaration)
Prior to J2SE 1.4 you could import classes from the default package using a syntax like this:
import Unfinished;
That's no longer allowed. So to access a default package class from within a packaged class requires moving the default package class into a package of its own.
If you have access to the source generated by groovy, some post-processing is needed to move the file into a dedicated package and add this "package" directive at its beginning.
Update 2014: bug 6975015, for JDK7 and JDK8, describe an even stricter prohibition against import from unnamed package.
The TypeName must be the canonical name of a class type, interface type, enum type, or annotation type.
The type must be either a member of a named package, or a member of a type whose outermost lexically enclosing type is a member of a named package, or a compile-time error occurs.
Andreas points out in the comments:
"why is [the default package] there in the first place? design error?"
No, it's deliberate.
JLS 7.4.2. Unnamed Packages says: "Unnamed packages are provided by the Java SE platform principally for convenience when developing small or temporary applications or when just beginning development".
In fact, you can.
Using reflections API you can access any class so far. At least I was able to :)
Class fooClass = Class.forName("FooBar");
Method fooMethod = fooClass.getMethod("fooMethod", String.class);
String fooReturned = (String)fooMethod.invoke(fooClass.newInstance(), "I did it");
Use jarjar to repackage the jar file with the following rule:
rule * <target package name>.#1
All classes in the default package of the source jar file will move to the target package, thus are able to access.
You can use packages in the Groovy code, and things will work just fine.
It may mean a minor reorganization of code under grails-app and a little bit of a pain at first, but on a large grails project, it just make sense to organize things in packages. We use the Java standard package naming convention com.foo.<app>.<package>.
Having everything in the default package becomes a hindrance to integration, as you're finding.
Controllers seem to be the one Grails artifact (or artefact) that resists being put in a Java package. Probably I just haven't figured out the Convention for that yet. ;-)
just to complete the idea:
From inside default-package you can access objects resided in named packages.