Ich habe ein großes Problem in meinem Diplomprojekt und wäre sehr froh, wenn ihr mir helfen könntet! Ich habe ein Maven Multi Modul Projekt gemacht und habe 3 "Core-projects"
NaviClean
: (Elternteil)NaviCleanDomain
: enthält das Domänenmodell mit allen meinen Entitäten und
eine Schnittstelle MeinRemoteDienst
, die von NaviCleanServer
benötigt wird
und NaviCleanCleint
für das Hessianprotocol
benötigt wirdNaviCleanClient
: enthält die GUI und eine hessische Verbindung zu
NaviCleanServerNaviCleanServer
: Hier sind meine Repositories, meine Verbindung zur DB
und die Implementierung der Schnittstelle einRemoteDienst
NaviCleanServer
& NaviCleanClient
haben NaviCleanDomain
in Maven als
Abhängigkeit.Jetzt bekomme ich jedes Mal, wenn ich versuche, den Server auf meinem Tomcat zu starten, die folgende Fehlermeldung:
ERROR: org.springframework.web.context.ContextLoader - Context initialization failed
org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'transaktionsRepository':
Injection of persistence dependencies failed;
nested exception is org.springframework.beans.factory.CannotLoadBeanClassException:
Error loading class [at.naviclean.service.impl.MeinRemoteDienstImpl] for bean with name 'meinRemoteDienstImpl' defined in file [C:\Users\Fredy\Documents\workspace-sts-3.1.0.RELEASE\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\NaviCleanServer\WEB-INF\classes\at\naviclean\service\impl\MeinRemoteDienstImpl.class]:
problem with class file or dependent class;
nested exception is java.lang.NoClassDefFoundError: at/naviclean/service/MeinRemoteDienst
at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.postProcessPropertyValues(PersistenceAnnotationBeanPostProcessor.java:342)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1106)
……………….
ModelBase:
package at.naviclean.domain;
import java.io.Serializable;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;
import javax.persistence.Version;
@SuppressWarnings("serial")
@MappedSuperclass
public class ModelBase implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id")
private Long id;
@Version
@Column(name = "ts")
private Date timestamp;
public Long getId() {
return id;
}
public Date getTimestamp() {
return timestamp;
}
public void setId(Long id) {
this.id = id;
}
public void setTimestamp(Date timestamp) {
this.timestamp = timestamp;
}
}
Kassa:
package at.naviclean.domain;
import javax.persistence.Column;
import javax.persistence.Entity;
@SuppressWarnings("serial")
@Entity
public class Kassa extends ModelBase {
@Column(name = "name", unique = true)
private String name;
@Column(name = "geld")
private int geld;
public Kassa(String name, int geld) {
this.name = name;
this.geld = geld;
}
public Kassa() {
}
public String getName() {
return name;
}
public int getGeld() {
return geld;
}
public void setName(String name) {
this.name = name;
}
public void setGeld(int geld) {
this.geld = geld;
}
}
MeinRemoteDienst:
package at.naviclean.service;
import at.naviclean.domain.Kassa;
public interface MeinRemoteDienst {
int getKassaCount(int plus);
String getNameFromKassa(int id);
Kassa findById(int id);
}
BaseRepository
package at.naviclean.repositories;
import org.springframework.data.jpa.repository.JpaRepository;
import at.naviclean.domain.ModelBase;
public interface BaseRepository<T extends ModelBase> extends
JpaRepository<T, Long> {
T findById(long id);
}
KassaRepository:
package at.naviclean.repositories;
import java.util.List;
import org.springframework.data.jpa.repository.Query;
import at.naviclean.domain.Kassa;
public interface KassaRepository extends BaseRepository<Kassa> {
List<Kassa> findByGeld(int geld);
Kassa findByName(String name);
@Query("select k from Kassa k where k.geld = ?1")
Kassa findByGeld1(int geld);
}
MeinRemoteDienstImpl:
package at.naviclean.service.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import at.naviclean.domain.Kassa;
import at.naviclean.repositories.KassaRepository;
import at.naviclean.service.MeinRemoteDienst;
@Service
public class MeinRemoteDienstImpl implements MeinRemoteDienst {
@Autowired(required = true)
public KassaRepository kassaR;
public int getKassaCount(int plus) {
return 2;
}
public String getNameFromKassa(int id) {
return kassaR.findById(id + 0l).getName();
}
@Override
public Kassa findById(int id) {
return = kassaR.findById(id + 0l);
}
}
Anwendungskontext.xml:
<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:repository="http://www.springframework.org/schema/data/repository"
xsi:schemaLocation="http://www.springframework.org/schema/data/repository http://www.springframework.org/schema/data/repository/spring-repository.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<import resource="infrastructures.xml" />
<jpa:repositories base-package="at.naviclean.repositories">
<repository:exclude-filter type="regex"
expression="at.naviclean.repositories.BaseRepository" />
</jpa:repositories>
<context:component-scan base-package="at.naviclean.service.impl" />
</beans>
infrastructures.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true" />
<property name="generateDdl" value="true" />
<property name="databasePlatform" value="org.hibernate.dialect.MySQLDialect" />
</bean>
</property>
</bean>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost/kassatest" />
<property name="username" value="root" />
<property name="password" value="" />
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" />
</beans>
servlet-context.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p" xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:c="http://www.springframework.org/schema/c"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<import resource="../root-context.xml" />
<bean id="idMeinRemoteDienst" class="at.naviclean.service.impl.MeinRemoteDienstImpl" />
<bean name="/MeinRemoteDienstHessian"
class="org.springframework.remoting.caucho.HessianServiceExporter"
p:serviceInterface="at.naviclean.service.MeinRemoteDienst"
p:service-ref="idMeinRemoteDienst" />
</beans>
wurzel-context.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<import resource="classpath:META-INF/spring/application-context.xml" />
</beans>
web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<!-- The definition of the Root Spring Container shared by all Servlets
and Filters -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/root-context.xml</param-value>
</context-param>
<!-- Creates the Spring Container shared by all Servlets and Filters -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>/MeinRemoteDienstHessian</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>/MeinRemoteDienstHessian</servlet-name>
<url-pattern>/remoting/*</url-pattern>
</servlet-mapping>
</web-app>
***Hier ist, was ich bereits versucht habe:
Ich schrieb diesen Test, der "ging rot":***
Paket at.spengergasse.kassa;
importieren static org.hamcrest.CoreMatchers.equalTo; importieren static org.hamcrest.CoreMatchers.is; importieren statisch org.hamcrest.CoreMatchers.not; importieren statisch org.hamcrest.CoreMatchers; importieren static org.hamcrest.CoreMatchers.nullValue; importieren static org.hamcrest.CoreMatchers.nullValue; importieren static org.hamcrest.MatcherAssert.assertThat;
import org.junit.Before; import org.junit.Test; importieren org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; importieren org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import at.naviclean.domain.Kassa; import at.naviclean.repositories.KassaRepository; import at.naviclean.repositories.KassaRepository;
@ContextConfiguration("classpath:META-INF/spring/application-context.xml") @RunWith(SpringJUnit4ClassRunner.class) public class KassaTest {
@Autowired(required = true)
private KassaRepository kassaR;
@Before
public void setUp() throws Exception {
}
@Test
public void findByIdTest() {
Kassa k = kassaR.findById(2);
assertThat(k, is(not(nullValue())));
}
@Test
public void findByGeld() {
Kassa k = kassaR.findByGeld1(1200);
assertThat(k, is(not(nullValue())));
}
@Test
public void test() {
Kassa vorher = new Kassa("ssf", 222);
kassaR.save(vorher);
Kassa nachher = kassaR.findById(vorher.getId());
kassaR.delete(nachher);
assertThat(vorher.getId(), is(equalTo(nachher.getId())));
}
}
ERRORS:
ERROR: org.springframework.test.context.TestContextManager -
Caught exception while allowing TestExecutionListener [org.springframework.test.context.support.DependencyInjectionTestExecutionListener@41e22632] to prepare test instance [at.spengergasse.kassa.KassaTest@6639be68]
java.lang.IllegalStateException: Failed to load ApplicationContext
at org.springframework.test.context.TestContext.getApplicationContext(TestContext.java:157)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:109)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:75)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:321)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:211)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:288)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:290)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'meinRemoteDienstImpl':
**Injection of autowired dependencies failed**;
nested exception is org.springframework.beans.factory.BeanCreationException:
Could not autowire field: public at.naviclean.repositories.KassaRepository at.naviclean.service.impl.MeinRemoteDienstImpl.kassaR;
nested exception is org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'kassaRepository': FactoryBean threw exception on object creation;
nested exception is java.lang.IllegalArgumentException: **Not an managed type: class at.naviclean.domain.Kassa**
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:287)
………..
2. Ich habe in meiner persitence.xml mein Domainmodel und die Repositories manuell eingefügt. Das Ergebnis war ein "grün" Test, aber ich war'nicht in der Lage, den Server noch zu starten...
Vielen Dank im Voraus!!! Ich kann mir nicht vorstellen, was es ohne Sie wäre :)
Ich erhielt einen sehr hilfreichen Rat von Oliver Gierke: Die letzte Ausnahme, die Sie erhalten, weist auf ein Problem mit Ihrer JPA Setup. "Not a managed bean" bedeutet, dass es sich nicht um einen Typ handelt, der dem JPA Provider bekannt ist
bekannt ist. Wenn Sie eine Spring-basierte JPA-Anwendung einrichten, würde ich empfehlen die "packagesToScan" Eigenschaft auf der LocalContainerEntityManagerFactory, die Sie konfiguriert haben, auf das Paket das Ihre JPA-Entitäten enthält. Alternativ können Sie auch alle Ihre Entitätsklassen in persistence.xml auflisten, aber das ist in der Regel umständlicher.
Der frühere Fehler (NoClassDefFound) zeigt an, dass die Klasse nicht auf dem Klassenpfad des Projekts verfügbar ist. Sie könnten also wanna check the inter module dependencies you have. Da die beiden relevanten Klassen im selben Modul zu befinden scheinen, könnte es auch nur ein Problem mit einer unvollständigen Bereitstellung an Tomcat sein (WTP ist irgendwie manchmal etwas zickig). Ich würde auf jeden Fall empfehlen, einen Test durchzuführen, um Überprüfung (wie Sie bereits getan haben). Da dies anscheinend zu einer anderen Ausnahme zu führen scheint, vermute ich, dass es sich wirklich um einen Eclipse-Fehler handelt
Vielen Dank!
Sie sollten den Geltungsbereich der Komponentenprüfung erweitern, z. B. <context:component-scan base-package="at.naviclean" />
, da Sie die Entitäten im Paket at.naviclean.domain;
platziert haben.
Dies sollte Ihnen helfen, die Ausnahmeregelung loszuwerden: Nicht ein verwalteter Typ: Klasse at.naviclean.domain.Kassa
Zur weiteren Fehlersuche können Sie versuchen, den Anwendungskontext zu dumpen (siehe javadoc), um herauszufinden, welche Klassen vom Komponentenscan erkannt wurden. Wenn einige immer noch nicht erkannt werden, überprüfen Sie ihre Annotation (@Service, @Component usw.)
EDIT:
Sie müssen auch die Klassen zu Ihrer persistence.xml
hinzufügen
<persistence-unit>
<class>at.naviclean.domain.Kassa</class>
...
</persistence-unit>
Bezug nehmend auf Oliver Gierke's Hinweis:
Wenn die Manipulation der persistance.xml ausreicht, dann haben Sie eine normale Java-Klasse statt einer Entity-Klasse erstellt.
Wenn man eine neue Entity-Klasse erstellt, dann sollte der Eintrag in der persistance.xml von Netbeans gesetzt werden (in meinem Fall).
Aber wie von Oliver Gierke erwähnt, kann man den Eintrag auch später in der persistance.xml hinzufügen (wenn man eine normale Java-Klasse erstellt hat).