Harish Dalmia
Harish Dalmia

Reputation: 138

Unable to clean the Jetty working directory while docker is restarted

This is for embed jetty. I am trying to clean the jetty working directory which is automatically created in the /tmp folder inside the container. I did write the below method-"cleanJettyWorkingDirectory()" logic to clean the working directory and it works. The problem here is, it is not allowing me to create a working directory now because think I am calling this method from the wrong place. Whenever I am restarting the docker, it is cleaning the entire working directory Please assist.

public void cleanJettyWorkingDirectory(){
    final File folder = new File(JETTY_WORKING_DIRECTORY);
    final File[] files = folder.listFiles( new FilenameFilter() {
        @Override
        public boolean accept( final File dir,
                               final String name ) {
            return name.matches( "jetty-0_0_0_0-.*" );
        }
    } );

    for ( final File file : files ) {
        try {
            FileUtils.deleteDirectory(file);
        } catch (IOException e) {
           logger.info("Unable to delete the Jetty working directory");
        }
    }
}

Jetty Service Main class file as below:

public class JettyServer {

private final static Logger logger = Logger.getLogger(JettyServer.class.getName());
private static final int JETTY_PORT = 10000;
private static final String JETTY_REALM_PROPERTIES_FILE_NAME = "realm.properties";
private static final String JETTY_REALM_NAME = "myrealm";

private static final String JETTY_WORKING_DIRECTORY="tmp";

public static QueuedThreadPool threadPool;

public JettyServer() {

    try {
       
         cleanJettyWorkingDirectory(); // *Calling here*
        RolloverFileOutputStream os = new RolloverFileOutputStream(JETTY_STDOUT_LOG_FILE_NAME, true);
        PrintStream logStream = new PrintStream(os);
        System.setOut(logStream);
        System.setErr(logStream);

        Server server = new Server(JETTY_PORT);
        server.addBean(getLoginService());
      
            try {
                logger.info("Configuring Jetty SSL..");
                HttpConfiguration http_config = new HttpConfiguration();
                http_config.setSecureScheme("https");
                http_config.setSecurePort(JETTY_PORT);
                https.setPort(JETTY_PORT);
                server.setConnectors(new Connector[]{https});
                logger.info("Jetty SSL successfully configured..");
            } catch (Exception e){
                logger.severe("Error configuring Jetty SSL.."+e);
                throw e;
            }
        
        Configuration.ClassList classlist = Configuration.ClassList.setServerDefault(server);
        classlist.addAfter("org.eclipse.jetty.webapp.FragmentConfiguration",
                "org.eclipse.jetty.plus.webapp.EnvConfiguration",
                "org.eclipse.jetty.plus.webapp.PlusConfiguration");

        //register ui and service web apps
        HandlerCollection webAppHandlers = getWebAppHandlers();

        for (Connector c : server.getConnectors()) {
            c.getConnectionFactory(HttpConnectionFactory.class).getHttpConfiguration().setRequestHeaderSize(MAX_REQUEST_HEADER_SIZE);
            c.getConnectionFactory(HttpConnectionFactory.class).getHttpConfiguration().setSendServerVersion(false);
        }

        threadPool = (QueuedThreadPool) server.getThreadPool();

        // request logs
        RequestLogHandler requestLogHandler = new RequestLogHandler();
        AsyncRequestLogWriter asyncRequestLogWriter = new AsyncRequestLogWriter(JETTY_REQUEST_LOG_FILE_NAME);
        asyncRequestLogWriter.setFilenameDateFormat(JETTY_REQUEST_LOG_FILE_NAME_DATE_FORMAT);
        asyncRequestLogWriter.setAppend(JETTY_REQUEST_LOG_FILE_APPEND);
        asyncRequestLogWriter.setRetainDays(JETTY_REQUEST_LOG_FILE_RETAIN_DAYS);
        asyncRequestLogWriter.setTimeZone(TimeZone.getDefault().getID());
        requestLogHandler.setRequestLog(new AppShellCustomRequestLog(asyncRequestLogWriter));
        webAppHandlers.addHandler(requestLogHandler);

        StatisticsHandler statisticsHandler = new StatisticsHandler();
        statisticsHandler.setHandler(new AppshellStatisticsHandler());
        webAppHandlers.addHandler(statisticsHandler);

        // set handler
        server.setHandler(webAppHandlers);

        //start jettyMetricsPsr
        JettyMetricStatistics.logJettyMetrics();

        // set error handler
        server.addBean(new CustomErrorHandler());

        // GZip Handler
        GzipHandler gzip = new GzipHandler();
        server.setHandler(gzip);
        gzip.setHandler(webAppHandlers);


        //setting server attribute for datasources
        server.setAttribute("fawappshellDS", new Resource(JNDI_NAME_FAWAPPSHELL, DatasourceUtil.getFawAppshellDatasource()));
        server.setAttribute("fawcommonDS", new Resource(JNDI_NAME_FAWCOMMON, DatasourceUtil.getCommonDatasource()));
        //new Resource(server, JNDI_NAME_FAWAPPSHELL, getFawAppshellDatasource());
        //new Resource(server, JNDI_NAME_FAWCOMMON, getFawCommonDatasource());
        
        server.start();
        server.join();

    } catch (Exception e) {
        e.printStackTrace();
    }
}

private HandlerCollection getWebAppHandlers() throws SQLException, NamingException{
    //Setting the war and context path for the service layer: oaxservice
    WebAppContext serviceWebapp = new WebAppContext();
    serviceWebapp.setWar(APPSHELL_API_WAR_FILE_PATH);
    serviceWebapp.setContextPath(APPSHELL_API_CONTEXT_PATH);
    serviceWebapp.setPersistTempDirectory(false);

    //setting the war and context path for the UI layer: oaxui
    WebAppContext uiWebapp = new WebAppContext();
    uiWebapp.setWar(APPSHELL_UI_WAR_FILE_PATH);
    uiWebapp.setContextPath(APPSHELL_UI_CONTEXT_PATH);
    uiWebapp.setAllowNullPathInfo(true);
    uiWebapp.setInitParameter("org.eclipse.jetty.servlet.Default.dirAllowed", "false");

    //set error page handler for the UI context
    uiWebapp.setErrorHandler(new CustomErrorHandler());

    //handling the multiple war files using HandlerCollection.
    HandlerCollection handlerCollection = new HandlerCollection();
    handlerCollection.setHandlers(new Handler[]{serviceWebapp, uiWebapp});
    return handlerCollection;
}


public LoginService getLoginService() throws IOException {
    URL realmProps = JettyServer.class.getClassLoader().getResource(JETTY_REALM_PROPERTIES_FILE_NAME);

    if (realmProps == null)
        throw new FileNotFoundException("Unable to find " + JETTY_REALM_PROPERTIES_FILE_NAME);
    return new HashLoginService(JETTY_REALM_NAME, realmProps.toExternalForm());
}

public void cleanJettyWorkingDirectory(){
    final File folder = new File(JETTY_WORKING_DIRECTORY);
    final File[] files = folder.listFiles( new FilenameFilter() {
        @Override
        public boolean accept( final File dir,
                               final String name ) {
            return name.matches( "jetty-0_0_0_0-.*" );
        }
    } );

    for ( final File file : files ) {
        try {
            FileUtils.deleteDirectory(file);
        } catch (IOException e) {
           logger.info("Unable to delete the Jetty working directory");
        }
    }
}

public static void main(String[] args) {
    new JettyServer();
}

}

Upvotes: 0

Views: 456

Answers (1)

Joakim Erdfelt
Joakim Erdfelt

Reputation: 49515

Option 1: Use docker tmpfs

If you want to eliminate the system temp persistence, just use docker correctly to avoid it doing that between restarts, don't write this custom logic within your java app.

The docker tmpfs is probably going to be a better solution.

See past answer: https://stackoverflow.com/a/52662602/775715

Option 2: Use linux systemd tmpfiles

You could also use systemd-tmpfiles or systemd-tmpfiles-clean to perform the cleanup (periodically) automatically within the Linux environment within your docker image.

Option 3: Use a non-standard system temp directory for Jetty

Configure a new Temp Directory for your Java instance ...

$ java -Djava.io.tmpdir=/var/run/jetty/work/ -jar start.jar

Then use your shell script that starts your Jetty instance to just clear out that unique directory before you execute the java instance.

aka:

JETTY_WORK=/var/run/jetty/work
rm -rf $JETTY_WORK/*
java -Djava.io.tmpdir=$JETTY_WORK/ -jar start.jar

This approach also catches all Java temp directory usages from your 3rd party libraries as well, not just Jetty itself.

Upvotes: 1

Related Questions