我在J2EE应用程序中使用enum时遇到问题。我在无状态服务bean内的switch case中使用enum。
在运行期间,我在switch语句中看到以下异常:
Caused by: java.lang.NoClassDefFoundError: com/comp/service/TestServiceImpl$1
此问题已在SO的其中一个主题上进行了广泛讨论。但我没有看到任何解决方案来解决这个问题。
在我的情况下,我使用JBOSS EAP6.1服务器。 JDK版本是1.7。代码是在Eclipse IDE中使用Maven构建的。应用程序部署为EAR存档。如何在我的EAR存档中的类路径中添加这个额外生成的类文件?有没有其他方法可以解决这个问题?
2014年6月29日更新: 我试图从命令行构建应用程序。然后生成这个额外的类文件。我能够成功地执行申请。这似乎是日食的错误。知道怎么解决吗?
来自EAR项目的pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>demo-maven</artifactId>
<groupId>com.comp.demo</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>demo-ear</artifactId>
<packaging>ear</packaging>
<name>demo - ear</name>
<url>www.comp.com</url>
<licenses>
<license>
<name>Apache License, Version 2.0</name>
<distribution>repo</distribution>
<url>http://www.apache.org/licenses/LICENSE-2.0.html</url>
</license>
</licenses>
<dependencies>
<!-- Depend on the ejb module and war so that we can package them -->
<dependency>
<groupId>com.comp.demo</groupId>
<artifactId>demo-web</artifactId>
<type>war</type>
</dependency>
<dependency>
<groupId>com.comp.demo</groupId>
<artifactId>demo-service</artifactId>
<type>ejb</type>
</dependency>
</dependencies>
<build>
<finalName>${project.parent.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-ear-plugin</artifactId>
<version>${version.ear.plugin}</version>
<configuration>
<!-- Tell Maven we are using Java EE 6 -->
<version>6</version>
<!-- Use Java EE ear libraries as needed. Java EE ear libraries
are in easy way to package any libraries needed in the ear, and automatically
have any modules (EJB-JARs and WARs) use them -->
<defaultLibBundleDir>lib</defaultLibBundleDir>
<modules></modules>
<fileNameMapping>no-version</fileNameMapping>
</configuration>
</plugin>
<!-- The JBoss AS plugin deploys your ear to a local JBoss EAP container -->
<!-- Due to Maven's lack of intelligence with EARs we need to configure
the jboss-as maven plugin to skip deployment for all modules. We then enable
it specifically in the ear module. -->
<plugin>
<groupId>org.jboss.as.plugins</groupId>
<artifactId>jboss-as-maven-plugin</artifactId>
<configuration>
<skip>false</skip>
</configuration>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<!-- When built in OpenShift the 'openshift' profile will be used when invoking mvn. -->
<!-- Use this profile for any OpenShift specific customization your app will need. -->
<!-- By default that is to put the resulting archive into the 'deployments' folder. -->
<!-- http://maven.apache.org/guides/mini/guide-building-for-different-environments.html -->
<id>openshift</id>
<build>
<plugins>
<plugin>
<artifactId>maven-ear-plugin</artifactId>
<version>${version.ear.plugin}</version>
<configuration>
<outputDirectory>deployments</outputDirectory>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
来自ejb项目的pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>demo-maven</artifactId>
<groupId>com.comp.demo</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>demo-service</artifactId>
<packaging>ejb</packaging>
<name>demo - service</name>
<url>www.comp.com</url>
<licenses>
<license>
<name>Apache License, Version 2.0</name>
<distribution>repo</distribution>
<url>http://www.apache.org/licenses/LICENSE-2.0.html</url>
</license>
</licenses>
<dependencies>
<!-- Declare the APIs we depend on and need for compilation. All of them
are provided by JBoss EAP 6 -->
<!-- Import the EJB API, we use provided scope as the API is included in
JBoss EAP 6 -->
<dependency>
<groupId>org.jboss.spec.javax.ejb</groupId>
<artifactId>jboss-ejb-api_3.1_spec</artifactId>
<scope>provided</scope>
</dependency>
<!-- Import the CDI API, we use provided scope as the API is included in
JBoss EAP 6 -->
<dependency>
<groupId>javax.enterprise</groupId>
<artifactId>cdi-api</artifactId>
<scope>provided</scope>
</dependency>
<!-- Import the JPA API, we use provided scope as the API is included in
JBoss EAP 6 -->
<dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.0-api</artifactId>
<scope>provided</scope>
</dependency>
<!-- JSR-303 (Bean Validation) Implementation -->
<!-- Provides portable constraints such as @Email -->
<!-- Hibernate Validator is shipped in JBoss EAP 6 -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jboss.ejb3</groupId>
<artifactId>jboss-ejb3-ext-api</artifactId>
<version>2.0.0-redhat-2</version>
<type>jar</type>
<scope>provided</scope>
</dependency>
<!-- Test scope dependencies -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.9.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>4.3.5.Final</version>
<scope>test</scope>
</dependency>
<!-- Optional, but highly recommended -->
<!-- Arquillian allows you to test enterprise code such as EJBs and Transactional(JTA)
JPA from JUnit/TestNG -->
<dependency>
<groupId>org.jboss.arquillian.junit</groupId>
<artifactId>arquillian-junit-container</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.arquillian.protocol</groupId>
<artifactId>arquillian-protocol-servlet</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>6.0</version>
<type>jar</type>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<artifactId>maven-ejb-plugin</artifactId>
<version>${version.ejb.plugin}</version>
<configuration>
<!-- Tell Maven we are using EJB 3.1 -->
<ejbVersion>3.1</ejbVersion>
</configuration>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<!-- The default profile skips all tests, though you can tune it to run
just unit tests based on a custom pattern -->
<!-- Seperate profiles are provided for running all tests, including Arquillian
tests that execute in the specified container -->
<id>default</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<build>
<plugins>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>${version.surefire.plugin}</version>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
</build>
</profile>
<profile>
<!-- An optional Arquillian testing profile that executes tests in your
JBoss EAP instance -->
<!-- This profile will start a new JBoss EAP instance, and execute the
test, shutting it down when done -->
<!-- Run with: mvn clean test -Parq-jbossas-managed -->
<id>arq-jbossas-managed</id>
<dependencies>
<dependency>
<groupId>org.jboss.as</groupId>
<artifactId>jboss-as-arquillian-container-managed</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</profile>
<profile>
<!-- An optional Arquillian testing profile that executes tests in a remote
JBoss EAP instance -->
<!-- Run with: mvn clean test -Parq-jbossas-remote -->
<id>arq-jbossas-remote</id>
<dependencies>
<dependency>
<groupId>org.jboss.as</groupId>
<artifactId>jboss-as-arquillian-container-remote</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</profile>
</profiles>
</project>
答案 0 :(得分:0)
我有一个与你的项目配置非常相似的项目配置:eclipse,Maven,JDK 1.6,JBoss EAP6.2,当在交换机案例中使用枚举时,我遇到与java.lang.NoClassDefFoundError相同的问题。
我找到了一个解决方法:生成一个ear文件(在我的情况下这是一场战争)并从JBoss管理控制台手动安装它。我注意到战争包括$ 1所需的类,然后你不会得到例外。
这只是一种解决方法,但它适用于我。这个解决方法的一个优点是后续部署通过eclipse完成!
我会听你问题的答案,因为我想要一个真正的解决方案。
答案 1 :(得分:0)
我遇到了类似的问题,简单的解决方法是将Enum定义为公开而非私有。
(没有时间进行验证,但我的预感是,这导致类不会被创建为名称$ 1.class ,而是像名称$ Enumname.class < / strong>,这似乎是个问题)