[Git][java-team/bcel][upstream] New upstream version 6.3

Emmanuel Bourg gitlab at salsa.debian.org
Fri Jul 19 12:43:23 BST 2019



Emmanuel Bourg pushed to branch upstream at Debian Java Maintainers / bcel


Commits:
de1bac86 by Emmanuel Bourg at 2019-07-19T11:34:11Z
New upstream version 6.3
- - - - -


26 changed files:

- .travis.yml
- CONTRIBUTING.md
- NOTICE.txt
- README.md
- RELEASE-NOTES.txt
- pom.xml
- src/changes/changes.xml
- src/main/java/org/apache/bcel/Const.java
- src/main/java/org/apache/bcel/classfile/Constant.java
- src/main/java/org/apache/bcel/classfile/ConstantClass.java
- + src/main/java/org/apache/bcel/classfile/ConstantDynamic.java
- src/main/java/org/apache/bcel/classfile/DescendingVisitor.java
- src/main/java/org/apache/bcel/classfile/EmptyVisitor.java
- src/main/java/org/apache/bcel/classfile/Visitor.java
- src/main/java/org/apache/bcel/util/ClassPath.java
- + src/main/java/org/apache/bcel/util/ModularRuntimeImage.java
- src/main/java/org/apache/bcel/util/Repository.java
- src/site/resources/bcel5-bcel6-clirr-report.html
- src/site/xdoc/download_bcel.xml
- src/site/xdoc/index.xml
- src/site/xdoc/issue-tracking.xml
- src/site/xdoc/mail-lists.xml
- src/test/java/org/apache/bcel/generic/JDKGenericDumpTestCase.java → src/test/java/org/apache/bcel/generic/JdkGenericDumpTestCase.java
- + src/test/java/org/apache/bcel/util/ClassPathTestCase.java
- + src/test/java/org/apache/bcel/util/ModularRuntimeImageTestCase.java
- src/test/java/org/apache/bcel/visitors/CounterVisitor.java


Changes:

=====================================
.travis.yml
=====================================
@@ -17,8 +17,7 @@ language: java
 sudo: false
 
 jdk:
-  - openjdk7
   - oraclejdk8
 
 after_success:
-  - mvn clean cobertura:cobertura coveralls:report
+  - mvn -Ddoclint:none clean cobertura:cobertura coveralls:report


=====================================
CONTRIBUTING.md
=====================================
@@ -1,115 +1,115 @@
-<!---
- 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.
--->
-<!---
- +======================================================================+
- |****                                                              ****|
- |****      THIS FILE IS GENERATED BY THE COMMONS BUILD PLUGIN      ****|
- |****                    DO NOT EDIT DIRECTLY                      ****|
- |****                                                              ****|
- +======================================================================+
- | TEMPLATE FILE: contributing-md-template.md                           |
- | commons-build-plugin/trunk/src/main/resources/commons-xdoc-templates |
- +======================================================================+
- |                                                                      |
- | 1) Re-generate using: mvn commons:contributing-md                    |
- |                                                                      |
- | 2) Set the following properties in the component's pom:              |
- |    - commons.jira.id  (required, alphabetic, upper case)             |
- |                                                                      |
- | 3) Example Properties                                                |
- |                                                                      |
- |  <properties>                                                        |
- |    <commons.jira.id>MATH</commons.jira.id>                           |
- |  </properties>                                                       |
- |                                                                      |
- +======================================================================+
---->
-Contributing to Apache Commons BCEL
-======================
-
-You have found a bug or you have an idea for a cool new feature? Contributing code is a great way to give something back to
-the open source community. Before you dig right into the code there are a few guidelines that we need contributors to
-follow so that we can have a chance of keeping on top of things.
-
-Getting Started
----------------
-
-+ Make sure you have a [JIRA account](https://issues.apache.org/jira/).
-+ Make sure you have a [GitHub account](https://github.com/signup/free).
-+ If you're planning to implement a new feature it makes sense to discuss you're changes on the [dev list](https://commons.apache.org/mail-lists.html) first. This way you can make sure you're not wasting your time on something that isn't considered to be in Apache Commons BCEL's scope.
-+ Submit a [Jira Ticket][jira] for your issue, assuming one does not already exist.
-  + Clearly describe the issue including steps to reproduce when it is a bug.
-  + Make sure you fill in the earliest version that you know has the issue.
-+ Find the corresponding [repository on GitHub](https://github.com/apache/?query=commons-),
-[fork](https://help.github.com/articles/fork-a-repo/) and check out your forked repository.
-
-Making Changes
---------------
-
-+ Create a _topic branch_ for your isolated work.
-  * Usually you should base your branch on the `master` or `trunk` branch.
-  * A good topic branch name can be the JIRA bug id plus a keyword, e.g. `BCEL-123-InputStream`.
-  * If you have submitted multiple JIRA issues, try to maintain separate branches and pull requests.
-+ Make commits of logical units.
-  * Make sure your commit messages are meaningful and in the proper format. Your commit message should contain the key of the JIRA issue.
-  * e.g. `BCEL-123: Close input stream earlier`
-+ Respect the original code style:
-  + Only use spaces for indentation.
-  + Create minimal diffs - disable _On Save_ actions like _Reformat Source Code_ or _Organize Imports_. If you feel the source code should be reformatted create a separate PR for this change first.
-  + Check for unnecessary whitespace with `git diff` -- check before committing.
-+ Make sure you have added the necessary tests for your changes, typically in `src/test/java`.
-+ Run all the tests with `mvn clean verify` to assure nothing else was accidentally broken.
-
-Making Trivial Changes
-----------------------
-
-The JIRA tickets are used to generate the changelog for the next release.
-
-For changes of a trivial nature to comments and documentation, it is not always necessary to create a new ticket in JIRA.
-In this case, it is appropriate to start the first line of a commit with '(doc)' instead of a ticket number.
-
-
-Submitting Changes
-------------------
-
-+ Sign and submit the Apache [Contributor License Agreement][cla] if you haven't already.
-  * Note that small patches & typical bug fixes do not require a CLA as
-    clause 5 of the [Apache License](https://www.apache.org/licenses/LICENSE-2.0.html#contributions)
-    covers them.
-+ Push your changes to a topic branch in your fork of the repository.
-+ Submit a _Pull Request_ to the corresponding repository in the `apache` organization.
-  * Verify _Files Changed_ shows only your intended changes and does not
-  include additional files like `target/*.class`
-+ Update your JIRA ticket and include a link to the pull request in the ticket.
-
-If you prefer to not use GitHub, then you can instead use
-`git format-patch` (or `svn diff`) and attach the patch file to the JIRA issue.
-
-
-Additional Resources
---------------------
-
-+ [Contributing patches](https://commons.apache.org/patches.html)
-+ [Apache Commons BCEL JIRA project page][jira]
-+ [Contributor License Agreement][cla]
-+ [General GitHub documentation](https://help.github.com/)
-+ [GitHub pull request documentation](https://help.github.com/send-pull-requests/)
-+ [Apache Commons Twitter Account](https://twitter.com/ApacheCommons)
-+ `#apache-commons` IRC channel on `irc.freenode.net`
-
-[cla]:https://www.apache.org/licenses/#clas
-[jira]:https://issues.apache.org/jira/browse/BCEL
+<!---
+ 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.
+-->
+<!---
+ +======================================================================+
+ |****                                                              ****|
+ |****      THIS FILE IS GENERATED BY THE COMMONS BUILD PLUGIN      ****|
+ |****                    DO NOT EDIT DIRECTLY                      ****|
+ |****                                                              ****|
+ +======================================================================+
+ | TEMPLATE FILE: contributing-md-template.md                           |
+ | commons-build-plugin/trunk/src/main/resources/commons-xdoc-templates |
+ +======================================================================+
+ |                                                                      |
+ | 1) Re-generate using: mvn commons-build:contributing-md              |
+ |                                                                      |
+ | 2) Set the following properties in the component's pom:              |
+ |    - commons.jira.id  (required, alphabetic, upper case)             |
+ |                                                                      |
+ | 3) Example Properties                                                |
+ |                                                                      |
+ |  <properties>                                                        |
+ |    <commons.jira.id>MATH</commons.jira.id>                           |
+ |  </properties>                                                       |
+ |                                                                      |
+ +======================================================================+
+--->
+Contributing to Apache Commons BCEL
+======================
+
+You have found a bug or you have an idea for a cool new feature? Contributing code is a great way to give something back to
+the open source community. Before you dig right into the code there are a few guidelines that we need contributors to
+follow so that we can have a chance of keeping on top of things.
+
+Getting Started
+---------------
+
++ Make sure you have a [JIRA account](https://issues.apache.org/jira/).
++ Make sure you have a [GitHub account](https://github.com/signup/free).
++ If you're planning to implement a new feature it makes sense to discuss your changes on the [dev list](https://commons.apache.org/mail-lists.html) first. This way you can make sure you're not wasting your time on something that isn't considered to be in Apache Commons BCEL's scope.
++ Submit a [Jira Ticket][jira] for your issue, assuming one does not already exist.
+  + Clearly describe the issue including steps to reproduce when it is a bug.
+  + Make sure you fill in the earliest version that you know has the issue.
++ Find the corresponding [repository on GitHub](https://github.com/apache/?query=commons-),
+[fork](https://help.github.com/articles/fork-a-repo/) and check out your forked repository.
+
+Making Changes
+--------------
+
++ Create a _topic branch_ for your isolated work.
+  * Usually you should base your branch on the `master` or `trunk` branch.
+  * A good topic branch name can be the JIRA bug id plus a keyword, e.g. `BCEL-123-InputStream`.
+  * If you have submitted multiple JIRA issues, try to maintain separate branches and pull requests.
++ Make commits of logical units.
+  * Make sure your commit messages are meaningful and in the proper format. Your commit message should contain the key of the JIRA issue.
+  * e.g. `BCEL-123: Close input stream earlier`
++ Respect the original code style:
+  + Only use spaces for indentation.
+  + Create minimal diffs - disable _On Save_ actions like _Reformat Source Code_ or _Organize Imports_. If you feel the source code should be reformatted create a separate PR for this change first.
+  + Check for unnecessary whitespace with `git diff` -- check before committing.
++ Make sure you have added the necessary tests for your changes, typically in `src/test/java`.
++ Run all the tests with `mvn clean verify` to assure nothing else was accidentally broken.
+
+Making Trivial Changes
+----------------------
+
+The JIRA tickets are used to generate the changelog for the next release.
+
+For changes of a trivial nature to comments and documentation, it is not always necessary to create a new ticket in JIRA.
+In this case, it is appropriate to start the first line of a commit with '(doc)' instead of a ticket number.
+
+
+Submitting Changes
+------------------
+
++ Sign and submit the Apache [Contributor License Agreement][cla] if you haven't already.
+  * Note that small patches & typical bug fixes do not require a CLA as
+    clause 5 of the [Apache License](https://www.apache.org/licenses/LICENSE-2.0.html#contributions)
+    covers them.
++ Push your changes to a topic branch in your fork of the repository.
++ Submit a _Pull Request_ to the corresponding repository in the `apache` organization.
+  * Verify _Files Changed_ shows only your intended changes and does not
+  include additional files like `target/*.class`
++ Update your JIRA ticket and include a link to the pull request in the ticket.
+
+If you prefer to not use GitHub, then you can instead use
+`git format-patch` (or `svn diff`) and attach the patch file to the JIRA issue.
+
+
+Additional Resources
+--------------------
+
++ [Contributing patches](https://commons.apache.org/patches.html)
++ [Apache Commons BCEL JIRA project page][jira]
++ [Contributor License Agreement][cla]
++ [General GitHub documentation](https://help.github.com/)
++ [GitHub pull request documentation](https://help.github.com/articles/creating-a-pull-request/)
++ [Apache Commons Twitter Account](https://twitter.com/ApacheCommons)
++ `#apache-commons` IRC channel on `irc.freenode.net`
+
+[cla]:https://www.apache.org/licenses/#clas
+[jira]:https://issues.apache.org/jira/browse/BCEL


=====================================
NOTICE.txt
=====================================
@@ -1,5 +1,5 @@
 Apache Commons BCEL
-Copyright 2004-2017 The Apache Software Foundation
+Copyright 2004-2019 The Apache Software Foundation
 
 This product includes software developed at
 The Apache Software Foundation (http://www.apache.org/).


=====================================
README.md
=====================================
@@ -25,7 +25,7 @@
  | commons-build-plugin/trunk/src/main/resources/commons-xdoc-templates |
  +======================================================================+
  |                                                                      |
- | 1) Re-generate using: mvn commons:readme-md                          |
+ | 1) Re-generate using: mvn commons-build:readme-md                    |
  |                                                                      |
  | 2) Set the following properties in the component's pom:              |
  |    - commons.componentid (required, alphabetic, lower case)          |
@@ -43,10 +43,10 @@
 Apache Commons BCEL
 ===================
 
-[![Build Status](https://travis-ci.org/apache/bcel.svg?branch=master)](https://travis-ci.org/apache/bcel)
-[![Coverage Status](https://coveralls.io/repos/apache/bcel/badge.svg?branch=master)](https://coveralls.io/r/apache/bcel)
+[![Build Status](https://travis-ci.org/apache/commons-bcel.svg)](https://travis-ci.org/apache/commons-bcel)
+[![Coverage Status](https://coveralls.io/repos/apache/commons-bcel/badge.svg)](https://coveralls.io/r/apache/commons-bcel)
 [![Maven Central](https://maven-badges.herokuapp.com/maven-central/org.apache.bcel/bcel/badge.svg)](https://maven-badges.herokuapp.com/maven-central/org.apache.bcel/bcel/)
-[![License](http://img.shields.io/:license-apache-blue.svg)](http://www.apache.org/licenses/LICENSE-2.0.html)
+[![Javadocs](https://javadoc.io/badge/org.apache.bcel/bcel/6.3.svg)](https://javadoc.io/doc/org.apache.bcel/bcel/6.3)
 
 Apache Commons Bytecode Engineering Library
 
@@ -54,7 +54,7 @@ Documentation
 -------------
 
 More information can be found on the [Apache Commons BCEL homepage](https://commons.apache.org/proper/commons-bcel).
-The [JavaDoc](https://commons.apache.org/proper/commons-bcel/javadocs/api-release) can be browsed.
+The [Javadoc](https://commons.apache.org/proper/commons-bcel/javadocs/api-release) can be browsed.
 Questions related to the usage of Apache Commons BCEL should be posted to the [user mailing list][ml].
 
 Where can I get the latest release?
@@ -67,7 +67,7 @@ Alternatively you can pull it from the central Maven repositories:
 <dependency>
   <groupId>org.apache.bcel</groupId>
   <artifactId>bcel</artifactId>
-  <version>6.2</version>
+  <version>6.3</version>
 </dependency>
 ```
 


=====================================
RELEASE-NOTES.txt
=====================================
@@ -1,3 +1,62 @@
+              Apache Commons BCEL
+                  Version 6.3-SNAPSHOT
+                RELEASE NOTES
+
+
+INTRODUCTION:
+
+The Apache Commons BCEL team is pleased to announce the release of
+Apache Commons BCEL 6.3-SNAPSHOT!
+
+The Byte Code Engineering Library (BCEL) is intended to give users a convenient
+way to analyze, create, and manipulate compiled .class files. Classes are
+represented by objects containing all the symbolic information of the given
+class: methods, fields and byte code instructions.
+
+?
+
+NEW FEATURES:
+=============
+
+o           Added org.apache.bcel.classfile.Visitor.visitConstantDynamic(ConstantDynamic) Thanks to Mark Thomas.
+o           Added org.apache.bcel.classfile.ConstantDynamic Thanks to Mark Thomas.
+o           Added fields in org.apache.bcel.Const for Java 9, 10, and 11. Thanks to Mark Thomas.
+o           Added fields in org.apache.bcel.Const for Java 12 and 13 based on Java Early Access releases. Thanks to Mark Thomas.
+
+FIXED BUGS:
+===========
+
+o BCEL-304: ClassPath.getClassFile() and friends do not work with JDK 9 and higher (PR #22.) Thanks to Gary Gregory, Ed Pavlak.
+o BCEL-305: ClassPath.getClassFile() and friends do not work with JRE 9 and higher Thanks to Gary Gregory.
+
+CHANGES:
+========
+
+o           Initial support for Java 11 Thanks to Mark Thomas, Gary Gregory.
+o           Update Java requirement from Java 7 to Java 8. Thanks to Gary Gregory.
+
+
+
+Have fun!
+-Apache Commons BCEL team
+
+Feedback
+--------
+
+Open source works best when you give feedback:
+
+    http://commons.apache.org/bcel
+
+Please direct all bug reports to JIRA:
+
+    https://issues.apache.org/jira/browse/BCEL
+
+Or subscribe to the commons-user mailing list
+
+The Apache Commons Team
+
+-----------------------------------------------------------------------------
+
               Apache Commons BCEL
                   Version 6.2
                 RELEASE NOTES


=====================================
pom.xml
=====================================
@@ -27,13 +27,13 @@
   <parent>
     <groupId>org.apache.commons</groupId>
     <artifactId>commons-parent</artifactId>
-    <version>42</version>
+    <version>47</version>
   </parent>
 
   <groupId>org.apache.bcel</groupId>
   <artifactId>bcel</artifactId>
   <packaging>jar</packaging>
-  <version>6.2</version>
+  <version>6.3</version>
   <name>Apache Commons BCEL</name>
   <description>Apache Commons Bytecode Engineering Library</description>
 
@@ -43,13 +43,19 @@
   <properties>
     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
     <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
-    <maven.compiler.source>1.7</maven.compiler.source>
-    <maven.compiler.target>1.7</maven.compiler.target>
+    <maven.compiler.source>1.8</maven.compiler.source>
+    <maven.compiler.target>1.8</maven.compiler.target>
     <commons.componentid>bcel</commons.componentid>
     <commons.module.name>org.apache.bcel</commons.module.name>
-    <commons.release.version>6.2</commons.release.version>
-    <commons.release.desc>(Java 7+)</commons.release.desc>
+    <commons.release.version>6.3</commons.release.version>
+    <commons.release.isDistModule>true</commons.release.isDistModule>
+    <commons.rc.version>RC1</commons.rc.version>
+    <commons.bc.version>6.2</commons.bc.version>
+    <commons.release.desc>(Java 8)</commons.release.desc>
     <commons.scmPubUrl>https://svn.apache.org/repos/infra/websites/production/commons/content/proper/commons-bcel</commons.scmPubUrl>
+    <commons.distSvnStagingUrl>scm:svn:https://dist.apache.org/repos/dist/dev/commons/${commons.componentid}</commons.distSvnStagingUrl>
+    <commons.releaseManagerName>Gary Gregory</commons.releaseManagerName>    
+    <commons.releaseManagerKey>86fdc7e2a11262cb</commons.releaseManagerKey>
     <!-- Configuration properties for the OSGi maven-bundle-plugin -->
     <commons.osgi.symbolicName>org.apache.${commons.componentid}</commons.osgi.symbolicName>
     <commons.osgi.export>org.apache.bcel.*;version=${project.version};-noimport:=true</commons.osgi.export>
@@ -59,6 +65,7 @@
     <commons.jira.id>BCEL</commons.jira.id>
     <commons.jira.pid>12314220</commons.jira.pid>
     <commons.findbugs.version>3.0.5</commons.findbugs.version>
+    <commons.surefire.version>3.0.0-M3</commons.surefire.version>
     <checkstyle.plugin.version>2.17</checkstyle.plugin.version>
     <commons.clirr.version>2.8</commons.clirr.version>
     <jna.version>4.5.0</jna.version>
@@ -442,7 +449,7 @@
     <dependency>
       <groupId>org.apache.commons</groupId>
       <artifactId>commons-lang3</artifactId>
-      <version>3.7</version>
+      <version>3.8.1</version>
       <scope>test</scope>
     </dependency>
   </dependencies>
@@ -518,7 +525,7 @@
         <dependency>
           <groupId>org.apache.commons</groupId>
           <artifactId>commons-collections4</artifactId>
-          <version>4.1</version>
+          <version>4.2</version>
           <scope>test</scope>
         </dependency>
       </dependencies>
@@ -568,16 +575,7 @@
         </plugins>
       </build>
     </profile>
-
-    <profile>
-      <id>jdk8-javadoc</id>
-      <activation>
-        <jdk>[1.8,)</jdk>
-      </activation>
-      <properties>
-        <additionalparam>-Xdoclint:none</additionalparam>
-      </properties>
-    </profile>
+    
   </profiles>
 
 </project>


=====================================
src/changes/changes.xml
=====================================
@@ -62,7 +62,18 @@ The <action> type attribute can be add,update,fix,remove.
    -->
 
   <body>
-    <release version="6.2" date="2017-12-DD" description="Experimental Java 9 Support">
+    <release version="6.3" date="2019-01-24" description="Experimental Java 9, 10, 11, 12-EA, and 13-EA Support">
+      <action issue="BCEL-304" type="fix" dev="ggregory" due-to="Gary Gregory, Ed Pavlak">ClassPath.getClassFile() and friends do not work with JDK 9 and higher (PR #22.)</action>
+      <action issue="BCEL-305" type="fix" dev="ggregory" due-to="Gary Gregory">ClassPath.getClassFile() and friends do not work with JRE 9 and higher</action>
+      <action                  type="update" dev="ggregory" due-to="Mark Thomas, Gary Gregory">Initial support for Java 11</action>
+      <action                  type="add" dev="ggregory" due-to="Mark Thomas">Added org.apache.bcel.classfile.Visitor.visitConstantDynamic(ConstantDynamic)</action>
+      <action                  type="add" dev="ggregory" due-to="Mark Thomas">Added org.apache.bcel.classfile.ConstantDynamic</action>
+      <action                  type="add" dev="ggregory" due-to="Mark Thomas">Added fields in org.apache.bcel.Const for Java 9, 10, and 11.</action>      
+      <action                  type="add" dev="ggregory" due-to="Mark Thomas">Added fields in org.apache.bcel.Const for Java 12 and 13 based on Java Early Access releases.</action>      
+      <action                  type="update" dev="ggregory" due-to="Gary Gregory">Update Java requirement from Java 7 to Java 8.</action>      
+    </release>
+
+    <release version="6.2" date="2017-12-08" description="Experimental Java 9 Support">
       <action issue="BCEL-294" type="fix" dev="britter" due-to="Mark Roberts">Incorrect comment in StackMap.java</action>
       <action issue="BCEL-296" type="fix" dev="ggregory" due-to="Mark Roberts">Incorrect comment in several classes.</action>
       <action issue="BCEL-295" type="fix" dev="ggregory" due-to="Mark Roberts">Fix local variable live range length; add test case.</action>


=====================================
src/main/java/org/apache/bcel/Const.java
=====================================
@@ -111,20 +111,72 @@ public final class Const {
    *  */
   public static final short MAJOR_1_8 = 52;
 
-  /** Major version number of class files for Java 1.9.
-   *  @see #MINOR_1_9
-   *  */
-  public static final short MAJOR_1_9 = 53;
-
   /** Minor version number of class files for Java 1.8.
    *  @see #MAJOR_1_8
    *  */
   public static final short MINOR_1_8 = 0;
 
-  /** Minor version number of class files for Java 1.9.
-   *  @see #MAJOR_1_9
+  /** Major version number of class files for Java 9.
+   *  @see #MINOR_9
+   *  */
+  public static final short MAJOR_9 = 53;
+
+  /** Minor version number of class files for Java 9.
+   *  @see #MAJOR_9
+   *  */
+  public static final short MINOR_9 = 0;
+
+  /**
+   * @deprecated Use {@link #MAJOR_9} instead
+   */
+  @Deprecated
+  public static final short MAJOR_1_9 = MAJOR_9;
+
+  /**
+   * @deprecated Use {@link #MINOR_9} instead
+   */
+  @Deprecated
+  public static final short MINOR_1_9 = MINOR_9;
+
+  /** Major version number of class files for Java 10.
+   *  @see #MINOR_10
+   *  */
+  public static final short MAJOR_10 = 54;
+
+  /** Minor version number of class files for Java 10.
+   *  @see #MAJOR_10
+   *  */
+  public static final short MINOR_10 = 0;
+
+  /** Major version number of class files for Java 11.
+   *  @see #MINOR_11
+   *  */
+  public static final short MAJOR_11 = 55;
+
+  /** Minor version number of class files for Java 11.
+   *  @see #MAJOR_11
    *  */
-  public static final short MINOR_1_9 = 0;
+  public static final short MINOR_11 = 0;
+
+  /** Major version number of class files for Java 12.
+   *  @see #MINOR_12
+   *  */
+  public static final short MAJOR_12 = 56;
+
+  /** Minor version number of class files for Java 12.
+   *  @see #MAJOR_12
+   *  */
+  public static final short MINOR_12 = 0;
+
+  /** Major version number of class files for Java 13.
+   *  @see #MINOR_13
+   *  */
+  public static final short MAJOR_13 = 57;
+
+  /** Minor version number of class files for Java 13.
+   *  @see #MAJOR_13
+   *  */
+  public static final short MINOR_13 = 0;
 
   /** Default major version number.  Class file is for Java 1.1.
    *  @see #MAJOR_1_1
@@ -364,6 +416,14 @@ public final class Const {
    */
   public static final byte CONSTANT_MethodType         = 16;
 
+  /**
+   * Marks a constant pool entry as dynamically computed.
+   * @see  <a href="https://bugs.openjdk.java.net/secure/attachment/74618/constant-dynamic.html">
+   * Change request for JEP 309</a>
+   * @since 6.3
+   */
+  public static final byte CONSTANT_Dynamic            = 17;
+
   /**
    * Marks a constant pool entry as an Invoke Dynamic
    * @see  <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4.10">
@@ -373,22 +433,16 @@ public final class Const {
 
   /**
    * Marks a constant pool entry as a Module Reference.
-   *
-   * <p>Note: Early access Java 9 support- currently subject to change</p>
-   *
-   * @see <a href="http://cr.openjdk.java.net/~mr/jigsaw/spec/lang-vm.html#jigsaw-2.6">
-   * JPMS: Modules in the Java Language and JVM</a>
+   * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.4.11">
+   * The Constant Pool in The Java Virtual Machine Specification</a>
    * @since 6.1
    */
   public static final byte CONSTANT_Module             = 19;
 
   /**
    * Marks a constant pool entry as a Package Reference.
-   *
-   * <p>Note: Early access Java 9 support- currently subject to change</p>
-   *
-   * @see <a href="http://cr.openjdk.java.net/~mr/jigsaw/spec/lang-vm.html#jigsaw-2.6">
-   * JPMS: Modules in the Java Language and JVM</a>
+   * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.4.12">
+   * The Constant Pool in The Java Virtual Machine Specification</a>
    * @since 6.1
    */
   public static final byte CONSTANT_Package            = 20;
@@ -403,7 +457,7 @@ public final class Const {
     "CONSTANT_Class", "CONSTANT_String", "CONSTANT_Fieldref",
     "CONSTANT_Methodref", "CONSTANT_InterfaceMethodref",
     "CONSTANT_NameAndType", "", "", "CONSTANT_MethodHandle",
-    "CONSTANT_MethodType", "", "CONSTANT_InvokeDynamic",
+    "CONSTANT_MethodType", "CONSTANT_Dynamic", "CONSTANT_InvokeDynamic",
     "CONSTANT_Module", "CONSTANT_Package"};
 
   /**


=====================================
src/main/java/org/apache/bcel/classfile/Constant.java
=====================================
@@ -127,52 +127,54 @@ public abstract class Constant implements Cloneable, Node {
     /**
      * Read one constant from the given input, the type depends on a tag byte.
      *
-     * @param input Input stream
+     * @param dataInput Input stream
      * @return Constant object
+     * @throws IOException if an I/O error occurs reading from the given {@code dataInput}.
+     * @throws ClassFormatException if the next byte is not recognized
      * @since 6.0 made public
      */
-    public static Constant readConstant( final DataInput input ) throws IOException,
-            ClassFormatException {
-        final byte b = input.readByte(); // Read tag byte
+    public static Constant readConstant(final DataInput dataInput) throws IOException, ClassFormatException {
+        final byte b = dataInput.readByte(); // Read tag byte
         switch (b) {
-            case Const.CONSTANT_Class:
-                return new ConstantClass(input);
-            case Const.CONSTANT_Fieldref:
-                return new ConstantFieldref(input);
-            case Const.CONSTANT_Methodref:
-                return new ConstantMethodref(input);
-            case Const.CONSTANT_InterfaceMethodref:
-                return new ConstantInterfaceMethodref(input);
-            case Const.CONSTANT_String:
-                return new ConstantString(input);
-            case Const.CONSTANT_Integer:
-                return new ConstantInteger(input);
-            case Const.CONSTANT_Float:
-                return new ConstantFloat(input);
-            case Const.CONSTANT_Long:
-                return new ConstantLong(input);
-            case Const.CONSTANT_Double:
-                return new ConstantDouble(input);
-            case Const.CONSTANT_NameAndType:
-                return new ConstantNameAndType(input);
-            case Const.CONSTANT_Utf8:
-                return ConstantUtf8.getInstance(input);
-            case Const.CONSTANT_MethodHandle:
-                return new ConstantMethodHandle(input);
-            case Const.CONSTANT_MethodType:
-                return new ConstantMethodType(input);
-            case Const.CONSTANT_InvokeDynamic:
-                return new ConstantInvokeDynamic(input);
-            case Const.CONSTANT_Module:
-                return new ConstantModule(input);
-            case Const.CONSTANT_Package:
-                return new ConstantPackage(input);
-            default:
-                throw new ClassFormatException("Invalid byte tag in constant pool: " + b);
+        case Const.CONSTANT_Class:
+            return new ConstantClass(dataInput);
+        case Const.CONSTANT_Fieldref:
+            return new ConstantFieldref(dataInput);
+        case Const.CONSTANT_Methodref:
+            return new ConstantMethodref(dataInput);
+        case Const.CONSTANT_InterfaceMethodref:
+            return new ConstantInterfaceMethodref(dataInput);
+        case Const.CONSTANT_String:
+            return new ConstantString(dataInput);
+        case Const.CONSTANT_Integer:
+            return new ConstantInteger(dataInput);
+        case Const.CONSTANT_Float:
+            return new ConstantFloat(dataInput);
+        case Const.CONSTANT_Long:
+            return new ConstantLong(dataInput);
+        case Const.CONSTANT_Double:
+            return new ConstantDouble(dataInput);
+        case Const.CONSTANT_NameAndType:
+            return new ConstantNameAndType(dataInput);
+        case Const.CONSTANT_Utf8:
+            return ConstantUtf8.getInstance(dataInput);
+        case Const.CONSTANT_MethodHandle:
+            return new ConstantMethodHandle(dataInput);
+        case Const.CONSTANT_MethodType:
+            return new ConstantMethodType(dataInput);
+        case Const.CONSTANT_Dynamic:
+            return new ConstantDynamic(dataInput);
+        case Const.CONSTANT_InvokeDynamic:
+            return new ConstantInvokeDynamic(dataInput);
+        case Const.CONSTANT_Module:
+            return new ConstantModule(dataInput);
+        case Const.CONSTANT_Package:
+            return new ConstantPackage(dataInput);
+        default:
+            throw new ClassFormatException("Invalid byte tag in constant pool: " + b);
         }
     }
 
-
     /**
      * @return Comparison strategy object
      */


=====================================
src/main/java/org/apache/bcel/classfile/ConstantClass.java
=====================================
@@ -27,7 +27,6 @@ import org.apache.bcel.Const;
  * This class is derived from the abstract {@link Constant}
  * and represents a reference to a (external) class.
  *
- * @version $Id$
  * @see     Constant
  */
 public final class ConstantClass extends Constant implements ConstantObject {
@@ -44,13 +43,13 @@ public final class ConstantClass extends Constant implements ConstantObject {
 
 
     /**
-     * Initialize instance from file data.
+     * Constructs an instance from file data.
      *
-     * @param file Input stream
-     * @throws IOException
+     * @param dataInput Input stream
+     * @throws IOException if an I/O error occurs reading from the given {@code dataInput}.
      */
-    ConstantClass(final DataInput file) throws IOException {
-        this(file.readUnsignedShort());
+    ConstantClass(final DataInput dataInput) throws IOException {
+        this(dataInput.readUnsignedShort());
     }
 
 
@@ -78,10 +77,10 @@ public final class ConstantClass extends Constant implements ConstantObject {
 
 
     /**
-     * Dump constant class to file stream in binary format.
+     * Dumps constant class to file stream in binary format.
      *
      * @param file Output file stream
-     * @throws IOException
+     * @throws IOException if an I/O error occurs writing to the DataOutputStream.
      */
     @Override
     public final void dump( final DataOutputStream file ) throws IOException {


=====================================
src/main/java/org/apache/bcel/classfile/ConstantDynamic.java
=====================================
@@ -0,0 +1,90 @@
+/*
+ * 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.
+ *
+ */
+package org.apache.bcel.classfile;
+
+import java.io.DataInput;
+import java.io.IOException;
+
+import org.apache.bcel.Const;
+
+/**
+ * This class is derived from the abstract {@link Constant}
+ * and represents a reference to a dynamically computed constant.
+ *
+ * @see     Constant
+ * @see  <a href="https://bugs.openjdk.java.net/secure/attachment/74618/constant-dynamic.html">
+ * Change request for JEP 309</a>
+ * @since 6.3
+ */
+public final class ConstantDynamic extends ConstantCP {
+
+    /**
+     * Initialize from another object.
+     */
+    public ConstantDynamic(final ConstantDynamic c) {
+        this(c.getBootstrapMethodAttrIndex(), c.getNameAndTypeIndex());
+    }
+
+
+    /**
+     * Initialize instance from file data.
+     *
+     * @param file Input stream
+     * @throws IOException
+     */
+    ConstantDynamic(final DataInput file) throws IOException {
+        this(file.readShort(), file.readShort());
+    }
+
+
+    public ConstantDynamic(final int bootstrap_method_attr_index, final int name_and_type_index) {
+        super(Const.CONSTANT_Dynamic, bootstrap_method_attr_index, name_and_type_index);
+    }
+
+
+    /**
+     * Called by objects that are traversing the nodes of the tree implicitly
+     * defined by the contents of a Java class. I.e., the hierarchy of methods,
+     * fields, attributes, etc. spawns a tree of objects.
+     *
+     * @param v Visitor object
+     */
+    @Override
+    public void accept( final Visitor v ) {
+        v.visitConstantDynamic(this);
+    }
+
+    /**
+     * @return Reference (index) to bootstrap method this constant refers to.
+     *
+     * Note that this method is a functional duplicate of getClassIndex
+     * for use by ConstantInvokeDynamic.
+     * @since 6.0
+     */
+    public final int getBootstrapMethodAttrIndex() {
+        return super.getClassIndex();  // AKA bootstrap_method_attr_index
+    }
+
+    /**
+     * @return String representation
+     */
+    @Override
+    public final String toString() {
+        return super.toString().replace("class_index", "bootstrap_method_attr_index");
+    }
+}


=====================================
src/main/java/org/apache/bcel/classfile/DescendingVisitor.java
=====================================
@@ -543,4 +543,12 @@ public class DescendingVisitor implements Visitor
         obj.accept(visitor);
         stack.pop();
     }
+
+    /** @since 6.3 */
+    @Override
+    public void visitConstantDynamic(final ConstantDynamic obj) {
+        stack.push(obj);
+        obj.accept(visitor);
+        stack.pop();
+    }
 }


=====================================
src/main/java/org/apache/bcel/classfile/EmptyVisitor.java
=====================================
@@ -310,4 +310,12 @@ public class EmptyVisitor implements Visitor
     @Override
     public void visitConstantModule(final ConstantModule constantModule) {
     }
+
+
+    /**
+     * @since 6.3
+     */
+    @Override
+    public void visitConstantDynamic(final ConstantDynamic obj) {
+    }
 }


=====================================
src/main/java/org/apache/bcel/classfile/Visitor.java
=====================================
@@ -156,4 +156,11 @@ public interface Visitor
      * @since 6.1
      */
     void visitConstantModule(ConstantModule constantModule);
+
+    /**
+     * @since 6.3
+     */
+    default void visitConstantDynamic(ConstantDynamic constantDynamic) {
+        // empty
+    }
 }


=====================================
src/main/java/org/apache/bcel/util/ClassPath.java
=====================================
@@ -17,6 +17,7 @@
  */
 package org.apache.bcel.util;
 
+import java.io.Closeable;
 import java.io.DataInputStream;
 import java.io.File;
 import java.io.FileInputStream;
@@ -25,141 +26,476 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.net.MalformedURLException;
 import java.net.URL;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Enumeration;
 import java.util.List;
 import java.util.Locale;
+import java.util.Objects;
 import java.util.StringTokenizer;
 import java.util.Vector;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipFile;
 
 /**
- * Responsible for loading (class) files from the CLASSPATH. Inspired by
- * sun.tools.ClassPath.
+ * Responsible for loading (class) files from the CLASSPATH. Inspired by sun.tools.ClassPath.
  *
  * @version $Id$
  */
-public class ClassPath {
+public class ClassPath implements Closeable {
 
-    public static final ClassPath SYSTEM_CLASS_PATH = new ClassPath(getClassPath());
+    private abstract static class AbstractPathEntry implements Closeable {
 
-    private static final FilenameFilter ARCHIVE_FILTER = new FilenameFilter() {
+        abstract ClassFile getClassFile(String name, String suffix) throws IOException;
+
+        abstract URL getResource(String name);
+
+        abstract InputStream getResourceAsStream(String name);
+    }
+
+    private abstract static class AbstractZip extends AbstractPathEntry {
+
+        private final ZipFile zipFile;
+
+        AbstractZip(final ZipFile zipFile) {
+            this.zipFile = Objects.requireNonNull(zipFile, "zipFile");
+        }
 
         @Override
-        public boolean accept( final File dir, String name ) {
-            name = name.toLowerCase(Locale.ENGLISH);
-            return name.endsWith(".zip") || name.endsWith(".jar");
+        public void close() throws IOException {
+            if (zipFile != null) {
+                zipFile.close();
+            }
+
         }
-    };
 
-    private final PathEntry[] paths;
-    private final String class_path;
-    private ClassPath parent;
+        @Override
+        ClassFile getClassFile(final String name, final String suffix) throws IOException {
+            final ZipEntry entry = zipFile.getEntry(toEntryName(name, suffix));
 
-    public ClassPath(final ClassPath parent, final String class_path) {
-        this(class_path);
-        this.parent = parent;
-    }
+            if (entry == null) {
+                return null;
+            }
 
-    /**
-     * Search for classes in given path.
-     *
-     * @param class_path
-     */
-    public ClassPath(final String class_path) {
-        this.class_path = class_path;
-        final List<PathEntry> list = new ArrayList<>();
-        for (final StringTokenizer tok = new StringTokenizer(class_path, File.pathSeparator); tok.hasMoreTokens();) {
-            final String path = tok.nextToken();
-            if (!path.isEmpty()) {
-                final File file = new File(path);
-                try {
-                    if (file.exists()) {
-                        if (file.isDirectory()) {
-                            list.add(new Dir(path));
-                        } else {
-                            list.add(new Zip(new ZipFile(file)));
-                        }
-                    }
-                } catch (final IOException e) {
-                    if (path.endsWith(".zip") || path.endsWith(".jar")) {
-                        System.err.println("CLASSPATH component " + file + ": " + e);
-                    }
+            return new ClassFile() {
+
+                @Override
+                public String getBase() {
+                    return zipFile.getName();
                 }
+
+                @Override
+                public InputStream getInputStream() throws IOException {
+                    return zipFile.getInputStream(entry);
+                }
+
+                @Override
+                public String getPath() {
+                    return entry.toString();
+                }
+
+                @Override
+                public long getSize() {
+                    return entry.getSize();
+                }
+
+                @Override
+                public long getTime() {
+                    return entry.getTime();
+                }
+            };
+        }
+
+        @Override
+        URL getResource(final String name) {
+            final ZipEntry entry = zipFile.getEntry(name);
+            try {
+                return entry != null ? new URL("jar:file:" + zipFile.getName() + "!/" + name) : null;
+            } catch (final MalformedURLException e) {
+                return null;
             }
         }
-        paths = new PathEntry[list.size()];
-        list.toArray(paths);
+
+        @Override
+        InputStream getResourceAsStream(final String name) {
+            final ZipEntry entry = zipFile.getEntry(name);
+            try {
+                return entry != null ? zipFile.getInputStream(entry) : null;
+            } catch (final IOException e) {
+                return null;
+            }
+        }
+
+        protected abstract String toEntryName(final String name, final String suffix);
+
+        @Override
+        public String toString() {
+            return zipFile.getName();
+        }
+
     }
 
     /**
-     * Search for classes in CLASSPATH.
-     * @deprecated Use SYSTEM_CLASS_PATH constant
+     * Contains information about file/ZIP entry of the Java class.
      */
-    @Deprecated
-    public ClassPath() {
-        this(getClassPath());
+    public interface ClassFile {
+
+        /**
+         * @return base path of found class, i.e. class is contained relative to that path, which may either denote a
+         *         directory, or zip file
+         */
+        String getBase();
+
+        /**
+         * @return input stream for class file.
+         */
+        InputStream getInputStream() throws IOException;
+
+        /**
+         * @return canonical path to class file.
+         */
+        String getPath();
+
+        /**
+         * @return size of class file.
+         */
+        long getSize();
+
+        /**
+         * @return modification time of class file.
+         */
+        long getTime();
     }
 
-    /** @return used class path string
-     */
-    @Override
-    public String toString() {
-        if (parent != null) {
-            return parent + File.pathSeparator + class_path;
+    private static class Dir extends AbstractPathEntry {
+
+        private final String dir;
+
+        Dir(final String d) {
+            dir = d;
+        }
+
+        @Override
+        public void close() throws IOException {
+            // Nothing to do
+
+        }
+
+        @Override
+        ClassFile getClassFile(final String name, final String suffix) throws IOException {
+            final File file = new File(dir + File.separatorChar + name.replace('.', File.separatorChar) + suffix);
+            return file.exists() ? new ClassFile() {
+
+                @Override
+                public String getBase() {
+                    return dir;
+                }
+
+                @Override
+                public InputStream getInputStream() throws IOException {
+                    return new FileInputStream(file);
+                }
+
+                @Override
+                public String getPath() {
+                    try {
+                        return file.getCanonicalPath();
+                    } catch (final IOException e) {
+                        return null;
+                    }
+                }
+
+                @Override
+                public long getSize() {
+                    return file.length();
+                }
+
+                @Override
+                public long getTime() {
+                    return file.lastModified();
+                }
+            } : null;
+        }
+
+        @Override
+        URL getResource(final String name) {
+            // Resource specification uses '/' whatever the platform
+            final File file = toFile(name);
+            try {
+                return file.exists() ? file.toURI().toURL() : null;
+            } catch (final MalformedURLException e) {
+                return null;
+            }
+        }
+
+        @Override
+        InputStream getResourceAsStream(final String name) {
+            // Resource specification uses '/' whatever the platform
+            final File file = toFile(name);
+            try {
+                return file.exists() ? new FileInputStream(file) : null;
+            } catch (final IOException e) {
+                return null;
+            }
+        }
+
+        private File toFile(final String name) {
+            return new File(dir + File.separatorChar + name.replace('/', File.separatorChar));
+        }
+
+        @Override
+        public String toString() {
+            return dir;
         }
-        return class_path;
     }
 
-    @Override
-    public int hashCode() {
-        if (parent != null) {
-            return class_path.hashCode() + parent.hashCode();
+    private static class Jar extends AbstractZip {
+
+        Jar(final ZipFile zip) {
+            super(zip);
+        }
+
+        @Override
+        protected String toEntryName(final String name, final String suffix) {
+            return packageToFolder(name) + suffix;
         }
-        return class_path.hashCode();
+
     }
 
+    private static class JrtModule extends AbstractPathEntry {
 
-    @Override
-    public boolean equals( final Object o ) {
-        if (o instanceof ClassPath) {
-            final ClassPath cp = (ClassPath)o;
-            return class_path.equals(cp.toString());
+        private final Path modulePath;
+
+        public JrtModule(final Path modulePath) {
+            this.modulePath = Objects.requireNonNull(modulePath, "modulePath");
         }
-        return false;
+
+        @Override
+        public void close() throws IOException {
+            // Nothing to do.
+
+        }
+
+        @Override
+        ClassFile getClassFile(final String name, final String suffix) throws IOException {
+            final Path resolved = modulePath.resolve(packageToFolder(name) + suffix);
+            if (Files.exists(resolved)) {
+                return new ClassFile() {
+
+                    @Override
+                    public String getBase() {
+                        return resolved.getFileName().toString();
+                    }
+
+                    @Override
+                    public InputStream getInputStream() throws IOException {
+                        return Files.newInputStream(resolved);
+                    }
+
+                    @Override
+                    public String getPath() {
+                        return resolved.toString();
+                    }
+
+                    @Override
+                    public long getSize() {
+                        try {
+                            return Files.size(resolved);
+                        } catch (final IOException e) {
+                            return 0;
+                        }
+                    }
+
+                    @Override
+                    public long getTime() {
+                        try {
+                            return Files.getLastModifiedTime(resolved).toMillis();
+                        } catch (final IOException e) {
+                            return 0;
+                        }
+                    }
+                };
+            }
+            return null;
+        }
+
+        @Override
+        URL getResource(final String name) {
+            final Path resovled = modulePath.resolve(name);
+            try {
+                return Files.exists(resovled) ? new URL("jrt:" + modulePath + "/" + name) : null;
+            } catch (final MalformedURLException e) {
+                return null;
+            }
+        }
+
+        @Override
+        InputStream getResourceAsStream(final String name) {
+            try {
+                return Files.newInputStream(modulePath.resolve(name));
+            } catch (final IOException e) {
+                return null;
+            }
+        }
+
+        @Override
+        public String toString() {
+            return modulePath.toString();
+        }
+
     }
 
+    private static class JrtModules extends AbstractPathEntry {
 
-    private static void getPathComponents( final String path, final List<String> list ) {
-        if (path != null) {
-            final StringTokenizer tok = new StringTokenizer(path, File.pathSeparator);
-            while (tok.hasMoreTokens()) {
-                final String name = tok.nextToken();
-                final File file = new File(name);
-                if (file.exists()) {
-                    list.add(name);
+        private final ModularRuntimeImage modularRuntimeImage;
+        private final JrtModule[] modules;
+
+        public JrtModules(String path) throws IOException {
+            this.modularRuntimeImage = new ModularRuntimeImage();
+            final List<Path> list = modularRuntimeImage.list(path);
+            this.modules = new JrtModule[list.size()];
+            for (int i = 0; i < modules.length; i++) {
+                modules[i] = new JrtModule(list.get(i));
+            }
+        }
+
+        @Override
+        public void close() throws IOException {
+            if (modules != null) {
+                // don't use a for each loop to avoid creating an iterator for the GC to collect.
+                for (int i = 0; i < modules.length; i++) {
+                    modules[i].close();
+                }
+            }
+            if (modularRuntimeImage != null) {
+                modularRuntimeImage.close();
+            }
+        }
+
+        @Override
+        ClassFile getClassFile(final String name, final String suffix) throws IOException {
+            // don't use a for each loop to avoid creating an iterator for the GC to collect.
+            for (int i = 0; i < modules.length; i++) {
+                final ClassFile classFile = modules[i].getClassFile(name, suffix);
+                if (classFile != null) {
+                    return classFile;
+                }
+            }
+            return null;
+        }
+
+        @Override
+        URL getResource(final String name) {
+            // don't use a for each loop to avoid creating an iterator for the GC to collect.
+            for (int i = 0; i < modules.length; i++) {
+                final URL url = modules[i].getResource(name);
+                if (url != null) {
+                    return url;
                 }
             }
+            return null;
         }
+
+        @Override
+        InputStream getResourceAsStream(final String name) {
+            // don't use a for each loop to avoid creating an iterator for the GC to collect.
+            for (int i = 0; i < modules.length; i++) {
+                final InputStream inputStream = modules[i].getResourceAsStream(name);
+                if (inputStream != null) {
+                    return inputStream;
+                }
+            }
+            return null;
+        }
+
+        @Override
+        public String toString() {
+            return Arrays.toString(modules);
+        }
+
     }
 
+    private static class Module extends AbstractZip {
 
-    /** Checks for class path components in the following properties:
-     * "java.class.path", "sun.boot.class.path", "java.ext.dirs"
+        Module(final ZipFile zip) {
+            super(zip);
+        }
+
+        @Override
+        protected String toEntryName(final String name, final String suffix) {
+            return "classes/" + packageToFolder(name) + suffix;
+        }
+
+    }
+
+    private static final FilenameFilter ARCHIVE_FILTER = new FilenameFilter() {
+
+        @Override
+        public boolean accept(final File dir, String name) {
+            name = name.toLowerCase(Locale.ENGLISH);
+            return name.endsWith(".zip") || name.endsWith(".jar");
+        }
+    };
+
+    private static final FilenameFilter MODULES_FILTER = new FilenameFilter() {
+
+        @Override
+        public boolean accept(final File dir, String name) {
+            name = name.toLowerCase(Locale.ENGLISH);
+            return name.endsWith(".jmod");
+        }
+    };
+
+    public static final ClassPath SYSTEM_CLASS_PATH = new ClassPath(getClassPath());
+
+    private static void addJdkModules(final String javaHome, final List<String> list) {
+        String modulesPath = System.getProperty("java.modules.path");
+        if (modulesPath == null || modulesPath.trim().isEmpty()) {
+            // Default to looking in JAVA_HOME/jmods
+            modulesPath = javaHome + File.separator + "jmods";
+        }
+        final File modulesDir = new File(modulesPath);
+        if (modulesDir.exists()) {
+            final String[] modules = modulesDir.list(MODULES_FILTER);
+            for (int i = 0; i < modules.length; i++) {
+                list.add(modulesDir.getPath() + File.separatorChar + modules[i]);
+            }
+        }
+    }
+
+    /**
+     * Checks for class path components in the following properties: "java.class.path", "sun.boot.class.path",
+     * "java.ext.dirs"
      *
      * @return class path as used by default by BCEL
      */
     // @since 6.0 no longer final
     public static String getClassPath() {
-        final String class_path = System.getProperty("java.class.path");
-        final String boot_path = System.getProperty("sun.boot.class.path");
-        final String ext_path = System.getProperty("java.ext.dirs");
+        final String classPathProp = System.getProperty("java.class.path");
+        final String bootClassPathProp = System.getProperty("sun.boot.class.path");
+        final String extDirs = System.getProperty("java.ext.dirs");
+        // System.out.println("java.version = " + System.getProperty("java.version"));
+        // System.out.println("java.class.path = " + classPathProp);
+        // System.out.println("sun.boot.class.path=" + bootClassPathProp);
+        // System.out.println("java.ext.dirs=" + extDirs);
+        final String javaHome = System.getProperty("java.home");
         final List<String> list = new ArrayList<>();
-        getPathComponents(class_path, list);
-        getPathComponents(boot_path, list);
+
+        // Starting in JRE 9, .class files are in the modules directory. Add them to the path.
+        final Path modulesPath = Paths.get(javaHome).resolve("lib/modules");
+        if (Files.exists(modulesPath) && Files.isRegularFile(modulesPath)) {
+            list.add(modulesPath.toAbsolutePath().toString());
+        }
+        // Starting in JDK 9, .class files are in the jmods directory. Add them to the path.
+        addJdkModules(javaHome, list);
+
+        getPathComponents(classPathProp, list);
+        getPathComponents(bootClassPathProp, list);
         final List<String> dirs = new ArrayList<>();
-        getPathComponents(ext_path, dirs);
+        getPathComponents(extDirs, dirs);
         for (final String d : dirs) {
             final File ext_dir = new File(d);
             final String[] extensions = ext_dir.list(ARCHIVE_FILTER);
@@ -169,6 +505,7 @@ public class ClassPath {
                 }
             }
         }
+
         final StringBuilder buf = new StringBuilder();
         String separator = "";
         for (final String path : list) {
@@ -179,89 +516,148 @@ public class ClassPath {
         return buf.toString().intern();
     }
 
+    private static void getPathComponents(final String path, final List<String> list) {
+        if (path != null) {
+            final StringTokenizer tokenizer = new StringTokenizer(path, File.pathSeparator);
+            while (tokenizer.hasMoreTokens()) {
+                final String name = tokenizer.nextToken();
+                final File file = new File(name);
+                if (file.exists()) {
+                    list.add(name);
+                }
+            }
+        }
+    }
+
+    static String packageToFolder(final String name) {
+        return name.replace('.', '/');
+    }
+
+    private final String classPath;
+
+    private ClassPath parent;
+
+    private final AbstractPathEntry[] paths;
 
     /**
-     * @param name fully qualified class name, e.g. java.lang.String
-     * @return input stream for class
+     * Search for classes in CLASSPATH.
+     *
+     * @deprecated Use SYSTEM_CLASS_PATH constant
      */
-    public InputStream getInputStream( final String name ) throws IOException {
-        return getInputStream(name.replace('.', '/'), ".class");
+    @Deprecated
+    public ClassPath() {
+        this(getClassPath());
     }
 
+    public ClassPath(final ClassPath parent, final String classPath) {
+        this(classPath);
+        this.parent = parent;
+    }
 
     /**
-     * Return stream for class or resource on CLASSPATH.
+     * Search for classes in given path.
      *
-     * @param name fully qualified file name, e.g. java/lang/String
-     * @param suffix file name ends with suff, e.g. .java
-     * @return input stream for file on class path
+     * @param classPath
      */
-    public InputStream getInputStream( final String name, final String suffix ) throws IOException {
-        InputStream is = null;
-        try {
-            is = getClass().getClassLoader().getResourceAsStream(name + suffix); // may return null
-        } catch (final Exception e) {
-            // ignored
+    @SuppressWarnings("resource")
+    public ClassPath(final String classPath) {
+        this.classPath = classPath;
+        final List<AbstractPathEntry> list = new ArrayList<>();
+        for (final StringTokenizer tokenizer = new StringTokenizer(classPath, File.pathSeparator); tokenizer
+                .hasMoreTokens();) {
+            final String path = tokenizer.nextToken();
+            if (!path.isEmpty()) {
+                final File file = new File(path);
+                try {
+                    if (file.exists()) {
+                        if (file.isDirectory()) {
+                            list.add(new Dir(path));
+                        } else if (path.endsWith(".jmod")) {
+                            list.add(new Module(new ZipFile(file)));
+                        } else if (path.endsWith(ModularRuntimeImage.MODULES_PATH)) {
+                            list.add(new JrtModules(ModularRuntimeImage.MODULES_PATH));
+                        } else {
+                            list.add(new Jar(new ZipFile(file)));
+                        }
+                    }
+                } catch (final IOException e) {
+                    if (path.endsWith(".zip") || path.endsWith(".jar")) {
+                        System.err.println("CLASSPATH component " + file + ": " + e);
+                    }
+                }
+            }
         }
-        if (is != null) {
-            return is;
+        paths = new AbstractPathEntry[list.size()];
+        list.toArray(paths);
+    }
+
+    @Override
+    public void close() throws IOException {
+        if (paths != null) {
+            for (final AbstractPathEntry path : paths) {
+                path.close();
+            }
+        }
+
+    }
+
+    @Override
+    public boolean equals(final Object o) {
+        if (o instanceof ClassPath) {
+            final ClassPath cp = (ClassPath) o;
+            return classPath.equals(cp.toString());
         }
-        return getClassFile(name, suffix).getInputStream();
+        return false;
     }
 
     /**
-     * @param name fully qualified resource name, e.g. java/lang/String.class
-     * @return InputStream supplying the resource, or null if no resource with that name.
-     * @since 6.0
+     * @return byte array for class
      */
-    public InputStream getResourceAsStream(final String name) {
-        for (final PathEntry path : paths) {
-            InputStream is;
-            if ((is = path.getResourceAsStream(name)) != null) {
-                return is;
-            }
-        }
-        return null;
+    public byte[] getBytes(final String name) throws IOException {
+        return getBytes(name, ".class");
     }
 
     /**
-     * @param name fully qualified resource name, e.g. java/lang/String.class
-     * @return URL supplying the resource, or null if no resource with that name.
-     * @since 6.0
+     * @param name
+     *            fully qualified file name, e.g. java/lang/String
+     * @param suffix
+     *            file name ends with suffix, e.g. .java
+     * @return byte array for file on class path
      */
-    public URL getResource(final String name) {
-        for (final PathEntry path : paths) {
-            URL url;
-            if ((url = path.getResource(name)) != null) {
-                return url;
+    public byte[] getBytes(final String name, final String suffix) throws IOException {
+        DataInputStream dis = null;
+        try (InputStream inputStream = getInputStream(name, suffix)) {
+            if (inputStream == null) {
+                throw new IOException("Couldn't find: " + name + suffix);
+            }
+            dis = new DataInputStream(inputStream);
+            final byte[] bytes = new byte[inputStream.available()];
+            dis.readFully(bytes);
+            return bytes;
+        } finally {
+            if (dis != null) {
+                dis.close();
             }
         }
-        return null;
     }
 
     /**
-     * @param name fully qualified resource name, e.g. java/lang/String.class
-     * @return An Enumeration of URLs supplying the resource, or an
-     * empty Enumeration if no resource with that name.
-     * @since 6.0
+     * @param name
+     *            fully qualified class name, e.g. java.lang.String
+     * @return input stream for class
      */
-    public Enumeration<URL> getResources(final String name) {
-        final Vector<URL> results = new Vector<>();
-        for (final PathEntry path : paths) {
-            URL url;
-            if ((url = path.getResource(name)) != null) {
-                results.add(url);
-            }
-        }
-        return results.elements();
+    public ClassFile getClassFile(final String name) throws IOException {
+        return getClassFile(name, ".class");
     }
 
     /**
-     * @param name fully qualified file name, e.g. java/lang/String
-     * @param suffix file name ends with suff, e.g. .java
+     * @param name
+     *            fully qualified file name, e.g. java/lang/String
+     * @param suffix
+     *            file name ends with suff, e.g. .java
      * @return class file for the java class
      */
-    public ClassFile getClassFile( final String name, final String suffix ) throws IOException {
+    public ClassFile getClassFile(final String name, final String suffix) throws IOException {
         ClassFile cf = null;
 
         if (parent != null) {
@@ -281,63 +677,54 @@ public class ClassPath {
 
     private ClassFile getClassFileInternal(final String name, final String suffix) throws IOException {
 
-      for (final PathEntry path : paths) {
-          final ClassFile cf = path.getClassFile(name, suffix);
+        for (final AbstractPathEntry path : paths) {
+            final ClassFile cf = path.getClassFile(name, suffix);
 
-          if(cf != null) {
-              return cf;
-          }
-      }
-
-      return null;
-   }
+            if (cf != null) {
+                return cf;
+            }
+        }
 
+        return null;
+    }
 
     /**
-     * @param name fully qualified class name, e.g. java.lang.String
+     * @param name
+     *            fully qualified class name, e.g. java.lang.String
      * @return input stream for class
      */
-    public ClassFile getClassFile( final String name ) throws IOException {
-        return getClassFile(name, ".class");
+    public InputStream getInputStream(final String name) throws IOException {
+        return getInputStream(packageToFolder(name), ".class");
     }
 
-
     /**
-     * @param name fully qualified file name, e.g. java/lang/String
-     * @param suffix file name ends with suffix, e.g. .java
-     * @return byte array for file on class path
+     * Return stream for class or resource on CLASSPATH.
+     *
+     * @param name
+     *            fully qualified file name, e.g. java/lang/String
+     * @param suffix
+     *            file name ends with suff, e.g. .java
+     * @return input stream for file on class path
      */
-    public byte[] getBytes(final String name, final String suffix) throws IOException {
-        DataInputStream dis = null;
-        try (InputStream is = getInputStream(name, suffix)) {
-            if (is == null) {
-                throw new IOException("Couldn't find: " + name + suffix);
-            }
-            dis = new DataInputStream(is);
-            final byte[] bytes = new byte[is.available()];
-            dis.readFully(bytes);
-            return bytes;
-        } finally {
-            if (dis != null) {
-                dis.close();
-            }
+    public InputStream getInputStream(final String name, final String suffix) throws IOException {
+        InputStream inputStream = null;
+        try {
+            inputStream = getClass().getClassLoader().getResourceAsStream(name + suffix); // may return null
+        } catch (final Exception e) {
+            // ignored
         }
+        if (inputStream != null) {
+            return inputStream;
+        }
+        return getClassFile(name, suffix).getInputStream();
     }
 
-
-    /**
-     * @return byte array for class
-     */
-    public byte[] getBytes( final String name ) throws IOException {
-        return getBytes(name, ".class");
-    }
-
-
     /**
-     * @param name name of file to search for, e.g. java/lang/String.java
+     * @param name
+     *            name of file to search for, e.g. java/lang/String.java
      * @return full (canonical) path for file
      */
-    public String getPath( String name ) throws IOException {
+    public String getPath(String name) throws IOException {
         final int index = name.lastIndexOf('.');
         String suffix = "";
         if (index > 0) {
@@ -347,200 +734,82 @@ public class ClassPath {
         return getPath(name, suffix);
     }
 
-
     /**
-     * @param name name of file to search for, e.g. java/lang/String
-     * @param suffix file name suffix, e.g. .java
+     * @param name
+     *            name of file to search for, e.g. java/lang/String
+     * @param suffix
+     *            file name suffix, e.g. .java
      * @return full (canonical) path for file, if it exists
      */
-    public String getPath( final String name, final String suffix ) throws IOException {
+    public String getPath(final String name, final String suffix) throws IOException {
         return getClassFile(name, suffix).getPath();
     }
 
-    private abstract static class PathEntry {
-
-        abstract ClassFile getClassFile( String name, String suffix ) throws IOException;
-        abstract URL getResource(String name);
-        abstract InputStream getResourceAsStream(String name);
-    }
-
-    /** Contains information about file/ZIP entry of the Java class.
+    /**
+     * @param name
+     *            fully qualified resource name, e.g. java/lang/String.class
+     * @return URL supplying the resource, or null if no resource with that name.
+     * @since 6.0
      */
-    public interface ClassFile {
-
-        /** @return input stream for class file.
-         */
-        InputStream getInputStream() throws IOException;
-
-
-        /** @return canonical path to class file.
-         */
-        String getPath();
-
-
-        /** @return base path of found class, i.e. class is contained relative
-         * to that path, which may either denote a directory, or zip file
-         */
-        String getBase();
-
-
-        /** @return modification time of class file.
-         */
-        long getTime();
-
-
-        /** @return size of class file.
-         */
-        long getSize();
-    }
-
-    private static class Dir extends PathEntry {
-
-        private final String dir;
-
-
-        Dir(final String d) {
-            dir = d;
-        }
-
-        @Override
-        URL getResource(final String name) {
-            // Resource specification uses '/' whatever the platform
-            final File file = new File(dir + File.separatorChar + name.replace('/', File.separatorChar));
-            try {
-                return file.exists() ? file.toURI().toURL() : null;
-            } catch (final MalformedURLException e) {
-               return null;
+    public URL getResource(final String name) {
+        for (final AbstractPathEntry path : paths) {
+            URL url;
+            if ((url = path.getResource(name)) != null) {
+                return url;
             }
         }
+        return null;
+    }
 
-        @Override
-        InputStream getResourceAsStream(final String name) {
-            // Resource specification uses '/' whatever the platform
-            final File file = new File(dir + File.separatorChar + name.replace('/', File.separatorChar));
-            try {
-               return file.exists() ? new FileInputStream(file) : null;
-            } catch (final IOException e) {
-               return null;
+    /**
+     * @param name
+     *            fully qualified resource name, e.g. java/lang/String.class
+     * @return InputStream supplying the resource, or null if no resource with that name.
+     * @since 6.0
+     */
+    public InputStream getResourceAsStream(final String name) {
+        for (final AbstractPathEntry path : paths) {
+            InputStream is;
+            if ((is = path.getResourceAsStream(name)) != null) {
+                return is;
             }
         }
-
-        @Override
-        ClassFile getClassFile( final String name, final String suffix ) throws IOException {
-            final File file = new File(dir + File.separatorChar
-                    + name.replace('.', File.separatorChar) + suffix);
-            return file.exists() ? new ClassFile() {
-
-                @Override
-                public InputStream getInputStream() throws IOException {
-                    return new FileInputStream(file);
-                }
-
-
-                @Override
-                public String getPath() {
-                    try {
-                        return file.getCanonicalPath();
-                    } catch (final IOException e) {
-                        return null;
-                    }
-                }
-
-
-                @Override
-                public long getTime() {
-                    return file.lastModified();
-                }
-
-
-                @Override
-                public long getSize() {
-                    return file.length();
-                }
-
-
-                @Override
-                public String getBase() {
-                    return dir;
-                }
-            } : null;
-        }
-
-
-        @Override
-        public String toString() {
-            return dir;
-        }
+        return null;
     }
 
-    private static class Zip extends PathEntry {
-
-        private final ZipFile zip;
-
-
-        Zip(final ZipFile z) {
-            zip = z;
-        }
-
-        @Override
-        URL getResource(final String name) {
-            final ZipEntry entry = zip.getEntry(name);
-            try {
-                return (entry != null) ? new URL("jar:file:" + zip.getName() + "!/" + name) : null;
-            } catch (final MalformedURLException e) {
-                return null;
-           }
-        }
-
-        @Override
-        InputStream getResourceAsStream(final String name) {
-            final ZipEntry entry = zip.getEntry(name);
-            try {
-                return (entry != null) ? zip.getInputStream(entry) : null;
-            } catch (final IOException e) {
-                return null;
+    /**
+     * @param name
+     *            fully qualified resource name, e.g. java/lang/String.class
+     * @return An Enumeration of URLs supplying the resource, or an empty Enumeration if no resource with that name.
+     * @since 6.0
+     */
+    public Enumeration<URL> getResources(final String name) {
+        final Vector<URL> results = new Vector<>();
+        for (final AbstractPathEntry path : paths) {
+            URL url;
+            if ((url = path.getResource(name)) != null) {
+                results.add(url);
             }
         }
+        return results.elements();
+    }
 
-        @Override
-        ClassFile getClassFile( final String name, final String suffix ) throws IOException {
-            final ZipEntry entry = zip.getEntry(name.replace('.', '/') + suffix);
-
-            if (entry == null) {
-                return null;
-            }
-
-            return new ClassFile() {
-
-                @Override
-                public InputStream getInputStream() throws IOException {
-                    return zip.getInputStream(entry);
-                }
-
-
-                @Override
-                public String getPath() {
-                    return entry.toString();
-                }
-
-
-                @Override
-                public long getTime() {
-                    return entry.getTime();
-                }
-
-
-                @Override
-                public long getSize() {
-                    return entry.getSize();
-                }
-
+    @Override
+    public int hashCode() {
+        if (parent != null) {
+            return classPath.hashCode() + parent.hashCode();
+        }
+        return classPath.hashCode();
+    }
 
-                @Override
-                public String getBase() {
-                    return zip.getName();
-                }
-            };
+    /**
+     * @return used class path string
+     */
+    @Override
+    public String toString() {
+        if (parent != null) {
+            return parent + File.pathSeparator + classPath;
         }
+        return classPath;
     }
 }


=====================================
src/main/java/org/apache/bcel/util/ModularRuntimeImage.java
=====================================
@@ -0,0 +1,154 @@
+/*
+ * 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.
+ *
+ */
+package org.apache.bcel.util;
+
+import java.io.Closeable;
+import java.io.File;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.nio.file.DirectoryStream;
+import java.nio.file.FileSystem;
+import java.nio.file.FileSystems;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Wraps a Java 9 JEP 220 modular runtime image. Requires the JRT NIO file system.
+ *
+ * @since 6.3
+ */
+public class ModularRuntimeImage implements Closeable {
+
+    static final String MODULES_PATH = File.separator + "modules";
+    static final String PACKAGES_PATH = File.separator + "packages";
+
+    private final URLClassLoader classLoader;
+    private final FileSystem fileSystem;
+
+    /**
+     * Constructs a default instance.
+     *
+     * @throws IOException
+     *             an I/O error occurs accessing the file system
+     */
+    public ModularRuntimeImage() throws IOException {
+        this(null, FileSystems.getFileSystem(URI.create("jrt:/")));
+    }
+
+    /**
+     * Constructs an instance using the JRT file system implementation from a specific Java Home.
+     *
+     * @param javaHome
+     *            Path to a Java 9 or greater home.
+     *
+     * @throws IOException
+     *             an I/O error occurs accessing the file system
+     */
+    public ModularRuntimeImage(final String javaHome) throws IOException {
+        final Map<String, ?> emptyMap = Collections.emptyMap();
+        final Path jrePath = Paths.get(javaHome);
+        final Path jrtFsPath = jrePath.resolve("lib").resolve("jrt-fs.jar");
+        this.classLoader = new URLClassLoader(new URL[] {jrtFsPath.toUri().toURL() });
+        this.fileSystem = FileSystems.newFileSystem(URI.create("jrt:/"), emptyMap, classLoader);
+    }
+
+    private ModularRuntimeImage(final URLClassLoader cl, final FileSystem fs) {
+        this.classLoader = cl;
+        this.fileSystem = fs;
+    }
+
+    @Override
+    public void close() throws IOException {
+        if (classLoader != null) {
+            if (classLoader != null) {
+                classLoader.close();
+            }
+            if (fileSystem != null) {
+                fileSystem.close();
+            }
+        }
+    }
+
+    /**
+     * Lists all entries in the given directory.
+     *
+     * @param dirPath
+     *            directory path.
+     * @return a list of dir entries if an I/O error occurs
+     * @throws IOException
+     *             an I/O error occurs accessing the file system
+     */
+    public List<Path> list(final Path dirPath) throws IOException {
+        final List<Path> list = new ArrayList<>();
+        try (DirectoryStream<Path> ds = Files.newDirectoryStream(dirPath)) {
+            final Iterator<Path> iterator = ds.iterator();
+            while (iterator.hasNext()) {
+                list.add(iterator.next());
+            }
+        }
+        return list;
+    }
+
+    /**
+     * Lists all entries in the given directory.
+     *
+     * @param dirName
+     *            directory path.
+     * @return a list of dir entries if an I/O error occurs
+     * @throws IOException
+     *             an I/O error occurs accessing the file system
+     */
+    public List<Path> list(final String dirName) throws IOException {
+        return list(fileSystem.getPath(dirName));
+    }
+
+    /**
+     * Lists all modules.
+     *
+     * @return a list of modules
+     * @throws IOException
+     *             an I/O error occurs accessing the file system
+     */
+    public List<Path> modules() throws IOException {
+        return list(MODULES_PATH);
+    }
+
+    /**
+     * Lists all packages.
+     *
+     * @return a list of modules
+     * @throws IOException
+     *             an I/O error occurs accessing the file system
+     */
+    public List<Path> packages() throws IOException {
+        return list(PACKAGES_PATH);
+    }
+
+    public FileSystem getFileSystem() {
+        return fileSystem;
+    }
+
+}


=====================================
src/main/java/org/apache/bcel/util/Repository.java
=====================================
@@ -30,43 +30,45 @@ import org.apache.bcel.classfile.JavaClass;
 public interface Repository {
 
     /**
-     * Store the provided class under "clazz.getClassName()"
+     * Stores the provided class under "clazz.getClassName()"
      */
     void storeClass( JavaClass clazz );
 
 
     /**
-     * Remove class from repository
+     * Removes class from repository
      */
     void removeClass( JavaClass clazz );
 
 
     /**
-     * Find the class with the name provided, if the class
+     * Finds the class with the name provided, if the class
      * isn't there, return NULL.
      */
     JavaClass findClass( String className );
 
 
     /**
-     * Find the class with the name provided, if the class
+     * Finds the class with the name provided, if the class
      * isn't there, make an attempt to load it.
      */
     JavaClass loadClass( String className ) throws java.lang.ClassNotFoundException;
 
 
     /**
-     * Find the JavaClass instance for the given run-time class object
+     * Finds the JavaClass instance for the given run-time class object
      */
     JavaClass loadClass( Class<?> clazz ) throws java.lang.ClassNotFoundException;
 
 
-    /** Clear all entries from cache.
+    /** 
+     * Clears all entries from cache.
      */
     void clear();
 
 
-    /** Get the ClassPath associated with this Repository
+    /** 
+     * Gets the ClassPath associated with this Repository
      */
     ClassPath getClassPath();
 }


=====================================
src/site/resources/bcel5-bcel6-clirr-report.html
=====================================
@@ -160,8 +160,8 @@ limitations under the License.
     JIRA Report</a>
           </li>
                                      <li class="none">
-                  <a href="apidocs/index.html" title="JavaDocs">
-    JavaDocs</a>
+                  <a href="apidocs/index.html" title="Javadocs">
+    Javadocs</a>
           </li>
                                      <li class="none">
                   <a href="xref/index.html" title="Source Xref">


=====================================
src/site/xdoc/download_bcel.xml
=====================================
@@ -26,22 +26,24 @@ limitations under the License.
  | commons-build-plugin/trunk/src/main/resources/commons-xdoc-templates |
  +======================================================================+
  |                                                                      |
- | 1) Re-generate using: mvn commons:download-page                      |
+ | 1) Re-generate using: mvn commons-build:download-page                |
  |                                                                      |
  | 2) Set the following properties in the component's pom:              |
- |    - commons.componentid (required, alphabetic, lower case)          |
+ |    - commons.componentid     (required, alphabetic, lower case)      |
  |    - commons.release.version (required)                              |
  |    - commons.release.name    (required)                              |
  |    - commons.binary.suffix   (optional)                              |
  |      (defaults to "-bin", set to "" for pre-maven2 releases)         |
  |    - commons.release.desc    (optional)                              |
  |    - commons.release.subdir  (optional)                              |
+ |    - commons.release.hash    (optional, lowercase, default sha256)   |
  |                                                                      |
- |    - commons.release.2/3.version       (conditional)                 |
- |    - commons.release.2/3.name          (conditional)                 |
- |    - commons.release.2/3.binary.suffix (optional)                    |
- |    - commons.release.2/3.desc          (optional)                    |
- |    - commons.release.2/3.subdir        (optional)                    |
+ |    - commons.release.[234].version       (conditional)               |
+ |    - commons.release.[234].name          (conditional)               |
+ |    - commons.release.[234].binary.suffix (optional)                  |
+ |    - commons.release.[234].desc          (optional)                  |
+ |    - commons.release.[234].subdir        (optional)                  |
+ |    - commons.release.[234].hash       (optional, lowercase, [sha256])|
  |                                                                      |
  | 3) Example Properties                                                |
  |    (commons.release.name inherited by parent:                        |
@@ -102,7 +104,7 @@ limitations under the License.
         It is essential that you
         <a href="https://www.apache.org/info/verification.html">verify the integrity</a>
         of downloaded files, preferably using the <code>PGP</code> signature (<code>*.asc</code> files);
-        failing that using the <code>MD5</code> hash (<code>*.md5</code> checksum files).
+        failing that using the <code>SHA256</code> hash (<code>*.sha256</code> checksum files).
       </p>
       <p>
         The <a href="https://www.apache.org/dist/commons/KEYS">KEYS</a>
@@ -111,32 +113,32 @@ limitations under the License.
       </p>
     </subsection>
     </section>
-    <section name="Apache Commons BCEL 6.2 (Java 7+)">
+    <section name="Apache Commons BCEL 6.3 (Java 8)">
       <subsection name="Binaries">
         <table>
           <tr>
-              <td><a href="[preferred]/commons/bcel/binaries/bcel-6.2-bin.tar.gz">bcel-6.2-bin.tar.gz</a></td>
-              <td><a href="https://www.apache.org/dist/commons/bcel/binaries/bcel-6.2-bin.tar.gz.md5">md5</a></td>
-              <td><a href="https://www.apache.org/dist/commons/bcel/binaries/bcel-6.2-bin.tar.gz.asc">pgp</a></td>
+              <td><a href="[preferred]/commons/bcel/binaries/bcel-6.3-bin.tar.gz">bcel-6.3-bin.tar.gz</a></td>
+              <td><a href="https://www.apache.org/dist/commons/bcel/binaries/bcel-6.3-bin.tar.gz.sha256">sha256</a></td>
+              <td><a href="https://www.apache.org/dist/commons/bcel/binaries/bcel-6.3-bin.tar.gz.asc">pgp</a></td>
           </tr>
           <tr>
-              <td><a href="[preferred]/commons/bcel/binaries/bcel-6.2-bin.zip">bcel-6.2-bin.zip</a></td>
-              <td><a href="https://www.apache.org/dist/commons/bcel/binaries/bcel-6.2-bin.zip.md5">md5</a></td>
-              <td><a href="https://www.apache.org/dist/commons/bcel/binaries/bcel-6.2-bin.zip.asc">pgp</a></td>
+              <td><a href="[preferred]/commons/bcel/binaries/bcel-6.3-bin.zip">bcel-6.3-bin.zip</a></td>
+              <td><a href="https://www.apache.org/dist/commons/bcel/binaries/bcel-6.3-bin.zip.sha256">sha256</a></td>
+              <td><a href="https://www.apache.org/dist/commons/bcel/binaries/bcel-6.3-bin.zip.asc">pgp</a></td>
           </tr>
         </table>
       </subsection>
       <subsection name="Source">
         <table>
           <tr>
-              <td><a href="[preferred]/commons/bcel/source/bcel-6.2-src.tar.gz">bcel-6.2-src.tar.gz</a></td>
-              <td><a href="https://www.apache.org/dist/commons/bcel/source/bcel-6.2-src.tar.gz.md5">md5</a></td>
-              <td><a href="https://www.apache.org/dist/commons/bcel/source/bcel-6.2-src.tar.gz.asc">pgp</a></td>
+              <td><a href="[preferred]/commons/bcel/source/bcel-6.3-src.tar.gz">bcel-6.3-src.tar.gz</a></td>
+              <td><a href="https://www.apache.org/dist/commons/bcel/source/bcel-6.3-src.tar.gz.sha256">sha256</a></td>
+              <td><a href="https://www.apache.org/dist/commons/bcel/source/bcel-6.3-src.tar.gz.asc">pgp</a></td>
           </tr>
           <tr>
-              <td><a href="[preferred]/commons/bcel/source/bcel-6.2-src.zip">bcel-6.2-src.zip</a></td>
-              <td><a href="https://www.apache.org/dist/commons/bcel/source/bcel-6.2-src.zip.md5">md5</a></td>
-              <td><a href="https://www.apache.org/dist/commons/bcel/source/bcel-6.2-src.zip.asc">pgp</a></td>
+              <td><a href="[preferred]/commons/bcel/source/bcel-6.3-src.zip">bcel-6.3-src.zip</a></td>
+              <td><a href="https://www.apache.org/dist/commons/bcel/source/bcel-6.3-src.zip.sha256">sha256</a></td>
+              <td><a href="https://www.apache.org/dist/commons/bcel/source/bcel-6.3-src.zip.asc">pgp</a></td>
           </tr>
         </table>
       </subsection>


=====================================
src/site/xdoc/index.xml
=====================================
@@ -61,11 +61,11 @@
 
     <section name="Documentation">
       <p>
-        The package descriptions in the <a href="javadocs/api-release/index.html">JavaDoc</a> give an overview of the available features
+        The package descriptions in the <a href="javadocs/api-release/index.html">Javadoc</a> give an overview of the available features
         and various <a href="project-reports.html">project reports</a> are provided.
       </p>
       <p>
-        The JavaDoc API documents are available online:
+        The Javadoc API documents are available online:
       </p>
       <ul>
         <li>The <a href="apidocs/index.html">current stable release</a></li>
@@ -77,11 +77,11 @@
     </section>
     <!-- ================================================== -->
     <section name="Release Information">
-      <p>The latest stable release of BCEL is 6.1. You may: </p>
+      <p>The latest stable release of BCEL is here, you may: </p>
       <ul>
-        <li>Download <a href="https://commons.apache.org/proper/commons-bcel/download_bcel.cgi">6.1</a></li>
-	<li>Read the <a href="https://www.apache.org/dist/commons/bcel/RELEASE-NOTES.txt">6.1 release notes</a></li>
-        <li>Inspect the <a href="bcel5-bcel6-clirr-report.html">extended Clirr report</a> comparing 5.2 with 6.0</li>
+        <li><a href="https://commons.apache.org/proper/commons-bcel/download_bcel.cgi">Download</a></li>
+	    <li>Read the <a href="https://www.apache.org/dist/commons/bcel/RELEASE-NOTES.txt">release notes</a></li>
+        <li>Inspect the <a href="bcel5-bcel6-clirr-report.html">extended Clirr report</a> comparing 5.2 with 6.x</li>
       </ul>
       <p>
         Alternatively you can pull it from the central Maven repositories:
@@ -89,7 +89,7 @@
 <dependency>
     <groupId>org.apache.bcel</groupId>
     <artifactId>bcel</artifactId>
-    <version>6.1</version>
+    <version>6.3</version>
 </dependency>
         </pre>
       </p>


=====================================
src/site/xdoc/issue-tracking.xml
=====================================
@@ -26,7 +26,7 @@ limitations under the License.
  | commons-build-plugin/trunk/src/main/resources/commons-xdoc-templates |
  +======================================================================+
  |                                                                      |
- | 1) Re-generate using: mvn commons:jira-page                          |
+ | 1) Re-generate using: mvn commons-build:jira-page                    |
  |                                                                      |
  | 2) Set the following properties in the component's pom:              |
  |    - commons.jira.id  (required, alphabetic, upper case)             |


=====================================
src/site/xdoc/mail-lists.xml
=====================================
@@ -26,7 +26,7 @@ limitations under the License.
  | commons-build-plugin/trunk/src/main/resources/commons-xdoc-templates |
  +======================================================================+
  |                                                                      |
- | 1) Re-generate using: mvn commons:mail-page                          |
+ | 1) Re-generate using: mvn commons-build:mail-page                    |
  |                                                                      |
  | 2) Set the following properties in the component's pom:              |
  |    - commons.componentid (required, alphabetic, lower case)          |


=====================================
src/test/java/org/apache/bcel/generic/JDKGenericDumpTestCase.java → src/test/java/org/apache/bcel/generic/JdkGenericDumpTestCase.java
=====================================
@@ -23,10 +23,20 @@ import static org.junit.Assert.fail;
 
 import java.io.File;
 import java.io.FileFilter;
+import java.io.IOException;
 import java.io.InputStream;
+import java.nio.file.FileSystems;
+import java.nio.file.FileVisitResult;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.PathMatcher;
+import java.nio.file.SimpleFileVisitor;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Enumeration;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Set;
 import java.util.jar.JarEntry;
 import java.util.jar.JarFile;
@@ -35,8 +45,12 @@ import org.apache.bcel.classfile.ClassParser;
 import org.apache.bcel.classfile.Code;
 import org.apache.bcel.classfile.JavaClass;
 import org.apache.bcel.classfile.Method;
+import org.apache.bcel.util.ModularRuntimeImage;
+import org.apache.commons.lang3.JavaVersion;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.SystemUtils;
+import org.junit.Assert;
+import org.junit.Assume;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
@@ -49,7 +63,46 @@ import com.sun.jna.platform.win32.Advapi32Util;
  * the instructions. The output bytes should be the same as the input.
  */
 @RunWith(Parameterized.class)
-public class JDKGenericDumpTestCase {
+public class JdkGenericDumpTestCase {
+
+    private static class ClassParserFilesVisitor extends SimpleFileVisitor<Path> {
+
+        private final PathMatcher matcher;
+
+        ClassParserFilesVisitor(final String pattern) {
+            matcher = FileSystems.getDefault().getPathMatcher("glob:" + pattern);
+        }
+
+        private void find(final Path path) throws IOException {
+            final Path name = path.getFileName();
+            if (name != null && matcher.matches(name)) {
+                try (final InputStream inputStream = Files.newInputStream(path)) {
+                    final ClassParser parser = new ClassParser(inputStream, name.toAbsolutePath().toString());
+                    final JavaClass jc = parser.parse();
+                    Assert.assertNotNull(jc);
+                }
+
+            }
+        }
+
+        @Override
+        public FileVisitResult preVisitDirectory(final Path dir, final BasicFileAttributes attrs) throws IOException {
+            find(dir);
+            return FileVisitResult.CONTINUE;
+        }
+
+        @Override
+        public FileVisitResult visitFile(final Path file, final BasicFileAttributes attrs) throws IOException {
+            find(file);
+            return FileVisitResult.CONTINUE;
+        }
+
+        @Override
+        public FileVisitResult visitFileFailed(final Path file, final IOException e) {
+            System.err.println(e);
+            return FileVisitResult.CONTINUE;
+        }
+    }
 
     private static final char[] hexArray = "0123456789ABCDEF".toCharArray();
 
@@ -62,7 +115,9 @@ public class JDKGenericDumpTestCase {
     private static final String KEY_JRE_9 = "SOFTWARE\\JavaSoft\\JRE";
 
     private static void addAllJavaHomesOnWindows(final String keyJre, final Set<String> javaHomes) {
-        javaHomes.addAll(findJavaHomesOnWindows(keyJre, Advapi32Util.registryGetKeys(HKEY_LOCAL_MACHINE, keyJre)));
+        if (Advapi32Util.registryKeyExists(HKEY_LOCAL_MACHINE, keyJre)) {
+            javaHomes.addAll(findJavaHomesOnWindows(keyJre, Advapi32Util.registryGetKeys(HKEY_LOCAL_MACHINE, keyJre)));
+        }
     }
 
     private static String bytesToHex(final byte[] bytes) {
@@ -97,10 +152,21 @@ public class JDKGenericDumpTestCase {
         addAllJavaHomesOnWindows(KEY_JRE_9, javaHomes);
         addAllJavaHomesOnWindows(KEY_JDK, javaHomes);
         addAllJavaHomesOnWindows(KEY_JDK_9, javaHomes);
+        addAllJavaHomes("ExtraJavaHomes", javaHomes);
         return javaHomes;
     }
 
-    private static Set<String> findJavaHomesOnWindows(final String keyJavaHome, final String[] keys) {
+    private static void addAllJavaHomes(String extraJavaHomesProp, Set<String> javaHomes) {
+		String path = System.getProperty(extraJavaHomesProp);
+		if (StringUtils.isEmpty(path)) {
+			return;
+		}
+		String[] paths = path.split(File.pathSeparator);
+		javaHomes.addAll(Arrays.asList(paths));
+		
+	}
+
+	private static Set<String> findJavaHomesOnWindows(final String keyJavaHome, final String[] keys) {
         final Set<String> javaHomes = new HashSet<>(keys.length);
         for (final String key : keys) {
             if (Advapi32Util.registryKeyExists(HKEY_LOCAL_MACHINE, keyJavaHome + "\\" + key)) {
@@ -118,7 +184,7 @@ public class JDKGenericDumpTestCase {
 
     private final String javaHome;
 
-    public JDKGenericDumpTestCase(final String javaHome) {
+    public JdkGenericDumpTestCase(final String javaHome) {
         this.javaHome = javaHome;
     }
 
@@ -144,7 +210,7 @@ public class JDKGenericDumpTestCase {
         }
     }
 
-    private File[] listJDKjars() throws Exception {
+    private File[] listJdkJars() throws Exception {
         final File javaLib = new File(javaHome, "lib");
         return javaLib.listFiles(new FileFilter() {
             @Override
@@ -154,6 +220,16 @@ public class JDKGenericDumpTestCase {
         });
     }
 
+    private File[] listJdkModules() throws Exception {
+        final File javaLib = new File(javaHome, "jmods");
+        return javaLib.listFiles(new FileFilter() {
+            @Override
+            public boolean accept(final File file) {
+                return file.getName().endsWith(".jmod");
+            }
+        });
+    }
+
     private void testJar(final File file) throws Exception {
         System.out.println(file);
         try (JarFile jar = new JarFile(file)) {
@@ -176,12 +252,35 @@ public class JDKGenericDumpTestCase {
     }
 
     @Test
-    public void testJDKjars() throws Exception {
-        final File[] jars = listJDKjars();
+    public void testJdkJars() throws Exception {
+        final File[] jars = listJdkJars();
         if (jars != null) {
             for (final File file : jars) {
                 testJar(file);
             }
         }
     }
+
+    @Test
+    public void testJdkModules() throws Exception {
+        final File[] jmods = listJdkModules();
+        if (jmods != null) {
+            for (final File file : jmods) {
+                testJar(file);
+            }
+        }
+    }
+
+    @Test
+    public void testJreModules() throws Exception {
+        Assume.assumeTrue(SystemUtils.isJavaVersionAtLeast(JavaVersion.JAVA_9));
+        try (final ModularRuntimeImage mri = new ModularRuntimeImage(javaHome)) {
+            final List<Path> modules = mri.modules();
+            Assert.assertFalse(modules.isEmpty());
+            for (final Path path : modules) {
+                Files.walkFileTree(path, new ClassParserFilesVisitor("*.class"));
+            }
+        }
+    }
+
 }


=====================================
src/test/java/org/apache/bcel/util/ClassPathTestCase.java
=====================================
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ *
+ */
+
+package org.apache.bcel.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.bcel.AbstractTestCase;
+import org.junit.Assert;
+
+public class ClassPathTestCase extends AbstractTestCase {
+
+    public void testGetClassFile() throws IOException {
+        Assert.assertNotNull(ClassPath.SYSTEM_CLASS_PATH.getClassFile("java.lang.String"));
+    }
+
+    public void testGetResource() throws IOException {
+        Assert.assertNotNull(ClassPath.SYSTEM_CLASS_PATH.getResource("java/lang/String.class"));
+    }
+
+    public void testGetResourceAsStream() throws IOException {
+        try (final InputStream inputStream = ClassPath.SYSTEM_CLASS_PATH
+                .getResourceAsStream("java/lang/String.class")) {
+            Assert.assertNotNull(inputStream);
+        }
+    }
+}
\ No newline at end of file


=====================================
src/test/java/org/apache/bcel/util/ModularRuntimeImageTestCase.java
=====================================
@@ -0,0 +1,84 @@
+/*
+ * 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.
+ *
+ */
+
+package org.apache.bcel.util;
+
+import java.io.IOException;
+import java.nio.file.Path;
+import java.util.Collection;
+import java.util.List;
+
+import org.apache.bcel.generic.JdkGenericDumpTestCase;
+import org.apache.commons.lang3.JavaVersion;
+import org.apache.commons.lang3.SystemUtils;
+import org.junit.Assert;
+import org.junit.Assume;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+/**
+ * Tests {@link ModularRuntimeImage}.
+ */
+ at RunWith(Parameterized.class)
+public class ModularRuntimeImageTestCase {
+
+    @Parameters(name = "{0}")
+    public static Collection<String> data() {
+        return JdkGenericDumpTestCase.data();
+    }
+
+    private final String javaHome;
+    private final ModularRuntimeImage modularRuntimeImage;
+
+    public ModularRuntimeImageTestCase(final String javaHome) throws IOException {
+        this.javaHome = javaHome;
+        Assume.assumeTrue(SystemUtils.isJavaVersionAtLeast(JavaVersion.JAVA_9));
+        this.modularRuntimeImage = new ModularRuntimeImage(javaHome);
+    }
+
+    @Test
+    public void testListJreModules() throws IOException {
+        final List<Path> listEntries = modularRuntimeImage.list(ModularRuntimeImage.MODULES_PATH);
+        Assert.assertFalse(listEntries.isEmpty());
+        Assert.assertTrue(listEntries.toString().indexOf("/java.base") > -1);
+    }
+
+    @Test
+    public void testListJreModule() throws IOException {
+        final List<Path> listEntries = modularRuntimeImage.list(ModularRuntimeImage.MODULES_PATH + "/java.base");
+        Assert.assertFalse(listEntries.isEmpty());
+        Assert.assertTrue(listEntries.toString().indexOf("/java.base") > -1);
+    }
+
+    @Test
+    public void testListJreModulePackageDir() throws IOException {
+        final List<Path> listEntries = modularRuntimeImage
+                .list(ModularRuntimeImage.MODULES_PATH + "/java.base/java/lang");
+        Assert.assertFalse(listEntries.isEmpty());
+        Assert.assertTrue(listEntries.toString().indexOf("/java.base/java/lang/String.class") > -1);
+    }
+
+    @Test
+    public void testListJrePackages() throws IOException {
+        final List<Path> listEntries = modularRuntimeImage.list(ModularRuntimeImage.PACKAGES_PATH);
+        Assert.assertFalse(listEntries.isEmpty());
+        Assert.assertTrue(listEntries.toString().indexOf("java.lang") > -1);
+    }
+}


=====================================
src/test/java/org/apache/bcel/visitors/CounterVisitor.java
=====================================
@@ -26,6 +26,7 @@ import org.apache.bcel.classfile.Code;
 import org.apache.bcel.classfile.CodeException;
 import org.apache.bcel.classfile.ConstantClass;
 import org.apache.bcel.classfile.ConstantDouble;
+import org.apache.bcel.classfile.ConstantDynamic;
 import org.apache.bcel.classfile.ConstantFieldref;
 import org.apache.bcel.classfile.ConstantFloat;
 import org.apache.bcel.classfile.ConstantInteger;
@@ -159,6 +160,9 @@ public class CounterVisitor implements Visitor
 
     /** @since 6.1 */
     public int constantPackageCount = 0;
+
+    /** @since 6.3 */
+    public int constantDynamicCount = 0;
     // CHECKSTYLE:ON
 
 
@@ -440,4 +444,10 @@ public class CounterVisitor implements Visitor
     public void visitConstantModule(final ConstantModule constantModule) {
         constantModuleCount++;
     }
+
+    /** @since 6.3 */
+    @Override
+    public void visitConstantDynamic(final ConstantDynamic constantDynamic) {
+        constantDynamicCount++;
+    }
 }



View it on GitLab: https://salsa.debian.org/java-team/bcel/commit/de1bac8612f2347fb127df3240b2376b9885ad59

-- 
View it on GitLab: https://salsa.debian.org/java-team/bcel/commit/de1bac8612f2347fb127df3240b2376b9885ad59
You're receiving this email because of your account on salsa.debian.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-java-commits/attachments/20190719/bf3b41dc/attachment.html>


More information about the pkg-java-commits mailing list