Deploying portlets to ROOT fails because of improper detection and handling of the "" context path.
DefaultApplicationIdResolver#resolveApplicationId(ServletContext) returns "/hostName" for the root context instead of "", where "hostName" is the name of the host containing the context (typically "localhost"). The program will seem to work normally except when HttpServletRequest.getContextPath() is called such as by the JSTL url tag. That method would then return the incorrect value of "/hostName".
Even when the context path is correctly detected as "", the portletId created by PortletWindowConfig#createPortletId(String, String, String) cannot by parsed by PortletWindowConfig#fromId(String) because the latter throws an exception if the id starts with ".".