Tomcat - starting webapps in a specific order

前端 未结 9 619
既然无缘
既然无缘 2020-12-05 07:51

I know that Tomcat and the Servlet spec do not support starting webapps in a particular order.

However, this seems to me like a common use case, and I\'m wondering i

相关标签:
9条回答
  • 2020-12-05 08:53

    In theory you could spawn a Runnable by ExecutorService in contextInitialized() which in turn checks the availability of the other webapp at timed intervals (perhaps by firing a HTTP HEAD request?). Once the other webapp is available, then set some attribute in the servlet context which indicates that. Add a Filter which checks for the presence of that attribute and blocks/continues requests accordingly.

    0 讨论(0)
  • 2020-12-05 08:53

    Since none of the options worked for Tomcat 9.0.19 (the one mentioned by @Luiz also) we used the code approach and replaced the Tomcat StandardHost and HostConfig with minimal custom implementations:

    public class CustomTomcatHost extends StandardHost {
    
        public CustomTomcatHost() {
            super();
        }
    
        @Override
        public void addLifecycleListener(LifecycleListener listener) {
            if (listener instanceof HostConfig) {
                listener = new OrderedHostConfig();
            }
            super.addLifecycleListener(listener);
        }
    }
    

    The deployApps function in HostConfig had to be overriden for sorting to work for everything (incl. WAR files in /webapps folder and also for descriptor XML files in configbase folder (e.g. conf/Catalina/localhost)):

    public class OrderedHostConfig extends HostConfig {
    
        public OrderedHostConfig() {
            super();
        }
    
        public String[] prioritySort(String[] paths) {
            if (paths == null) return null;
    
            Arrays.sort(paths, new Comparator<String>() {
                @Override
                public int compare(String a, String b) {
                    return a.compareTo(b); //TODO: sort paths based on your criteria
                }
            });
    
            return paths;
        }
    
        @Override
        protected void deployApps() {
    
            File appBase = host.getAppBaseFile();
            File configBase = host.getConfigBaseFile();
    
            String[] apps = prioritySort(filterAppPaths(appBase.list()));
    
            // Deploy XML descriptors from configBase
            deployDescriptors(configBase, prioritySort(configBase.list()));
            // Deploy WARs
            deployWARs(appBase, apps);
            // Deploy expanded folders
            deployDirectories(appBase, apps);
        }
    }
    

    Then we placed the new classes in a new jar file in Tomcat /lib directory and modified conf/server.xml file to replace the host class with our own implementation:

    <Host name="localhost"  appBase="webapps" unpackWARs="true" autoDeploy="true" className="com.example.CustomTomcatHost" >
    

    During start Tomcat loaded all components in the required order.

    0 讨论(0)
  • 2020-12-05 08:55

    Here is a nice trick i use to create 2 levels of webapp loading. in each level the order is not guaranteed. This relies on the fact that tomcat will load first context descriptors from tomcat/conf/[Engine Name]/[Host Name] and only then contexts from the appBase attribute of the Host element in server.xml

    Just add the following code somewhere in the webapp you would like to load in the 2nd level ( i.e. later )

    File contextDescriptor = new File(getParameter("catalina.home"),"/conf/Catalina/localhost/mywebapp.xml");
    contextDescriptor.deleteOnExit();
    
    0 讨论(0)
提交回复
热议问题