[MJAVADOC-567] "Not in a module on the module source path" when using JDK 12
diff --git a/src/it/projects/MJAVADOC-567_aggr-mixed/invoker.properties b/src/it/projects/MJAVADOC-567_aggr-mixed/invoker.properties
new file mode 100644
index 0000000..ad0c0ee
--- /dev/null
+++ b/src/it/projects/MJAVADOC-567_aggr-mixed/invoker.properties
@@ -0,0 +1,19 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+# 
+#   http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+invoker.buildResult = failure
+invoker.java.version = 9+
+invoker.goals = javadoc:aggregate
\ No newline at end of file
diff --git a/src/it/projects/MJAVADOC-567_aggr-mixed/module1/pom.xml b/src/it/projects/MJAVADOC-567_aggr-mixed/module1/pom.xml
new file mode 100644
index 0000000..288012b
--- /dev/null
+++ b/src/it/projects/MJAVADOC-567_aggr-mixed/module1/pom.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied.  See the License for the
+  specific language governing permissions and limitations
+  under the License.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+	<parent>
+		<artifactId>javadoc-maven-report-exception</artifactId>
+		<groupId>testcase</groupId>
+		<version>1.0-SNAPSHOT</version>
+	</parent>
+	<artifactId>module1</artifactId>
+</project>
\ No newline at end of file
diff --git a/src/it/projects/MJAVADOC-567_aggr-mixed/module1/src/main/java/module-info.java b/src/it/projects/MJAVADOC-567_aggr-mixed/module1/src/main/java/module-info.java
new file mode 100644
index 0000000..0dd7ad2
--- /dev/null
+++ b/src/it/projects/MJAVADOC-567_aggr-mixed/module1/src/main/java/module-info.java
@@ -0,0 +1,23 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+module module1
+{
+	exports module1;
+}
\ No newline at end of file
diff --git a/src/it/projects/MJAVADOC-567_aggr-mixed/module1/src/main/java/module1/Main.java b/src/it/projects/MJAVADOC-567_aggr-mixed/module1/src/main/java/module1/Main.java
new file mode 100644
index 0000000..e60dbdb
--- /dev/null
+++ b/src/it/projects/MJAVADOC-567_aggr-mixed/module1/src/main/java/module1/Main.java
@@ -0,0 +1,24 @@
+package module1;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+public final class Main
+{
+}
diff --git a/src/it/projects/MJAVADOC-567_aggr-mixed/module2/pom.xml b/src/it/projects/MJAVADOC-567_aggr-mixed/module2/pom.xml
new file mode 100644
index 0000000..6545dbc
--- /dev/null
+++ b/src/it/projects/MJAVADOC-567_aggr-mixed/module2/pom.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied.  See the License for the
+  specific language governing permissions and limitations
+  under the License.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <artifactId>javadoc-maven-report-exception</artifactId>
+    <groupId>testcase</groupId>
+    <version>1.0-SNAPSHOT</version>
+  </parent>
+  <artifactId>module2</artifactId>
+
+</project>
\ No newline at end of file
diff --git a/src/it/projects/MJAVADOC-567_aggr-mixed/module2/src/main/java/module2/Main.java b/src/it/projects/MJAVADOC-567_aggr-mixed/module2/src/main/java/module2/Main.java
new file mode 100644
index 0000000..b864f0e
--- /dev/null
+++ b/src/it/projects/MJAVADOC-567_aggr-mixed/module2/src/main/java/module2/Main.java
@@ -0,0 +1,24 @@
+package module2;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+public final class Main
+{
+}
diff --git a/src/it/projects/MJAVADOC-567_aggr-mixed/pom.xml b/src/it/projects/MJAVADOC-567_aggr-mixed/pom.xml
new file mode 100644
index 0000000..9b4797b
--- /dev/null
+++ b/src/it/projects/MJAVADOC-567_aggr-mixed/pom.xml
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied.  See the License for the
+  specific language governing permissions and limitations
+  under the License.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <artifactId>javadoc-maven-report-exception</artifactId>
+  <groupId>testcase</groupId>
+  <version>1.0-SNAPSHOT</version>
+  <packaging>pom</packaging>
+  
+  <url>https://issues.apache.org/jira/browse/MJAVADOC-567</url>
+
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+  </properties>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <version>3.8.0</version>
+        <configuration>
+          <release>9</release>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-javadoc-plugin</artifactId>
+        <version>@project.version@</version>
+        <executions>
+          <execution>
+            <id>aggregate</id>
+            <goals>
+              <goal>aggregate</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+
+  <modules>
+    <module>module1</module>
+    <module>module2</module>
+  </modules>
+
+</project>
\ No newline at end of file
diff --git a/src/it/projects/MJAVADOC-567_aggr-mixed/verify.groovy b/src/it/projects/MJAVADOC-567_aggr-mixed/verify.groovy
new file mode 100644
index 0000000..2627dc1
--- /dev/null
+++ b/src/it/projects/MJAVADOC-567_aggr-mixed/verify.groovy
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+ 
+def buildLog = new File(basedir,'build.log')
+
+def expectedLines = ['Creating an aggregated report for both named and unnamed modules is not possible.',
+                     'Ensure that every module has a module descriptor or is a jar with a MANIFEST.MF containing an Automatic-Module-Name.',
+                     'Fix the following projects:',
+                     ' - testcase:module2']
+
+def errorLines = buildLog.readLines() 
+                         .dropWhile{ !it.startsWith('[ERROR]') }
+                         .takeWhile{ it.startsWith('[ERROR]') }
+                         .collect  { it - '[ERROR] '}
+                         
+assert expectedLines == errorLines                   
diff --git a/src/main/java/org/apache/maven/plugins/javadoc/AbstractJavadocMojo.java b/src/main/java/org/apache/maven/plugins/javadoc/AbstractJavadocMojo.java
index 17588d0..b7f7308 100644
--- a/src/main/java/org/apache/maven/plugins/javadoc/AbstractJavadocMojo.java
+++ b/src/main/java/org/apache/maven/plugins/javadoc/AbstractJavadocMojo.java
@@ -2234,32 +2234,35 @@
 

         if ( StringUtils.isEmpty( sourcepath ) )

         {

-            

-            Set<Path> sourcePaths =

-                new LinkedHashSet<>( JavadocUtil.pruneDirs( project, getProjectSourceRoots( project ) ) );

-

-            if ( project.getExecutionProject() != null )

+            if ( !"pom".equals( project.getPackaging()  ) )

             {

-                sourcePaths.addAll( JavadocUtil.pruneDirs( project, getExecutionProjectSourceRoots( project ) ) );

-            }

+                Set<Path> sourcePaths =

+                    new LinkedHashSet<>( JavadocUtil.pruneDirs( project, getProjectSourceRoots( project ) ) );

 

-            /*

-             * Should be after the source path (i.e. -sourcepath '.../src/main/java;.../src/main/javadoc') and

-             * *not* the opposite. If not, the javadoc tool always copies doc files, even if -docfilessubdirs is

-             * not setted.

-             */

-            if ( getJavadocDirectory() != null )

-            {

-                File javadocDir = getJavadocDirectory();

-                if ( javadocDir.exists() && javadocDir.isDirectory() )

+                if ( project.getExecutionProject() != null )

                 {

-                    Collection<Path> l = JavadocUtil.pruneDirs( project, Collections.singletonList(

-                        getJavadocDirectory().getAbsolutePath() ) );

-                    sourcePaths.addAll( l );

+                    sourcePaths.addAll( JavadocUtil.pruneDirs( project, getExecutionProjectSourceRoots( project ) ) );

                 }

+

+                /*

+                 * Should be after the source path (i.e. -sourcepath '.../src/main/java;.../src/main/javadoc') and *not*

+                 * the opposite. If not, the javadoc tool always copies doc files, even if -docfilessubdirs is not

+                 * setted.

+                 */

+                if ( getJavadocDirectory() != null )

+                {

+                    File javadocDir = getJavadocDirectory();

+                    if ( javadocDir.exists() && javadocDir.isDirectory() )

+                    {

+                        Collection<Path> l =

+                            JavadocUtil.pruneDirs( project,

+                                               Collections.singletonList( getJavadocDirectory().getAbsolutePath() ) );

+                        sourcePaths.addAll( l );

+                    }

+                }

+                mappedSourcePaths.put( ArtifactUtils.versionlessKey( project.getGroupId(), project.getArtifactId() ),

+                                       sourcePaths );               

             }

-            mappedSourcePaths.put( ArtifactUtils.versionlessKey( project.getGroupId(), project.getArtifactId() ),

-                                   sourcePaths );

             

             if ( includeDependencySources )

             {

@@ -2356,7 +2359,7 @@
             return Collections.singleton( aggregatedProject );

         }

 

-        List<Path> modulePaths = new LinkedList<Path>();

+        List<Path> modulePaths = new LinkedList<>();

         for ( String module :  aggregatedProject.getModules() )

         {

             modulePaths.add( new File( aggregatedProject.getBasedir(), module ).toPath() );

@@ -4875,13 +4878,14 @@
             if ( findMainDescriptor( sourcepaths ) != null )

             {

                 containsModuleDescriptor = true;

+                break;

             }

         }

         

-        

         Path moduleSourceDir = null;

         if ( containsModuleDescriptor && allSourcePaths.size() > 1 )

         {

+            Collection<String> unnamedProjects = new ArrayList<>();

             for ( Map.Entry<String, Collection<Path>> projectSourcepaths : allSourcePaths.entrySet() )

             {

                 MavenProject aggregatorProject = reactorKeys.get( projectSourcepaths.getKey() );

@@ -4932,6 +4936,7 @@
                             }

                         }

                     }

+

                     if ( moduleName != null )

                     {

                         moduleSourceDir = javadocOutputDirectory.toPath().resolve( "src" );

@@ -4957,17 +4962,28 @@
                     }

                     else

                     {

-                        // todo

-                        getLog().error( "no module descriptor for " + projectSourcepaths.getKey() );

+                        unnamedProjects.add( projectSourcepaths.getKey() );

                     }

                 }

                 else

                 {

                     // todo

                     getLog().error( "no reactor project: " + projectSourcepaths.getKey() );

-

                 }

             }

+            

+            if ( !unnamedProjects.isEmpty() )

+            {

+                getLog().error( "Creating an aggregated report for both named and unnamed modules is not possible." );

+                getLog().error( "Ensure that every module has a module descriptor or is a jar with a MANIFEST.MF "

+                    + "containing an Automatic-Module-Name." );

+                getLog().error( "Fix the following projects:" );

+                for ( String unnamedProject : unnamedProjects )

+                {

+                    getLog().error( " - " + unnamedProject );

+                }

+                throw new MavenReportException( "Aggregator report contains named and unnamed modules" );

+            }

         }

 

         Collection<Path> roots = new ArrayList<>();

diff --git a/src/site/apt/examples/aggregate.apt.vm b/src/site/apt/examples/aggregate.apt.vm
index c10e094..0a8b8a4 100644
--- a/src/site/apt/examples/aggregate.apt.vm
+++ b/src/site/apt/examples/aggregate.apt.vm
@@ -48,14 +48,7 @@
 
 +-----+
 
-* Using The \<aggregate/\> Parameter (<<deprecated>>)
-
- <<Note>>: {{{../javadoc-mojo.html#aggregate}\<aggregate/\>}} parameter is <<deprecated>> since 2.5. Please use the
- <<<aggregate>>> goal instead of.
-
- The {{{../javadoc-mojo.html#aggregate}\<aggregate/\>}} parameter can be used to generate javadocs for multi-module
- projects. It gives the option to generate one javadoc report for the entire project (all modules) or generate one 
- javadoc report for each module. Since 3.1.0 the <<<aggregate>>> has changed a little bit. It'll generate aggregated 
+ Since 3.1.0 the <<<aggregate>>> has changed a little bit. It'll generate aggregated 
  reports at every level.
  To get only an aggregated project at root level, you need to configure the pom like:
  
@@ -91,34 +84,6 @@
 </project>
 +-----+
 
- When you execute javadoc:javadoc from Project directory with aggregate set to <<true>>, a javadoc report will be created
- in the target directory of Project with all the javadocs of Project's modules included. If aggregate is
- set to <<false>> (default), a javadoc report for Module1 will be generated in the target directory of Module1, a javadoc
- report for Module2 will be generated in the target directory of Module2, and a javadoc report for Module3 will be
- generated in the target directory of Module3.
-
-+-----+
-<project>
-  ...
-  <reporting> (or <build>)
-    <plugins>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-javadoc-plugin</artifactId>
-        <version>${project.version}</version>
-        <configuration>
-          ...
-          <aggregate>true</aggregate>
-          ...
-        </configuration>
-      </plugin>
-    </plugins>
-    ...
-  </reporting> (or </build>)
-  ...
-</project>
-+-----+
-
 * Using The <<<aggregate>>> Goals
 
  The {{{../javadoc-mojo.html#aggregate}\<aggregate/\>}} parameter doesn't include generate source directories defined
@@ -207,6 +172,28 @@
 </project>
 +-----+
 
+* Aggregating Javadocs For Modularized projects
+
+  Since Java 9 it is possible to add module descriptors to your projects, which can have an impact on the generated reports.
+  Be aware that is not possible to have a mixture of named and unnamed modules. Ideally every Maven module has a Java module descriptor,
+  but this is not always possible, e.g. due to split packages of dependencies.
+  In such case you must have a jar containing a <<<META-INF/MANIFEST.MF>>> with an entry for the <<<Automatic-Module-Name>>>.
+  In other words: ensure to call <<<package javadoc:aggregate>>>, because the manifest file is only being read from jar, not from folder.
+  
++-----+
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-jar-plugin</artifactId>
+          <configuration>
+            <archive>
+              <manifestEntries>
+                <Automatic-Module-Name>com.foo.bar</Automatic-Module-Name>
+              </manifestEntries>
+            </archive>
+          </configuration>
+        </plugin>  
++-----+
+
  The Javadoc plugin contains several <<<aggregate>>> goals to be use with an aggregator project. Here is the full list
  of all <<<aggregate>>> goals: