我以为我会使用Java 8中的新ResourceBundleControlProvider框架来修复Oracle自身无法修复的问题-读取资源束时使用的默认编码.
所以我做了一个控制:
package com.acme.resources;
import java.io.IOException;
import java.util.Locale;
import java.util.ResourceBundle;
public class AcmeResourceBundleControl extends ResourceBundle.Control
{
@Override
public ResourceBundle newBundle(String baseName, Locale locale, String format,
ClassLoader loader, boolean reload)
throws IllegalAccessException, InstantiationException, IOException
{
throw new UnsupportedOperationException("TODO");
}
}
然后我做了一个提供者:
package com.acme.resources;
import java.util.ResourceBundle;
import java.util.spi.ResourceBundleControlProvider;
public class AcmeResourceBundleControlProvider implements ResourceBundleControlProvider
{
private static final ResourceBundle.Control CONTROL = new AcmeResourceBundleControl();
@Override
public ResourceBundle.Control getControl(String baseName)
{
if (baseName.startsWith("com.acme."))
{
return CONTROL;
}
else
{
return null;
}
}
}
然后在META-INF / services / java.util.spi.ResourceBundleControlProvider中:
com.acme.resources.AcmeResourceBundleControlProvider
然后,我只是尝试从IDEA运行我们的应用程序,发现它永远不会加载我的提供程序(否则将引发异常.)
我检查了名字,它们似乎都匹配了.我检查了IDEA正在使用的编译器输出目录,它确实包含服务文件.我编写了一个简单的测试程序,它只是尝试查找服务:
public static void main(String[] args)
{
for (ResourceBundleControlProvider provider :
ServiceLoader.load(ResourceBundleControlProvider.class))
{
System.out.println(provider.getClass());
}
}
这确实打印出一个条目,这是我的实现类的名称.因此,问题不在服务文件中.
如果我在ResourceBundle内设置断点,则似乎可以访问自定义提供程序类.对调试器的初步尝试表明ServiceLoader找不到任何实现,但是我不知道为什么.我确定发生了一些狡猾的类加载器魔术,导致无法加载我的类.