Win a copy of Node.js Design Patterns: Design and implement production-grade Node.js applications using proven patterns and techniques this week in the Server-Side JavaScript and NodeJS forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Ron McLeod
  • Rob Spoor
  • Tim Cooke
  • Junilu Lacar
Sheriffs:
  • Henry Wong
  • Liutauras Vilda
  • Jeanne Boyarsky
Saloon Keepers:
  • Jesse Silverman
  • Tim Holloway
  • Stephan van Hulst
  • Tim Moores
  • Carey Brown
Bartenders:
  • Al Hobbs
  • Mikalai Zaikin
  • Piet Souris

OCP Java SE 11 Programmer II Study Guide (Sybex 816) Possible Errata Chapter 6

 
Saloon Keeper
Posts: 1338
40
Eclipse IDE Postgres Database C++ Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I found the wording used in Jeanne and Scott's Sybex 816 book (and the corresponding chapter in the CSG) to be somewhat confusing, or rather to impart a conception of something that caused me trouble when reading/watching other things later.

I will quote the section on Unnamed Modules in full, so as not to present it out of context.

Jeanne and Scott's Sybex 816 book wrote:An unnamed module appears on the classpath.  Like an automatic module, it is a regular JAR.  Unlike an automatic module, it is on the classpath rather than the module path.  This means an unnamed module is treated like old code and a second-class-citizen to modules.  Figure 6.3 shows an unnamed module with one package.

[Here, the illustration shows that zoo.legacy.jar is an unnamed module]

An unnamed module does not usually contain a module-info file.  If it happens to contain one, that file will be ignored since it is on the classpath.

Unnamed modules do not export any packages to named or automatic modules.  The unnamed module can read from any jars on the classpath or module path.  You can think of an unnamed module as code that works the way Java worked before modules.  Yes, we know it is confusing to have something that isn't really a module to have the word module in its name.



There's a lot of good stuff in there, and I am not complaining just to complain, so let me highlight the misconception I took away from this.

They make it sound like if you have 279 .JAR files on your classpath, you have 279 unnamed modules, at least that is how I read it.
The words that made me think that were:  "Like an automatic module, it is a regular JAR. " and the description saying the illustration of a single JAR showed an unnamed module.

Now in actuality, the way that we use the term seems to be similar to the "unnamed package" when it comes to packages.  Within the scope of a single compilation or execution, there is only one "unnamed package" for a Java program.  If we compile 128 sources, or are running 96 classes all defined with no package definition at the top of their source, they are all together, sloppy and happy in their big old "unnamed package" together.  It is impossible for code in other packages to import them or refer to them, it isn't a good practice, but they are most decidedly "all in the same package" for all purposes I can think of, mostly accessibility and potential for fatal naming conflicts.

The "unnamed module" is a similar concept.  We aren't happy to see it, but when we do, we know it is "One Big Sloppy, Happy unnamed module" for all intents and purposes.  If there are 146 jars on our classpath when we compile or run, all that code is in the same module.  Other modules can't requires it because it has no name.  If 20 of the jars happen to all contain the same package name, lots of people will be confused and distressed, but that is 100% legal, just terrible.  But it is just one module, for all purposes.  Everything in it can access everything else in it without any benefit or protection from JPMS, it is legacy Wild Wild West behavior.  This big gloppy ball of stuff can access named and automatic modules (exactly how is beyond the scope of the exam) but those modules can't access it.

So I find it rather confusing to call a JAR sitting around somewhere on the file system that may or may not have a module-info element in it "an unnamed module".

A .JAR file, whether or not it has module-info in it becomes part of the unnamed module by virtue of being listed on the classpath.
That same .JAR file, if it has no module-info in it will become a SINGLE AUTOMATIC MODULE if it is placed on the module-path, and will in fact be a NAMED MODULE if it does contain a module-info in it.

So just looking at a single .JAR file, yes, we can say whether it would be a named module or an automatic module were it to be found on the module-path at compile time or runtime, but we can never say a .JAR file *is* an unnamed module without context.  If we see the compilation or run (and possibly the value of a CLASSPATH environment variable) then we can say a whole list of .JAR files/packages that will be part of "The Unnamed Module" in that context, which is rather a different thing.
 
Jesse Silverman
Saloon Keeper
Posts: 1338
40
Eclipse IDE Postgres Database C++ Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I have another quibble.  Maybe more than a quibble, I am unsure.  Hopefully they won't multiply like tribbles.

Let me reproduce the table that is meant to summarize the different characteristics of Named, Automatic and The Un-Named Module:

TABLE 6.3 Properties of modules types
---------------------------------------------------------------------------------------------------------------------
Property                                                           Named                   Automatic   Unnamed
---------------------------------------------------------------------------------------------------------------------
A ______ module contains a module-info file?       Yes                            No         Ignored if Present


A ______ module exports which packages to                                      All packages    No packages
          other modules?                                    Those in module-info file  


A ______ module is readable by other modules     Yes                         Yes                    No
          on the module path?                                

A ______ module is readable by other JARS
            on the classpath?                                     Yes                         Yes                   Yes

Earlier today, I learned thru Stephan's educational efforts that the Named and Automatic modules are indeed readable by JARS on the classpath.
How to do so is not in scope of the exam, and not shown in the book, but I no longer have any qualms about the last line of this table.

But not so good on the third line.  I think I have a problem with there even being one third line instead of two, if I am not totally confused.

This is because the same answer isn't true about all modules on the module path!

The last column of the third row currently reads "No", which says that packages in the Unnamed Module will not be available to code in either Named or Automatic Modules.

This is not my understanding.  A big win in using Automatic Modules was precisely the advantage that they CAN read stuff from the Unnamed Module, quite UNLIKE Named Modules, which, of course, can not.

I couldn't find a Javadocs reference but here are two that I've found that together make me almost certain that Automatic Modules have access to the code that is in JAR files only found on the classpath:

https://openjdk.java.net/projects/jigsaw/spec/sotms/#automatic-modules :

To enable migration even when some JAR files cannot be used as automatic modules we enable automatic modules to act as bridges between code in explicit modules and code still on the class path: In addition to reading every other named module, an automatic module is also made to read the unnamed module. If our application’s original class path had, e.g., also contained the JAR files org-baz-fiz.jar and org-baz-fuz.jar, then we would have the graph...
(shows a graph)
The unnamed module exports all of its packages, as mentioned earlier, so code in the automatic modules will be able to access any public type loaded from the class path.

An automatic module that makes use of types from the class path must not expose those types to the explicit modules that depend upon it, since explicit modules cannot declare dependences upon the unnamed module. If code in the explicit module com.foo.app refers to a public type in com.foo.bar, e.g., and the signature of that type refers to a type in one of the JAR files still on the class path, then the code in com.foo.app will not be able to access that type since com.foo.app cannot depend upon the unnamed module. This can be remedied by treating com.foo.app as an automatic module temporarily, so that its code can access types from the class path, until such time as the relevant JAR file on the class path can be treated as an automatic module or converted into an explicit module.



and http://tutorials.jenkov.com/java/modules.html#automatic-modules :

An automatic module can read classes in the unnamed module. This is different from explicitly named modules (real Java modules) which cannot read classes in the unnamed module.



So, certainly both named and automatic modules are readable by any other named or automatic module on the module-path.
A Named Module can read any Named or Automatic Module on the module-path by just saying:
requires NamedOrAutomaticModName
or
requires transitive NamedOrAutomaticModName

So that part is good, we even know how to do it.  Automatic Modules require all Named and all Automatic Modules, well...automatically...their whole reason for existence is to let us solve otherwise unsolvable migration problems until we live in a fully modular world...

But how can we give a single answer to "Is the Unnamed Module readable to (sic) other modules on the module path?"
It is a trick question, because NO NAMED MODULE may access it, but as a compromise hack to let people deal with a Partially Modularized World, it would seem (evidence above) that Automatic Modules indeed CAN and MAY WELL NEED TO  access code in the UNNAMED MODULE.

Which brings us to the Second Row, Last Column.
The goofy Unnamed Module doesn't explicitly export anything to anyone, it just sits there grinning.
However, that doesn't mean that Automatic Modules can't access it, they can:

From the Original Jigsaw Spec, https://openjdk.java.net/projects/jigsaw/spec/sotms/#automatic-modules :

The unnamed module exports all of its packages. This enables flexible migration, as we shall see below. 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. This restriction is intentional, since allowing named modules to depend upon the arbitrary content of the class path would make reliable configuration impossible.

If a package is defined in both a named module and the unnamed module then the package in the unnamed module is ignored



and from the more readable if perhaps less authoritative Jenkov tutorial:

http://tutorials.jenkov.com/java/modules.html#unnamed-module

The unnamed module exports all its packages. However, the classes in the unnamed module are only readable by other classes in the unnamed module - or from automatic modules (see next section). No named module can read the classes of the unnamed module.

If a package is exported by a named module, but also found in the unnamed module, the package from the named module will be used.

All classes in the unnamed module requires all modules found on the module path. That way, all classes in the unnamed module can read all classes exported by all the Java modules found on the module path.



Now to be honest, I didn't mean to Jump Down This Rabbit-Hole.  I had glancing, half-remembered casual exposure to the JPMS from some videos I casually watched or tutorials I glanced at.

It was the fact that the summary table did not seem to correspond to what I remembered that had me pay so much attention to the topic.

As a big part of the point of this chapter is as an introduction to migration strategies for going from non-modular code bases to modular ones, I consider the confusion about the meaning of the entries in the table in these respects to be serious enough be worth addressing.  It will be a great day when nobody needs Automatic Modules anymore because we are in a fully-modular universe, but until then they are pretty important, and some of the most important magic they do to bridge our gap between the two worlds is obscured by the current presentation of this table.

I fully appreciate how tricky it is to present a topic like this, i.e. a topic that most decidedly deserves a whole book to itself (and in fact has two or three very good ones!) but only has limited coverage on the OCJP exam that this text is preparing us for.  So I am not snarking or complaining.  However, I think the stuff I highlighted is rather key to the spirit of Chapter 6's "Overview of Migration Strategies Minus Too Many Nasty Details", and would hope the table gets re-worked.
 
Jesse Silverman
Saloon Keeper
Posts: 1338
40
Eclipse IDE Postgres Database C++ Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Another errata for the same chapter, section Splitting a Big Project Into Modules, figure 6.9 does not correlate to the textual description of it:

Scott and Jeanne wrote:Figure 6.9 shows the new modules without any cyclic dependencies.  Notice the new module zoo.tickets.discount.  We created a new package to put in that module.  This allows the developers to put common code in there and break the dependency.  No more cyclic dependencies!


Minor extra for the errata or re-write, there are two new packages added in the new module that was added in the figure and mentioned in the errata:
zoo.tickets.etech

rather than one.

I don't know how I missed the errata, normally I go thru and mark the book up according to the latest posted errata, I must have done that too early in the cycle and missed this one (and some others I am marking the book up with now)...


 
author & internet detective
Posts: 40747
827
Eclipse IDE VI Editor Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Jesse Silverman wrote:Another errata for the same chapter, section Splitting a Big Project Into Modules, figure 6.9 does not correlate to the textual description of it:

Scott and Jeanne wrote:Figure 6.9 shows the new modules without any cyclic dependencies.  Notice the new module zoo.tickets.discount.  We created a new package to put in that module.  This allows the developers to put common code in there and break the dependency.  No more cyclic dependencies!


Minor extra for the errata or re-write, there are two new packages added in the new module that was added in the figure and mentioned in the errata:
zoo.tickets.etech

rather than one.


I agree there are two packages. Good catch.
 
Jeanne Boyarsky
author & internet detective
Posts: 40747
827
Eclipse IDE VI Editor Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
For the rest of this thread, there's an aspect that we need to present a simplified view of the world. This chapter is for the purpose of passing the exam, not going into every last detail of modules.
 
Jesse Silverman
Saloon Keeper
Posts: 1338
40
Eclipse IDE Postgres Database C++ Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I can deal with that, tho I am happier when stuff just gets omitted/left unsaid rather than table entries being present that are arguably incorrect (I find unlearning things difficult when I move ahead later)...

Here's an easy one.

In Figure 6-10 the package name of the Service Locator package in the Service is written:
zoo.tours.reservation

As it appears multiple times in the code samples and descriptive text as:
zoo.tours.reservations

It would probably be best to change the figure to concur with that usage.


 
Jesse Silverman
Saloon Keeper
Posts: 1338
40
Eclipse IDE Postgres Database C++ Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Finally (at least final before I do the review questions!)
In the last section before the summary, we are titled Merging Service Locator and Consumer

But the section goes on to not only merge the Service Locator and the Consumer, but also bundles in an implementation as well, all in one Big Fat Happy module zoo.tours.hybrid.
The resulting module-info.java file of course reflects this, as does the discussion, but we could have merged only the Service Locator and the Consumer, which is what the section title led me to expect was going to happen.

A short sentence at the beginning that said something like "We will often merge the Service Locator with the Consumer.  In this example, we will show you additionally merging another Service Provider as well, so you can see everything together in this one example." would have removed my confusion about what gets shown versus what the title led me to expect to see.

I think I see what you were going for now, because only the Service Locator and the Consumer wind up in the same class, and the new implementation is in its own class (of course) but in the same new package of the same new module.

Also in this section, on page 336, we again refer to the Service Locator (a concept) as ServiceLocator, which makes it appear to be an actual class or interface name, which it is not, that would be ServiceLoader, as someone pointed out earlier in this chapter and is already in the errata for page 330.

On to the Chapter Review Questions!!


 
Jesse Silverman
Saloon Keeper
Posts: 1338
40
Eclipse IDE Postgres Database C++ Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
This one is for Stephan's "Multiple Choice Questions Suck!!" file.

Yes, I got this wrong, yes, I went back and forth and decided there was no obviously right answer so there I was trying to guess which they wanted to see, I guessed wrongly (corrections already applied from errata to fix D. E. F. answer choices):

Question 14 tb617624.JaSE11PrgIISG.c06.14
Suppose you have a project with one package named magic.wand and another project with one package named magic.potion. These projects have a circular dependency, so you decide to create a third project named magic.helper. The magic.helper module has the common code containing a package named magic.util. For simplicity, let’s give each module the same name as the package. Which of the following need to appear in your module-info files? (Choose all that apply.)
A. exports magic.potion; in the potion project
B. exports magic.util; in the magic helper project
C. exports magic.wand; in the wand project
D. requires magic.helper; in the magic helper project
E. requires magic.helper; in the potion project
F. requires magic.helper; in the wand project
You Answered Incorrectly.
Since the new project extracts the common code, it must have an exports directive for that code, making option B correct. The other two modules do not have to expose anything. They must have a requires directive to be able to use the exported code, making options E and F correct.



Here is my problem.  Duh, I got B right, and E, and F.  Those parts just test your knowledge of the subject.
I note that B and D should say magic.helper as the name of the project but that ain't my problem.

Clearly, when we had the circular dependency, both magic.wand and magic.potion must necessarily have been exported.
Otherwise, we would have failed with some other error, not circular dependency!
So we KNOW that they were both exported before, and are not told that they were qualified exports, let's presume they weren't.
Okay, what else in the world could have depended on them by just saying requires?

Well, literally any named module, for sure, and automatic modules as well, right?

So now that we are getting rid of the circular dependency, do we retain those exports which we know were there because it seems likely someone else was also using them or remove them because they were only there in a futile attempt to achieve an invalid circular dependency?

I chose the former, knowing I was only guessing between these two options.

The question is very legitimate, you need to know how to resolve accidental circular dependencies.

But knowing whether or not we should say that the original exports need to remain or not seems deep into "trick question" territory, it also feels like the kind of thing you would put on if you were marking everyone wrong as a joke, because you could easily argue either one was wrong.  Well, I could, but I am good at arguing.

Onwards!
 
Jesse Silverman
Saloon Keeper
Posts: 1338
40
Eclipse IDE Postgres Database C++ Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I got question 7 from this chapter right, but disagree with the explanation.

F. An unnamed module can be involved in a cyclic dependency with an automatic module <-- this is false, but not for the stated reason

Finally. Option F is incorrect because unnamed modules cannot be referenced from an automatic module.



There is only one unnamed module, much like there is only one unnamed package, but that is secondary.

The unnamed module most decidedly can be referenced from an automatic module.

Doing so may be out-of-scope for the 819 (I'm not really sure) but it definitely can be.

I am okay with omitting statements or material that is not in scope, but saying automatic modules can't call code found on the classpath is just untrue in JPMS.  Let's not say that.
 
Jesse Silverman
Saloon Keeper
Posts: 1338
40
Eclipse IDE Postgres Database C++ Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Question 19's answer persists in saying more than is required to answer the question, and accidentally lying in the process:


An unnamed module is not available to any modules on the module path. Therefore, it doesn’t export any packages, and option F is correct.



But the unnamed module is available to all automatic modules on the module path.  In fact, it exports ALL packages to all of them.

F is still the correct choice, because it exports them only to unnamed modules, not to named ones, but still...
 
Willie Smits increased rainfall 25% in three years by planting trees. Tiny ad:
Thread Boost feature
https://coderanch.com/t/674455/Thread-Boost-feature
reply
    Bookmark Topic Watch Topic
  • New Topic