*/
private void compileJava(String className, final String source, Set<String> extraClassPath) throws IOException {
if (LOG.isTraceEnabled())
LOG.trace("Compiling [#0], source: [#1]", className, source);
JavaCompiler compiler =
ToolProvider.getSystemJavaCompiler();
DiagnosticCollector<JavaFileObject> diagnostics =
new DiagnosticCollector<JavaFileObject>();
//the generated bytecode is fed to the class loader
JavaFileManager jfm = new
ForwardingJavaFileManager<StandardJavaFileManager>(
compiler.getStandardFileManager(diagnostics, null, null)) {
@Override
public JavaFileObject getJavaFileForOutput(Location location,
String name,
JavaFileObject.Kind kind,
FileObject sibling) throws IOException {
MemoryJavaFileObject fileObject = new MemoryJavaFileObject(name, kind);
classLoader.addMemoryJavaFileObject(name, fileObject);
return fileObject;
}
};
//read java source code from memory
String fileName = className.replace('.', '/') + ".java";
SimpleJavaFileObject sourceCodeObject = new SimpleJavaFileObject(toURI(fileName), JavaFileObject.Kind.SOURCE) {
@Override
public CharSequence getCharContent(boolean
ignoreEncodingErrors)
throws IOException, IllegalStateException,
UnsupportedOperationException {
return source;
}
};
//build classpath
//some entries will be added multiple times, hence the set
List<String> optionList = new ArrayList<String>();
Set<String> classPath = new HashSet<String>();
FileManager fileManager = ServletActionContext.getContext().getInstance(FileManagerFactory.class).getFileManager();
//find available jars
ClassLoaderInterface classLoaderInterface = getClassLoaderInterface();
UrlSet urlSet = new UrlSet(classLoaderInterface);
//find jars
List<URL> urls = urlSet.getUrls();
for (URL url : urls) {
URL normalizedUrl = fileManager.normalizeToFileProtocol(url);
File file = FileUtils.toFile(ObjectUtils.defaultIfNull(normalizedUrl, url));
if (file.exists())
classPath.add(file.getAbsolutePath());
}
//these should be in the list already, but I am feeling paranoid
//this jar
classPath.add(getJarUrl(EmbeddedJSPResult.class));
//servlet api
classPath.add(getJarUrl(Servlet.class));
//jsp api
classPath.add(getJarUrl(JspPage.class));
try {
Class annotationsProcessor = Class.forName("org.apache.AnnotationProcessor");
classPath.add(getJarUrl(annotationsProcessor));
} catch (ClassNotFoundException e) {
//ok ignore
}
//add extra classpath entries (jars where tlds were found will be here)
for (Iterator<String> iterator = extraClassPath.iterator(); iterator.hasNext();) {
String entry = iterator.next();
classPath.add(entry);
}
String classPathString = StringUtils.join(classPath, File.pathSeparator);
if (LOG.isDebugEnabled()) {
LOG.debug("Compiling [#0] with classpath [#1]", className, classPathString);
}
optionList.addAll(Arrays.asList("-classpath", classPathString));
//compile
JavaCompiler.CompilationTask task = compiler.getTask(
null, jfm, diagnostics, optionList, null,
Arrays.asList(sourceCodeObject));
if (!task.call()) {
throw new StrutsException("Compilation failed:" + diagnostics.getDiagnostics().get(0).toString());