66 * The Java Pathfinder core (jpf-core) platform is licensed under the
77 * Apache License, Version 2.0 (the "License"); you may not use this file except
88 * in compliance with the License. You may obtain a copy of the License at
9- *
10- * http://www.apache.org/licenses/LICENSE-2.0.
9+ *
10+ * http://www.apache.org/licenses/LICENSE-2.0.
1111 *
1212 * Unless required by applicable law or agreed to in writing, software
1313 * distributed under the License is distributed on an "AS IS" BASIS,
1414 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15- * See the License for the specific language governing permissions and
15+ * See the License for the specific language governing permissions and
1616 * limitations under the License.
1717 */
1818package gov .nasa .jpf .jvm ;
@@ -119,29 +119,57 @@ protected void addSystemBootClassPath () {
119119 }
120120
121121 /**
122- * this is the main method to create the ClassPath, which is called from the ctor
122+ * This is the main method to create the ClassPath, which is called from the ctor.
123+ *
124+ * Search order (first match wins):
125+ * 1. Extension boot classpaths (any *.boot_classpath property except vm.boot_classpath)
126+ * - This allows extensions to override jpf-core model classes
127+ * 2. Explicit classpath entries (from 'classpath' property)
128+ * 3. jpf-core's vm.boot_classpath
129+ * 4. JRE runtime classes (handled by JRTClassFileContainer in getMatch)
123130 */
124131 @ Override
125132 protected void initializeSystemClassPath (VM vm , int appId ) {
126133 Config conf = vm .getConfig ();
127134 File [] pathElements ;
128135
129- // explicit "classpath[.id]" settings have precedence
136+ // First, load ALL extension boot classpaths (any property ending in .boot_classpath)
137+ // This allows extensions to override jpf-core model classes
138+ for (Object keyObj : conf .keySet ()) {
139+ String key = keyObj .toString ();
140+ if (key .endsWith (".boot_classpath" ) && !key .equals ("vm.boot_classpath" )) {
141+ String [] bootPaths = conf .getStringArray (key );
142+ if (bootPaths != null ) {
143+ for (String bp : bootPaths ) {
144+ bp = bp .trim ();
145+ if (bp .length () > 0 && !bp .equals ("<system>" ) && !bp .equals ("<s>" )) {
146+ File f = new File (bp );
147+ if (f .exists ()) {
148+ addClassPathElement (f .getAbsolutePath ());
149+ log .info ("added extension boot classpath (" , key , "): " , f .getAbsolutePath ());
150+ }
151+ }
152+ }
153+ }
154+ }
155+ }
156+
157+ // explicit "classpath[.id]" settings
130158 pathElements = getPathElements (conf , "classpath" , appId );
131159 if (pathElements != null ) {
132160 for (File f : pathElements ) {
133161 addClassPathElement (f .getAbsolutePath ());
134162 }
135163 }
136164
137- // we optionally append boot_classpath
165+ // we optionally append vm. boot_classpath (jpf-core's boot classpath)
138166 pathElements = getPathElements (conf , "vm.boot_classpath" , appId );
139167 if (pathElements != null ) {
140168 for (File f : pathElements ) {
141- if (f .getName ().equals ("<system>" )) {
169+ if (f .getName ().equals ("<system>" ) || f . getName (). equals ( "<s>" ) ) {
142170 addSystemBootClassPath ();
143171 } else {
144- addClassPathElement ( f .getAbsolutePath ());
172+ addClassPathElement (f .getAbsolutePath ());
145173 }
146174 }
147175 }
@@ -165,14 +193,14 @@ protected JVMCodeBuilder getSystemCodeBuilder (ClassFile cf, MethodInfo mi) {
165193 defaultCodeBuilder .reset (cf , mi );
166194 return defaultCodeBuilder ;
167195 }
168-
196+
169197 @ Override
170198 protected ClassInfo createClassInfo (String clsName , String url , byte [] data , ClassLoaderInfo definingLoader ) throws ClassParseException {
171199 ClassFile cf = new ClassFile (data );
172200 JVMCodeBuilder cb = getCodeBuilder (clsName );
173201 ClassInfo ci = new JVMClassInfo (clsName , definingLoader , cf , url , cb );
174202 setAttributes (ci );
175-
203+
176204 return ci ;
177205 }
178206}
0 commit comments