001/* 002 * Copyright 2012-2017 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.boot.context; 018 019import org.apache.commons.logging.Log; 020import org.apache.commons.logging.LogFactory; 021 022import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent; 023import org.springframework.context.ApplicationListener; 024import org.springframework.core.Ordered; 025import org.springframework.core.env.ConfigurableEnvironment; 026 027/** 028 * An {@link ApplicationListener} that halts application startup if the system file 029 * encoding does not match an expected value set in the environment. By default has no 030 * effect, but if you set {@code spring.mandatory_file_encoding} (or some camelCase or 031 * UPPERCASE variant of that) to the name of a character encoding (e.g. "UTF-8") then this 032 * initializer throws an exception when the {@code file.encoding} System property does not 033 * equal it. 034 * 035 * <p> 036 * The System property {@code file.encoding} is normally set by the JVM in response to the 037 * {@code LANG} or {@code LC_ALL} environment variables. It is used (along with other 038 * platform-dependent variables keyed off those environment variables) to encode JVM 039 * arguments as well as file names and paths. In most cases you can override the file 040 * encoding System property on the command line (with standard JVM features), but also 041 * consider setting the {@code LANG} environment variable to an explicit 042 * character-encoding value (e.g. "en_GB.UTF-8"). 043 * 044 * @author Dave Syer 045 * @author Madhura Bhave 046 */ 047public class FileEncodingApplicationListener 048 implements ApplicationListener<ApplicationEnvironmentPreparedEvent>, Ordered { 049 050 private static final Log logger = LogFactory 051 .getLog(FileEncodingApplicationListener.class); 052 053 @Override 054 public int getOrder() { 055 return Ordered.LOWEST_PRECEDENCE; 056 } 057 058 @Override 059 public void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) { 060 ConfigurableEnvironment environment = event.getEnvironment(); 061 if (!environment.containsProperty("spring.mandatory-file-encoding")) { 062 return; 063 } 064 String encoding = System.getProperty("file.encoding"); 065 String desired = environment.getProperty("spring.mandatory-file-encoding"); 066 if (encoding != null && !desired.equalsIgnoreCase(encoding)) { 067 logger.error("System property 'file.encoding' is currently '" + encoding 068 + "'. It should be '" + desired 069 + "' (as defined in 'spring.mandatoryFileEncoding')."); 070 logger.error("Environment variable LANG is '" + System.getenv("LANG") 071 + "'. You could use a locale setting that matches encoding='" 072 + desired + "'."); 073 logger.error("Environment variable LC_ALL is '" + System.getenv("LC_ALL") 074 + "'. You could use a locale setting that matches encoding='" 075 + desired + "'."); 076 throw new IllegalStateException( 077 "The Java Virtual Machine has not been configured to use the " 078 + "desired default character encoding (" + desired + ")."); 079 } 080 } 081 082}