当我尝试在已使用@Secured
注释的@PreAuthorize
方法中使用@Controller
或@RequestMapping
时,我发现了一个奇怪的错误。当我尝试启动应用程序时,它给出了以下错误(使用带有vFabric 2.6.1的spring STS 2.8.1在win 7 32位上,包括springframework和spring security 3.1):
Caused by: java.lang.ClassFormatError: Duplicate method name&signature in class file com/dnp/web/controllers/HomeController
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClassCond(ClassLoader.java:631)
at java.lang.ClassLoader.defineClass(ClassLoader.java:615)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
at org.apache.catalina.loader.WebappClassLoader.findClassInternal(WebappClassLoader.java:2820)
at org.apache.catalina.loader.WebappClassLoader.findClass(WebappClassLoader.java:1150)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1645)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1523)
at org.springframework.util.ClassUtils.forName(ClassUtils.java:258)
at org.springframework.beans.factory.support.AbstractBeanDefinition.resolveBeanClass(AbstractBeanDefinition.java:417)
at org.springframework.beans.factory.support.AbstractBeanFactory.doResolveBeanClass(AbstractBeanFactory.java:1283)
at org.springframework.beans.factory.support.AbstractBeanFactory.resolveBeanClass(AbstractBeanFactory.java:1254)
... 43 more
控制器代码:
@Controller
public class HomeController {
private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
@PreAuthorize("hasRole('ROLE_USER')")
@RequestMapping(value = "/", method = RequestMethod.GET)
public String home(Locale locale, Model model) {
logger.info("Welcome home! the client locale is "+ locale.toString());
Date date = new Date();
DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);
String formattedDate = dateFormat.format(date);
model.addAttribute("serverTime", formattedDate );
return "home";
}
}
我不知道为什么会抛出这个错误,并且没有在互联网上找到任何关于它的信息。此外,服务层上的安全注释也可以正常工作。
PD:完整的应用程序跟踪在这里:http://pastebin.com/raw.php?i=VxdYPDXL,安全和servlet上下文的主要部分在这里:http://pastebin.com/cva5VgkH
答案 0 :(得分:0)
@rabusmar,我从SpringForum获得了这个链接 http://forum.springsource.org/showthread.php?109850-RequestMapping-and-PreAuthorize-not-compatible
似乎PreAuthorize和Request Mapping不兼容。他们在页面末尾给出了解决方案。试试吧。
此外,当一个已经由一个注释检测的类被另一个注释再次检测时,就会出现ClassFormatError,在这种情况下,HomeController可能已经由PreAuthorize和RequestMapping再次检测,反之亦然,这就是你得到的原因。 ClassFormatError。
您可以在我上面提供的春季论坛链接中尝试解决方案。
答案 1 :(得分:0)
似乎这个问题是由Spring AOP和AspectJ编译时编织相同方法之间的一些奇怪冲突造成的:我正在使用一个方面来建议控制器方法调用,它是编译时编织的控制器。因此,解决方案只是禁用AspectJ编译,现在它可以正常工作。
答案 2 :(得分:0)
我在一些groovy代码中遇到了类似的ClassFormatError。但错误消息没有说明哪个方法名称和签名是重复的。
我通过运行以下命令找到了错误:
javap -private -c io.cloudsoft.mapr.m3.MasterNodeImpl | grep -A 1 '^$' | sort | uniq -c | less
这找到了所有方法签名(在我的javap输出中始终以空行开头),然后计算唯一出现次数,以便我可以看到哪个方法签名是重复的。我希望别人这么好用。
(对于那些感兴趣的人,我的问题是groovy的@InheritConstructors的奇怪行为,它以某种方式添加了两次no-arg构造函数。)