Vaadin Prod Mode via System Property

hi, i am getting the message in the log “Vaadin is running in DEBUG MODE.” even though i added mypackage.productionMode=true to the VM parameters of my application server. I am running vaadin 7.1.13. but calling http://localhost/myapp/?debug does not get me the console. So somehow it is in prod mode and somehow not. Any explanation?

My goal is to have the vaadin web app in production mode through a VM setting. Using web.xml or hard coded in the source is no option for this case.

Hi Mihael,

What I’m doing is using Servlet 3 feature instead of web.xml for servlet registration.
You can then inject the system property you want in the servlet registration.
Ex:

ServletRegistration.Dynamic applicationServletRegistration = servletContext.addServlet("ApplicationServlet", MyApplicationServlet.class); // add mapping, UI class and stuff... // Then set the productionMode from the productionMode System property applicationServletRegistration.setInitParameter("productionMode", System.getProperty("productionMode"))); Fred

I don’t know why you are coding this by yourself. It is already available, see com.vaadin.server.DefaultDeploymentConfiguratin.checkProductionmode() .

My question is why it is not (completely) working in my case.

You are right, but I use the same productionMode system property for other stuff in my app which are not related to Vaadin.
Furthermore the checkProductionmode() will check the property at the application level (ie servlet init parameter first), then falls back to system property if the servlet init parameter is not set.
My way allows to always set the application level parameter so it’s deterministic.

Maybe you can provide your web.xml and startup command line so that we can help you

Fred

web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
        http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    version="3.0">
    
    <servlet>
        <display-name>Web Launcher Tiles - Vaadin OSGi Servlet</display-name>
        <servlet-name>vaadin_servlet</servlet-name>
        <servlet-class>de.sgbs.web.launcher.tiles.OsgiVaadinServlet</servlet-class>
        <init-param>
            <param-name>UI</param-name>
            <param-value>de.sgbs.web.launcher.tiles.ui.Application</param-value>
        </init-param>
    </servlet>

    <servlet-mapping>
        <servlet-name>vaadin_servlet</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
    
    <session-config>
        <session-timeout>300</session-timeout>
    </session-config>
    
</web-app>

[code]
public class OsgiVaadinServlet extends VaadinServlet {

private static final long serialVersionUID = -4733496883901044844L;

@Override
protected VaadinServletService createServletService(
        DeploymentConfiguration deploymentConfiguration) throws ServiceException {
    
    VaadinServletService service = new VaadinServletService(this, deploymentConfiguration) {
        private static final long serialVersionUID = 1L;

        @Override
        public ClassLoader getClassLoader() {
            return OsgiVaadinServlet.class.getClassLoader();
        }

        @Override
        protected List<RequestHandler> createRequestHandlers() throws ServiceException {
            ClassLoader actual = Thread.currentThread().getContextClassLoader();
            try {
                Thread.currentThread().setContextClassLoader(
                        DefaultBroadcaster.class.getClassLoader());
                return super.createRequestHandlers();
            } finally {
                Thread.currentThread().setContextClassLoader(actual);
            }
        }
    };
    service.init();
    return service;
}

}
[/code]VM argument:

-Dde.sgbs.web.launcher.tiles.productionMode=true

Hope it helps.

Mihael

I did in in this way. But I would expect some better support from the framework, soem extension point for required VaadinServletConfiguration#productionMode

/**
 * Custom Vaadin servlet.
 * <p>Vaading config <code>productionMode</code> is set by default to <code>true</code>.
 * You may change it by setting the system property <code>productionMode</code> (done in {@link #init(ServletConfig)})
 */
@WebServlet(urlPatterns = "/*")
@VaadinServletConfiguration(ui = MyUI.class, productionMode = true)
public class CustomUIServlet extends VaadinCDIServlet {

    private static final String PRODUCTION_MODE = "productionMode";

    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        setupProductionMode(servletConfig);
        super.init(servletConfig);
    }

    private void setupProductionMode(ServletConfig servletConfig) {

        String productionMode = System.getProperty(PRODUCTION_MODE);

        if (productionMode != null) {
            servletConfig.getServletContext().setInitParameter(PRODUCTION_MODE, productionMode);
        }
    }

}

The current implementation of DefaultDeploymentConfiguration.checkProductionMode() is that it first checks the servlet init parameter, then the system property, then defaults to false. This is not ideal IMHO. I think that this setting should not be configured in web.xml or servlet configuration as this setting is not really an application setting - this is an environment setting.

Ideal setup would be for the very same code to run by default in production mode on production servers, and in the dev mode on on developer machines. This could be achieved easily, simply by running dev server locally, with a system property of, say, -Dde.sgbs.web.launcher.tiles.productionMode=false. However, current Vaadin implementation would require you to set -Dde.sgbs.web.launcher.tiles.productionMode=true on the production servers instead, which is error-prone and potentially disastrous.

Therefore, I would vote to set the productionMode by default to true in the DefaultDeploymentConfiguration Vaadin class. This change is however a bit controversial - it will break backward compatibility. However, I can imagine that a lot of coders simply set productionMode in servlet/web.xml and those guys will be unaffected by this. If you agree, I can open a feature request at Vaadin Issue tracker.

I am currently trying to decide on how to address a similar issue, it seems this thread did not reach a clear resolution, unless someone can point me to one.
Thanks

Luboš Račanský’s solution is brilliant, unfortunately it doesn’t work for me in Tomcat:

java.lang.IllegalStateException: Initialization parameters cannot be set after the context has been initialized
    at org.apache.catalina.core.ApplicationContext.setInitParameter(ApplicationContext.java:1003)
    at org.apache.catalina.core.ApplicationContextFacade.setInitParameter(ApplicationContextFacade.java:624)

Therefore, I’m simply having a zero-sized file named /etc/myapp/production which serves as a marker of the production env. Then, I just check for the file and reconfigure accordingly (pardon the Kotlin code):

@WebServlet(urlPatterns = arrayOf("/*"), name = "MyUIServlet", asyncSupported = true)
@VaadinServletConfiguration(ui = MyUI::class, productionMode = true)
class MyUIServlet : VaadinServlet() {
    override fun createDeploymentConfiguration(initParameters: Properties?): DeploymentConfiguration {
        initParameters!!.put(Constants.SERVLET_PARAMETER_PRODUCTION_MODE, "" + File("/etc/myproject/production").exists())
        return super.createDeploymentConfiguration(initParameters)
    }
}

Thanks Martin, your solution works for me, with details a bit different (I use a System Property instead of a file), but the idea is similar: private static final String PRODUCTION_MODE = "productionMode"; ... @Override protected DeploymentConfiguration createDeploymentConfiguration(Properties initParameters) { boolean isDeveloperMode = Boolean.getBoolean("myapp.isdeveloper"); initParameters.setProperty(PRODUCTION_MODE, Boolean.toString(!isDeveloperMode)); DeploymentConfiguration config = super.createDeploymentConfiguration(initParameters); }