从war web app启动jvm子进程

时间:2012-03-30 14:09:09

标签: java war

我有一个有趣的设置。我有一个注册Web服务的Web应用程序。 Web服务本质上是一系列类的前端,它们执行以下操作:

  1. 设置RMI服务器
  2. 使用具有指定类的jvm启动子进程以执行某项工作
  3. 通常,为了解析类路径,我读取了System.getProperty(“java.class.path”);我为-cp参数设置了这个。但是,对于war文件,这没用。

    这是我从类路径启动特定类的函数的样子:

    public static Process launchClassProcess(@SuppressWarnings("rawtypes") Class c, String[] javaArgs, String[] programArgs) throws Exception {
        String separator = System.getProperty("file.separator");
        String classpath = System.getProperty("java.class.path");
        String home = System.getProperty("java.home");
        String path = home + separator + "bin" + separator + "java";
        String[] jvmArgs = new String[] { path, "-cp", classpath };
        String[] classArgs = new String[] { c.getName() };
        String[] processBuilderArgs = new String[jvmArgs.length + javaArgs.length + classArgs.length + programArgs.length];
        int i = 0;
    
        for (String arg:jvmArgs) {
            processBuilderArgs[i++] = arg;
        }
    
        for (String arg:javaArgs) {
            processBuilderArgs[i++] = arg;
        }
    
        for (String arg:classArgs) {
            processBuilderArgs[i++] = arg;
        }
    
        for (String arg:programArgs) {
            processBuilderArgs[i++] = arg;
        }
    
        ProcessBuilder processBuilder = new ProcessBuilder(processBuilderArgs);
        StringBuilder command = new StringBuilder();
        int j = 0;
    
        for (String part:processBuilder.command()) {
            if (j++ != 0) {
                command.append(" ");
            }
    
            command.append(part);
        }
    
        LogUtils.recordMessage("executing: " + command.toString());
    
        processBuilder.redirectErrorStream(true);
    
        return (new ProcessBuilder(processBuilderArgs)).start();
    }
    

    如何使用war文件使此功能正常工作?我想我必须以某种方式找到我的war文件在文件系统上解压缩的位置,并找到我可以构建完整类路径的libs文件夹。

2 个答案:

答案 0 :(得分:1)

执行此操作的最佳方法是添加一些修改类路径的魔法,以使上述功能起作用。

我们需要以下servlet,我们称之为InitServlet

public class InitServlet extends HttpServlet {

    public void init() throws ServletException {
        String libRealPath = getServletContext().getRealPath("/WEB-INF/lib/");

        if (libRealPath == null) {
            throw new ServletException("cannot find web-inf lib path");
        }

        ArrayList<String> libs = new ArrayList<String>();
        File libDir = new File(libRealPath);

        for (String file:libDir.list(new FilenameFilter() {

            public boolean accept(File dir, String file) {
                return file.endsWith(".jar");
            }

        })) {
            libs.add(libRealPath + System.getProperty("file.separator") + file);
        }

        System.setProperty("java.class.path", System.getProperty("java.class.path") + System.getProperty("path.separator") + ProcessUtils.joinPaths(libs));
    }

}

然后,我们需要在web.xml中注册servlet以实现魔术:

<servlet>
    <servlet-name>init-servlet</servlet-name>
    <servlet-class>InitServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>

答案 1 :(得分:0)

您可以从ServletContext获取lib文件夹的内容:

ServletContext context = ....;
Set< String > libs = context.getResourcePaths( "/WEB-INF/lib" );