All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.leonard.maven.plugins.jspc.JspcMojo Maven / Gradle / Ivy

//========================================================================
//$Id: JspcMojo.java 6430 2011-03-15 17:52:17Z joakime $
//Copyright 2006 Mort Bay Consulting Pty. Ltd.
//------------------------------------------------------------------------
//Licensed 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 io.leonard.maven.plugins.jspc;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.logging.Handler;
import java.util.logging.LogManager;
import java.util.logging.Logger;
import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;
import org.apache.jasper.JasperException;
import org.apache.jasper.JspC;
import org.apache.jasper.TrimSpacesOption;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.plugins.annotations.ResolutionScope;
import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.util.DirectoryScanner;
import org.codehaus.plexus.util.StringUtils;
import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer;
import org.slf4j.bridge.SLF4JBridgeHandler;
import org.xml.sax.SAXException;

/**
 * 

* This goal will compile jsps for a webapp so that they can be included in a * war. *

*

* It is a fork of jetty-jspc-maven-plugin * but has the following improvements: *

*
    *
  • Faster: ability of multi-threading see threads parameter
  • *
  • Not stop at the first error : see stopAtFirstError parameter
  • *
*

* The compiler used in this plugin the Apache Jasper 9.0.12 but it can be * overloaded. *

* * @author Leonard Ehrenfried * @description Runs jspc compiler to produce .java and .class files */ @Mojo(name = "compile", defaultPhase = LifecyclePhase.PROCESS_CLASSES, requiresDependencyResolution = ResolutionScope.COMPILE, threadSafe = true) public class JspcMojo extends AbstractMojo { private static final String WEB_XML = "web.xml"; public static final String END_OF_WEBAPP = ""; /** * The maven project. */ @Parameter(defaultValue = "${project}", readonly = true, required = true) private MavenProject project; /** * File into which to generate the <servlet> and <servlet-mapping> * tags for the compiled jsps.
*

* If multithreading mode is active (threads > 1), then this filename will be * suffixed by ".threadIndex" (example : webfrag.xml.3). */ @Parameter(defaultValue = "${basedir}/target/webfrag.xml") private String webXmlFragment; /** * Optional. A marker string in the src web.xml file which indicates where to * merge in the generated web.xml fragment. Note that the marker string will NOT * be preserved during the insertion. Can be left blank, in which case the * generated fragment is inserted just before the </web-app> line */ @Parameter private String insertionMarker; /** * Merge the generated fragment file with the web.xml from * webAppSourceDirectory. The merged file will go into the same directory as the * webXmlFragment. */ @Parameter(defaultValue = "true") private boolean mergeFragment; /** * The destination directory into which to put the compiled jsps. */ @Parameter(defaultValue = "${project.build.outputDirectory}") private String generatedClasses; /** * Controls whether or not .java files generated during compilation will be * preserved. */ @Parameter(defaultValue = "false") private boolean keepSources; /** * Default root package for all generated classes */ @Parameter(defaultValue = "jsp") private String packageRoot; /** * Root directory for all html/jsp etc files */ @Parameter(defaultValue = "${basedir}/src/main/webapp") private String webAppSourceDirectory; /** * Location of web.xml. Defaults to src/main/webapp/web.xml. */ @Parameter(defaultValue = "${basedir}/src/main/webapp/WEB-INF/web.xml") private String webXml; /** * The comma separated list of patterns for file extensions to be processed. By * default will include all .jsp and .jspx files. */ @Parameter(defaultValue = "**\\/*.jsp, **\\/*.jspx, **\\/*.jspf") private String[] includes; /** * The comma separated list of file name patters to exclude from compilation. */ @Parameter(defaultValue = "**\\/.svn\\/**") private String[] excludes; /** * The location of the compiled classes for the webapp */ @Parameter(defaultValue = "${project.build.outputDirectory}") private File classesDirectory; /** * Whether or not to output more verbose messages during compilation. */ @Parameter(defaultValue = "false") private boolean verbose; /** * If true, validates tlds when parsing. */ @Parameter(defaultValue = "false") private boolean validateXml; /** * If true, validates web.xml file (xml format) * after beeing merge if mergeFragment parameter is true */ @Parameter(defaultValue = "true") private boolean validateWebXmlAfterMerge; /** * If true, validates web.xml file (xsd see webXmlXsdSchema parameter) * after beeing merge if mergeFragment parameter is true */ @Parameter(defaultValue = "false") private boolean validateWebXmlWithXsdAfterMerge; /** * The link to xsd schema to validate web xml file after merging, if * mergeFragment parameter is true. */ @Parameter(defaultValue = "http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd") private String webXmlXsdSchema; /** * Optionnal hostname of http proxy (use when validating dtd/xsd with external URL) */ @Parameter private String httpProxyHost; /** * Optionnal port of http proxy (use when validating dtd/xsd with external URL) */ @Parameter private String httpProxyPort; /** * Optionnal no proxy hosts (use when validating dtd/xsd with external URL)
* A list of hosts that should be reached directly, bypassing the proxy.
* This is a list of patterns separated by '|'.
* The patterns may start or end with a '*' for wildcards.
* Any host matching one of these patterns will be reached through a direct connection instead of through a proxy.
* See https://docs.oracle.com/javase/8/docs/technotes/guides/net/proxies.html */ @Parameter private String httpNoProxyHosts; private boolean proxyEnvSet; private String httpProxyHostBackup; private String httpProxyPortBackup; private String httpNoProxyHostsBackup; /** * The encoding scheme to use. */ @Parameter(defaultValue = "UTF-8") private String javaEncoding; /** * Whether or not to generate JSR45 compliant debug info */ @Parameter(defaultValue = "true") private boolean suppressSmap; /** * Whether or not to ignore precompilation errors caused by jsp fragments. */ @Parameter(defaultValue = "false") private boolean ignoreJspFragmentErrors; /** * Fail the build and stop at the first jspc error. If set to "false", all jsp * will be compiled even if they raise errors, and all errors will be listed * when they raise. In this case the build will fail too. In case of threads > 1 * and stopAtFirstError=true, each thread can have is own first error. */ @Parameter(defaultValue = "true") private boolean stopAtFirstError; /** * The number of threads will be used for compile all of the jsps. Number total * of jsps will be divided by thread number. Each part will be given to * differents thread. */ @Parameter(defaultValue = "1") private int threads; /** * Whether Jsp Tag Pooling should be enabled. */ @Parameter(defaultValue = "true") private boolean enableJspTagPooling; /** * Should white spaces in template text between actions or directives be * trimmed? */ @Parameter(defaultValue = "false") private String trimSpaces; /** * Should text strings be generated as char arrays, to improve performance in * some cases? */ @Parameter(defaultValue = "false") private boolean genStringAsCharArray; /** * Version of Java used to compile the jsp files. */ @Parameter(defaultValue = "1.8") private String compilerVersion; /** * Name of the compiler class used to compile the jsp files. If threads * parameter is greater than 2, then maybe the compilerClass * "org.apache.jasper.compiler.ParallelJDTCompiler" will be more efficient */ @Parameter(defaultValue = "org.apache.jasper.compiler.JDTCompiler") private String compilerClass; /** * When scriptlet expressions are used for attribute values, should the rules in JSP.1.6 * for the escaping of quote characters be strictly applied? Default [true] */ @Parameter(defaultValue = "true") private boolean strictQuoteEscaping; /** * Set this to 'true' to bypass compilation of JSP sources. */ @Parameter(defaultValue = "false", property = "jspc.skip") private boolean skip; /** * The comma separated list of JAR file name patterns to skip when scanning for tag libraries (TLDs). * See {@link org.apache.tomcat.util.scan.StandardJarScanFilter StandardJarScanFilter}. * * @see Standard implementation * */ @Parameter private String tldSkip; /** * The comma separated list of JAR file name patterns to scan when scanning for tag libraries (TLDs). * See {@link org.apache.tomcat.util.scan.StandardJarScanFilter StandardJarScanFilter}. * * @see Standard implementation * */ @Parameter private String tldScan; /** * Controls if JARs are scanned or skipped by default when scanning for TLDs. * See {@link org.apache.tomcat.util.scan.StandardJarScanFilter StandardJarScanFilter}. * * @see Standard implementation * */ @Parameter private Boolean defaultTldScan; private Map resourcesCache = new ConcurrentHashMap<>(); private Handler[] handlers; @Override public void execute() throws MojoExecutionException, MojoFailureException { if (getLog().isDebugEnabled()) { getLog().info("verbose=" + verbose); getLog().info("webAppSourceDirectory=" + webAppSourceDirectory); getLog().info("generatedClasses=" + generatedClasses); getLog().info("webXmlFragment=" + webXmlFragment); getLog().info("webXml=" + webXml); getLog().info("validateXml=" + validateXml); getLog().info("packageRoot=" + packageRoot); getLog().info("javaEncoding=" + javaEncoding); getLog().info("insertionMarker=" + (insertionMarker == null || insertionMarker.equals("") ? END_OF_WEBAPP : insertionMarker)); getLog().info("keepSources=" + keepSources); getLog().info("mergeFragment=" + mergeFragment); getLog().info("suppressSmap=" + suppressSmap); getLog().info("ignoreJspFragmentErrors=" + ignoreJspFragmentErrors); getLog().info("webXmlXsdSchema=" + webXmlXsdSchema); getLog().info("stopAtFirstError=" + stopAtFirstError); getLog().info("threads=" + threads); getLog().info("enableJspTagPooling=" + enableJspTagPooling); getLog().info("trimSpaces=" + trimSpaces); getLog().info("genStringAsCharArray=" + genStringAsCharArray); getLog().info("compilerVersion=" + compilerVersion); getLog().info("compilerClass=" + compilerClass); getLog().info("strictQuoteEscaping=" + strictQuoteEscaping); getLog().info("skip=" + skip); } if ( skip ) { getLog().info( "Not compiling jsp sources" ); return; } try { long start = System.currentTimeMillis(); installLogHandler(); prepare(); compile(); cleanupSrcs(); mergeWebXml(); long finish = System.currentTimeMillis(); long millis = finish - start; String time = String.format("%d min, %d sec", TimeUnit.MILLISECONDS.toMinutes(millis), TimeUnit.MILLISECONDS.toSeconds(millis) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis))); getLog().info("Compilation completed in " + time); } catch (Exception e) { throw new MojoExecutionException("Failure processing jsps", e); } finally { uninstallLogHandler(); } } public void compile() throws IOException, InterruptedException, MojoExecutionException, ExecutionException, JasperException { ClassLoader currentClassLoader = Thread.currentThread().getContextClassLoader(); ArrayList urls = new ArrayList(); setUpClassPath(urls); URLClassLoader ucl = new URLClassLoader(urls.toArray(new URL[0]), currentClassLoader); StringBuilder classpathStr = new StringBuilder(); for (int i = 0; i < urls.size(); i++) { if (getLog().isDebugEnabled()) { getLog().debug("webappclassloader contains: " + urls.get(i)); } classpathStr.append(urls.get(i).getFile()); if (getLog().isDebugEnabled()) { getLog().debug("added to classpath: " + urls.get(i).getFile()); } classpathStr.append(System.getProperty("path.separator")); } Thread.currentThread().setContextClassLoader(ucl); String[] jspFiles = getJspFiles(webAppSourceDirectory); if (verbose) { getLog().info("Files selected to precompile: " + StringUtils.join(jspFiles, ", ")); } ExecutorService executor = Executors.newFixedThreadPool(threads); List> results = executor.invokeAll(initJspcWorkers(classpathStr, jspFiles, initJspList(jspFiles))); executor.shutdown(); getLog().info("Number total of jsps : " + jspFiles.length); manageResults(results); Thread.currentThread().setContextClassLoader(currentClassLoader); } private List initJspList(String[] jspFiles) { List jspFilesList = new ArrayList<>(); Collections.addAll(jspFilesList, jspFiles); return jspFilesList; } private List initJspcWorkers(StringBuilder classpathStr, String[] jspFiles, List jspFilesList) throws JasperException, IOException { List workers = new ArrayList<>(); int minItem = jspFiles.length / threads; int maxItem = minItem + 1; int threadsWithMaxItems = jspFiles.length - threads * minItem; int start = 0; JspCContextAccessor topJspC = initJspc(classpathStr, -1, null); for (int index = 0; index < threads; index++) { int threadNumber = index + 1; int itemsCount = (index < threadsWithMaxItems ? maxItem : minItem); int end = start + itemsCount; List jspFilesSubList = jspFilesList.subList(start, end); if (jspFilesSubList.isEmpty()) { getLog().info("Thread " + threadNumber + " have nothing to do, skip it"); } else { JspC firstJspC = initJspc(classpathStr, index, topJspC); JspcWorker worker = new JspcWorker(firstJspC, jspFilesSubList); workers.add(worker); start = end; getLog().info("Number of jsps for thread " + threadNumber + " : " + jspFilesSubList.size()); } } return workers; } private JspCContextAccessor initJspc(StringBuilder classpathStr, int threadIndex, JspCContextAccessor topJspC) throws IOException, JasperException { JspCContextAccessor jspc = new JspCContextAccessor(); jspc.setWebXmlInclude(getwebXmlFragmentFilename(threadIndex)); jspc.setUriroot(webAppSourceDirectory); jspc.setPackage(packageRoot); jspc.setOutputDir(generatedClasses); jspc.setValidateXml(validateXml); jspc.setClassPath(classpathStr.toString()); jspc.setCompile(true); jspc.setSmapSuppressed(suppressSmap); jspc.setSmapDumped(!suppressSmap); jspc.setJavaEncoding(javaEncoding); jspc.setFailOnError(stopAtFirstError); jspc.setPoolingEnabled(enableJspTagPooling); jspc.setTrimSpaces(TrimSpacesOption.valueOf(trimSpaces.toUpperCase())); jspc.setGenStringAsCharArray(genStringAsCharArray); jspc.setCompilerSourceVM(compilerVersion); jspc.setCompilerTargetVM(compilerVersion); jspc.setcompilerClass(compilerClass); jspc.setResourcesCache(resourcesCache); jspc.setStrictQuoteEscaping(strictQuoteEscaping); jspc.setTldSkip(tldSkip); jspc.setTldScan(tldScan); jspc.setDefaultTldScan(defaultTldScan); if (topJspC == null) { jspc.initClassLoader(); jspc.initServletContext(); } else { jspc.initContext(topJspC); } // JspC#setExtensions() does not exist, so // always set concrete list of files that will be processed. if (topJspC != null) { getLog().info("Includes=" + StringUtils.join(includes, ",")); if (excludes != null) { getLog().info("Excludes=" + StringUtils.join(excludes, ",")); } } if (verbose) { jspc.setVerbose(99); } else { jspc.setVerbose(0); } // force jspc Thread Count to 1 to avoid parallelism because it has already done // in this plugin jspc.setThreadCount("1"); return jspc; } private void manageResults(List> results) throws InterruptedException, ExecutionException, MojoExecutionException { boolean failTheBuild = false; for (Future result : results) { if (result.get() != null) { getLog().error(result.get()); failTheBuild = true; } } if (failTheBuild) { throw new MojoExecutionException("see previous errors"); } } private String[] getJspFiles(String webAppSrcDir) { DirectoryScanner scanner = new DirectoryScanner(); scanner.setBasedir(new File(webAppSrcDir)); if ((excludes != null) && (excludes.length != 0)) { scanner.setExcludes(excludes); } scanner.addDefaultExcludes(); scanner.setIncludes(includes); scanner.setCaseSensitive(false); scanner.scan(); String[] includedFiles = scanner.getIncludedFiles(); getLog() .debug(String.format("Included files returned from directory scan: %s", StringUtils.join(includedFiles, ","))); getLog().debug(String.format("Excluded files returned from directory scan: %s", StringUtils.join(scanner.getExcludedFiles(), ","))); getLog().debug(String.format("Excluded directories returned from directory scan: %s", StringUtils.join(scanner.getExcludedDirectories(), ","))); return includedFiles; } /** * Until Jasper supports the option to generate the srcs in a different dir than * the classes, this is the best we can do. */ public void cleanupSrcs() { // delete the .java files - depending on keepGenerated setting if (!keepSources) { File generatedClassesDir = new File(generatedClasses); if (generatedClassesDir.exists() && generatedClassesDir.isDirectory()) { delete(generatedClassesDir, f -> f.isDirectory() || f.getName().endsWith(".java")); } } } static void delete(File dir, FileFilter filter) { File[] files = dir.listFiles(filter); for (int i = 0; i < files.length; i++) { File f = files[i]; if (f.isDirectory()) { delete(f, filter); } else { f.delete(); } } } /** * Take the web fragment (for each thread if we active multithreading mode) and * put it inside a copy of the web.xml. *

* You can specify the insertion point by specifying the string in the * insertionMarker configuration entry. *

* If you dont specify the insertionMarker, then the fragment will be inserted * at the end of the file just before the </webapp> * * @throws IOException maybe thrown during writing mergedXml file * @throws MojoExecutionException maybe thrown when validating mergedXml file */ public void mergeWebXml() throws IOException, MojoExecutionException { if (mergeFragment) { // open the src web.xml File webXmlFile = getWebXmlFile(); if (!webXmlFile.exists()) { getLog().info(webXmlFile.toString() + " does not exist, cannot merge with generated fragment"); return; } File mergedWebXml = new File(new File(getwebXmlFragmentFilename(0)).getParentFile(), WEB_XML); Path mergedWebXmlPath = createAndGetMergeWebXml(mergedWebXml); try (BufferedReader webXmlReader = new BufferedReader( new InputStreamReader(new FileInputStream(webXmlFile), StandardCharsets.UTF_8))) { writeWebXmlMergedFile(webXmlReader, mergedWebXmlPath); } if (validateWebXmlAfterMerge) { validateXmlContent(mergedWebXml); } if (validateWebXmlWithXsdAfterMerge) { validateWithXsd(mergedWebXml); } } } private Path createAndGetMergeWebXml(File mergedWebXml) throws IOException { Path mergedWebXmlPath = Paths.get(mergedWebXml.toURI()); Files.deleteIfExists(mergedWebXmlPath); Files.createFile(mergedWebXmlPath); return mergedWebXmlPath; } private void validateXmlContent(File mergedWebXml) throws IOException, MojoExecutionException { try { setHttpProxyIfNecessary(); DocumentBuilder parser = DocumentBuilderFactory.newInstance().newDocumentBuilder(); parser.parse(mergedWebXml); } catch (ParserConfigurationException e) { getLog().debug("Unable to instanciate Document Builder, so web.xml merged validation is not possible", e); } catch (SAXException e) { throw new MojoExecutionException("Error when validating XML content of merged web.xml !", e); } finally { restoreHttpProxy(); } } private void validateWithXsd(File mergedWebXml) throws IOException, MojoExecutionException { try { setHttpProxyIfNecessary(); Source webXmlSource = new StreamSource(mergedWebXml); SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); Schema webXmlSchema = schemaFactory.newSchema(getWebXmlSchema()); Validator validator = webXmlSchema.newValidator(); validator.validate(webXmlSource); } catch (SAXException e) { throw new MojoExecutionException("Error when validating with XSD merged web.xml !", e); } finally { restoreHttpProxy(); } } private void setHttpProxyIfNecessary() { if (!proxyEnvSet && httpProxyHost != null && !httpProxyHost.isEmpty()) { proxyEnvSet = true; httpProxyHostBackup = System.getProperty("http.proxyHost"); System.setProperty("http.proxyHost", httpProxyHost); httpProxyPortBackup = System.getProperty("http.proxyPort"); System.setProperty("http.proxyPort", httpProxyPort); if (httpNoProxyHosts != null && !httpNoProxyHosts.isEmpty()) { httpNoProxyHostsBackup = System.getProperty("http.nonProxyHosts"); System.setProperty("http.nonProxyHosts", httpNoProxyHosts); } } } private void restoreHttpProxy() { if (proxyEnvSet) { System.setProperty("http.proxyHost", httpProxyHostBackup != null ? httpProxyHostBackup : ""); System.setProperty("http.proxyPort", httpProxyPortBackup != null ? httpProxyPortBackup : ""); if (httpNoProxyHosts != null && !httpNoProxyHosts.isEmpty()) { System.setProperty("http.nonProxyHosts", httpNoProxyHostsBackup != null ? httpNoProxyHostsBackup : ""); } proxyEnvSet = false; } } private StreamSource[] getWebXmlSchema() throws MalformedURLException { URL webXmlXsdUrl = new URL(webXmlXsdSchema); return new StreamSource[] {new StreamSource(webXmlXsdUrl.toExternalForm())}; } private String writeWebXmlMergedFile(BufferedReader webXmlReader, Path mergedWebXmlPath) throws IOException { // read up to the insertion marker or the if there is no marker String marker = (insertionMarker == null || insertionMarker.equals("") ? END_OF_WEBAPP : insertionMarker); String line = ""; while ((line = webXmlReader.readLine()) != null) { if (line.indexOf(marker) >= 0) { writeXmlFragments(mergedWebXmlPath); writeEndOfWebappIfNecessary(mergedWebXmlPath, marker); } else { Files.write(mergedWebXmlPath, (line + System.lineSeparator()).getBytes(StandardCharsets.UTF_8), StandardOpenOption.APPEND); } } return marker; } private void writeEndOfWebappIfNecessary(Path mergedWebXmlPath, String marker) throws IOException { if (marker.equals(END_OF_WEBAPP)) { Files.write(mergedWebXmlPath, END_OF_WEBAPP.getBytes(StandardCharsets.UTF_8), StandardOpenOption.APPEND); } } private void writeXmlFragments(Path mergedWebXmlPath) throws IOException { for (int index = 0; index < threads; index++) { File fragmentWebXml = new File(getwebXmlFragmentFilename(index)); if (!fragmentWebXml.exists()) { getLog().info("No fragment web.xml file generated for thread " + index); } else { // put in the generated fragment for the current thread Files.write(mergedWebXmlPath, Files.readAllBytes(Paths.get(fragmentWebXml.toURI())), StandardOpenOption.APPEND); } } } private void installLogHandler() { handlers = LogManager.getLogManager().getLogger("").getHandlers(); SLF4JBridgeHandler.removeHandlersForRootLogger(); SLF4JBridgeHandler.install(); } private void uninstallLogHandler() { SLF4JBridgeHandler.uninstall(); Logger rootLogger = LogManager.getLogManager().getLogger(""); for (Handler handler : handlers) { rootLogger.addHandler(handler); } } private void prepare() { // For some reason JspC doesn't like it if the dir doesn't // already exist and refuses to create the web.xml fragment File generatedSourceDirectoryFile = new File(generatedClasses); if (!generatedSourceDirectoryFile.exists()) { generatedSourceDirectoryFile.mkdirs(); } } /** * Set up the execution classpath for Jasper. *

* Put everything in the classesDirectory and all of the dependencies on the * classpath. * * @param urls a list to which to add the urls of the dependencies * @throws IOException */ private void setUpClassPath(List urls) throws IOException { String classesDir = classesDirectory.getCanonicalPath(); classesDir = classesDir + (classesDir.endsWith(File.pathSeparator) ? "" : File.separator); // we must keep deprecated usage of File.toURL because URLClassloader seem not // working with path with %20 for example. urls.add(new File(classesDir).toURL()); if (getLog().isDebugEnabled()) { getLog().debug("Adding to classpath classes dir: " + classesDir); } for (Iterator iter = project.getArtifacts().iterator(); iter.hasNext();) { Artifact artifact = (Artifact) iter.next(); // Include runtime and compile time libraries if (!Artifact.SCOPE_TEST.equals(artifact.getScope())) { String filePath = artifact.getFile().getCanonicalPath(); if (getLog().isDebugEnabled()) { getLog().debug("Adding to classpath dependency file: " + filePath); } urls.add(artifact.getFile().toURL()); } } } private File getWebXmlFile() throws IOException { File file = null; File baseDir = project.getBasedir().getCanonicalFile(); File defaultWebAppSrcDir = new File(baseDir, "src/main/webapp").getCanonicalFile(); File webAppSrcDir = new File(webAppSourceDirectory).getCanonicalFile(); File defaultWebXml = new File(defaultWebAppSrcDir, WEB_XML).getCanonicalFile(); // If the web.xml has been changed from the default, try that File webXmlFile = new File(webXml).getCanonicalFile(); if (webXmlFile.compareTo(defaultWebXml) != 0) { file = new File(webXml); return file; } // If the web app src directory has not been changed from the default, use // whatever // is set for the web.xml location file = new File(webAppSrcDir, WEB_XML); return file; } /** * Add thread index at the end of webXmlFragment filename to deal with * multithreading. If the number of threads is equal to 1 (no multithreading) we * don't add suffix to maintain the same behavior as in the mode without * multithreading. * * @param threadIndex the index of current thread * @return web xml fragment filename with thread index */ private String getwebXmlFragmentFilename(int threadIndex) { return threads == 1 ? webXmlFragment : webXmlFragment + "." + threadIndex; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy