@@ -116,8 +116,7 @@ public static String getClasspath() {
116
116
sb .append (url .toString ()).append (File .pathSeparator );
117
117
}
118
118
119
- classpath = sb .toString ();
120
-
119
+ classpath = fixClasspath (sb .toString ());
121
120
}
122
121
return classpath ;
123
122
}
@@ -132,14 +131,17 @@ private <T> Class<? extends T> compile0(Class<T> superClass, String source) {
132
131
final List <JavaFileObject > compilationUnits = Collections .singletonList (new SourceFile (toUri ("Generated" ), source ));
133
132
final FileManager fileManager = new FileManager (standardJavaFileManager );
134
133
final StringWriter output = new StringWriter ();
135
- final JavaCompiler .CompilationTask task = compiler .getTask (output , fileManager , diagnostics , Arrays .asList ("-g" , "-proc:none" , "-classpath" , getClasspath ()), null , compilationUnits );
134
+ final String localClasspath = getClasspath ();
135
+ final JavaCompiler .CompilationTask task = compiler .getTask (output , fileManager , diagnostics , Arrays .asList ("-g" , "-verbose" , "-proc:none" , "-classpath" , localClasspath ), null , compilationUnits );
136
136
137
137
if (!task .call ()) {
138
138
log .error ("Compilation diagnostics:" );
139
139
for (Diagnostic <? extends JavaFileObject > diag : diagnostics .getDiagnostics ()) {
140
140
log .error (diag .getMessage (Locale .getDefault ()));
141
141
}
142
142
143
+ log .error ("Full classpath: {}" , localClasspath );
144
+
143
145
throw new IllegalArgumentException ("Compilation failed:\n " + output + "\n Source code: \n " + source );
144
146
}
145
147
@@ -152,6 +154,48 @@ private <T> Class<? extends T> compile0(Class<T> superClass, String source) {
152
154
throw new IllegalArgumentException ("Compilation yielded an unexpected number of classes: " + classCount );
153
155
}
154
156
157
+ /**
158
+ * Cleans a raw classpath string by:
159
+ * 1. Removing any leading/trailing single quotes.
160
+ * 2. Stripping out “jar:file:///” and “file:/” URI prefixes.
161
+ * 3. Removing “!/” suffixes from JAR‐in‐WAR entries.
162
+ * 4. Eliminating any literal newline characters.
163
+ *
164
+ * After this, each entry is a plain filesystem path, separated by File.pathSeparator.
165
+ *
166
+ * @param rawClasspath the unprocessed classpath (e.g. containing "jar:file://…!/:" or "file:/…" fragments)
167
+ * @return a cleaned classpath suitable for passing to JavaCompiler or ClassLoader
168
+ */
169
+ public static String fixClasspath (String rawClasspath ) {
170
+ if (rawClasspath == null ) {
171
+ return null ;
172
+ }
173
+
174
+ String cp = rawClasspath ;
175
+
176
+ // Remove any newline or carriage‐return characters
177
+ // (we only want one long line with proper path separators)
178
+ cp = cp .replaceAll ("[\\ r\\ n]" , "" );
179
+
180
+ // Remove “!/jar:file://”
181
+ cp = cp .replaceAll ("!/:jar" , "" );
182
+ cp = cp .replaceAll (":jar:" , ":" );
183
+
184
+ // Remove “file:/” prefixes
185
+ // This turns "file:/opt/jetty/…" into "/opt/jetty/…"
186
+ cp = cp .replaceAll ("file:/+" , "/" );
187
+
188
+ // If there are any accidental duplicate path‐separators,
189
+ // collapse them. For Unix/Linux, File.pathSeparator is ":"
190
+ String sep = File .pathSeparator ;
191
+ String doubleSep = sep + sep ;
192
+ while (cp .contains (doubleSep )) {
193
+ cp = cp .replace (doubleSep , sep );
194
+ }
195
+
196
+ return cp ;
197
+ }
198
+
155
199
/**
156
200
* Represents a source file whose contents is loaded from a String
157
201
*/
0 commit comments