What module is the unnamed package part of in Java? - java

I think that the unnamed package is part of the unnamed module, however I can't be sure as I can't find any answers online, so I posted my question here.
From https://docs.oracle.com/javase/tutorial/java/package/createpkgs.html:
If you do not use a package statement, your type ends up in an unnamed package. Generally speaking, an unnamed package is only for small or temporary applications or when you are just beginning the development process. Otherwise, classes and interfaces belong in named packages.
*Edit: The answer is that the unnamed package is part of the unnamed module

It is in a (the) unnamed module.
According to the Java 11 edition of the JLS 7.4.2
The host system must associate ordinary compilation units in an unnamed package with an unnamed module (§7.7.5), not a named module.
This is more authoritative than the Java Tutorial.

Related

What's the difference between the 'java.se' and 'java.base' Module in Java Platform Modules System

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.

Unnamed module interaction with named module by ServiceLoader::load

I have a project like this:
\---main
\---src
\---com.foo
\---UnnamedStart.java
\---api
\---src
\---com.foo.api
\---ApiInterface.java
\---module-info.java
\---impl
\---src
\---com.foo.impl
\---ApiInterfaceImpl.java
\---module-info.java
Implementatio of UnnamedStart.java is:
public static void main(String[] args) {
ServiceLoader<ApiInterface> services = ServiceLoader.load(ApiInterface.class);
...
}
Note that main is unnamed module.
api/src/module-info.java is:
module com.foo.api {
exports com.foo.api;
}
and impl/src/module-info.java is:
update 1.1 - code below updated see comments, added requires
update 1.2 - code below updated, provides A with B changed to provides B with A mistake during creating question, originally was ok
module com.foo.impl {
requires com.foo.api; //added (update 1.1)
provides com.foo.impl.ApiInterface
with com.foo.api.ApiInterfaceImpl; //vice versa (update 1.2)
}
When I run my code in UnnamedStart.java I end up with no element in services.
I also tried to create a static method in com.foo.api.ApiInterface:
static List<ApiInterface> getInstances() {
ServiceLoader<ApiInterface> services = ServiceLoader.load(ApiInterface.class);
List<ApiInterface> list = new ArrayList<>();
services.iterator().forEachRemaining(list::add);
return list;
}
and add in api/src/module-info.java line uses com.foo.api.ApiInterface; but it gave the same result (nothing).
The only way I made it work is by migrating main from unnamed to named module.
1. How does java 9 work when unnamed module trying to interact with named module?
2. Does it possible to make it work and keeping the main like unnamed module?
update 1.3 - added related project
ServiceLoader::load works as usual, but the are other things.
[Short answer]
1. Unnamed module reads the same like named module to named module, but named module can not access types in the unnamed module.
2. You are trying to launch an application from a non-modular JAR so you have to explicitly resolve required modules by --add-modules com.foo.impl.
Note that your required modules have to be on module graph (e.g. add by --module-path).
[More details]
1. There are 4 different types of modules: built-in platform module, named module, automatic module, unnamed module and each of them are named apart from unnamed module
As they wrote the unnamed module treats all the other modules the same like named module:
All other modules have names, of course, so we will henceforth refer to those as named modules.
The unnamed module reads every other module. [...]
The unnamed module exports all of its packages. [...] It does not, however, mean that code in a named module can access types in the unnamed module. A named module cannot, in fact, even declare a dependence upon the unnamed module.
[...]
If a package is defined in both a named module and the unnamed module then the package in the unnamed module is ignored.
Even an automatic module indeed is also named:
An automatic module is a named module that is defined implicitly, since it does not have a module declaration.
2. Second part of this answer
If you compile non-modular code or launch an application from a non-modular JAR, the module system is still in play and because non-modular code does not express any dependencies, it will not resolve modules from the module path.
So if non-modular code depends on artifacts on the module path, you need to add them manually with the --add-modules option. Not necessarily all of them, just those that you directly depend on (the module system will pull in transitive dependencies) - or you can use ALL-MODULE-PATH (check the linked post, it explains this in more detail).
This #nullpointer comment will be useful
Also, the module resolution still needed the impl to be resolved during the startup. To check which you could also make use of the --show-module-resolution flag.

java 9: In module-info.java do i have to again mention packages((as requires) that are already being imported in sources

working with java 9 modules, if i am using java.xml in my code...
1) i will import xml package using import statement...
2) if i don't mention that this package is required in the module declaration of my module...
- will the compilation of my module work.. ??
i would guess... no... and on mentioning that xml package is required on module-info.java... it might work.
so.. what I am wondering is... is that not redundancy... every importing package is implicitly... required. (unless i need to understand module even better)
Is there a way to mention that all imported packages are required in module declaration, other wise it could be a long list to mention in module-info.java?
First of all, in module-info.java you mention modules, not packages. E.g. java.xml is a module which contains about 25 packages. So, if your module uses 10 packages from the java.xml module, you don't have to repeat that 10 times in module-info.java, you write requires java.xml just once. So, that huge list of dependencies is not huge actually.
If you really want to skip all those declarations, you can just not create module-info.java (but I don't recommend to do that). A module that does not have module-info.java is called an automatic module and it implicitly requires all other modules.

What happens when you don't create a package and have a protected variable? [duplicate]

Let's assume I have a file named Main.java with the following code:
public class Main {
public static void main(String[] args) {
System.out.println("Hello world");
}
}
Is it put in a specific package, in (maybe?) an unnamed package?
A class that is not in a named package is in an unnamed package. Thus the full class name is Main.
Such classes cannot be used from a named package, except via reflection.
The JLS says that:
Unnamed packages are provided by the Java SE platform principally for convenience when developing small or temporary applications or when just beginning development.
Java does not have namespaces, it has packages. And yes, classes with no package declarations are implicitly part of an "unnamed package", often also called "default package". However, since it's not possible to import classes from an unnamed package and since the language spec explicitly allows implementations to have different rules about whether and how classes in unnamed packages are visible to each other, it's generally a good idea to put all classes in named packages except for experimental code.
According to the JLS it's called:
7.4.2 Unnamed Packages
A compilation unit that has no package declaration is part of an unnamed package.

Method getModule returning unnamed module for class in named module

I just started to have a look at the Java 9 module system and I was wondering whether it is possible for a class to know in which module it is located.
Therefor I created the following module
module de.test {
exports de.test.myexport;
}
and compiled a jar file that looks like
> jar --print-module-descriptor --file=Java9Test-1.0-SNAPSHOT.jar
de.test
requires mandated java.base
exports de.test.myexport
In package de.test, I have a class called Overview where I'm calling
Module module = Overview.class.getModule();
However, the returned module object is unnamed and has no ModuleDescriptor.
Am I using getModule() correctly here, or is there any other way to load the module of a class?
I'm using JDK 9 build 120 on OS X.
All JARs on the class path (with java --class-path ...) get bundled into the same so-called unnamed module, regardless of whether they are "a real module" or "just a JAR". When you ask a class from such a JAR for its module, you get the result you describe.
Try putting the JAR on the module path (with java --module-path ...) and Class::getModule should return what you expect.

Categories

Resources