JSF CDI @Inject No eligible for injection beans are found

denis7788

Bekanntes Mitglied
Hallo,

ich habe gerade ein Tutorial nachgespielt und kann einen Fehler nicht nachvollziehen. Als zusätzliche Info: Im Tutorial wird noch eine ältere Glassfish version genutzt, bei der CDI bei der Projekterstellung explizit aktiviert werden muss. Ich nutze Glassfish 8 und habe gelesen, dass es per default aktiviert ist.

Jedenfalss bekomme ich die Warnung "No eligible for injection beans are found", wenn ich mein Interface injizieren will und beim deployen eine NullPointerException (unten der log). Ich finde nicht heraus, woran es liegt.

Hier mein Code:
HTML:
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://xmlns.jcp.org/jsf/html">
    <h:head>
        <title>Facelet Title</title>
    </h:head>
    <h:body>
        Wie heißen Sie?
        <h:form>
            <h:inputText value="#{greetingManager.name}" />
            <h:commandButton action="greet" value="Send" />
        </h:form>
    </h:body>
</html>

HTML:
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://xmlns.jcp.org/jsf/html">
    <h:head>
        <title>Facelet Title</title>
    </h:head>
    <h:body>
        <h1>#{greetingManager.greeting}</h1>
    </h:body>
</html>

Java:
@Named
@SessionScoped
public class GreetingManager implements Serializable {

    private static final long serialVersionUID = 1L;
   
    @Inject
    private Greeter service;
    private String name;
   
    public String getName() {
        return name;
    }
   
    public void setName(String name) {
        this.name = name;
    }
   
    public String getGreeting() {
        return service.sayHello(name);
    }
   
}

Java:
@Stateless
public interface Greeter {
   
    public String sayHello(String name);
   
}

Java:
public class TheGreeter implements Greeter{

    @Override
    public String sayHello(String name) {
        String str = "Hallo, "+ name;
        return str;
    }
   
}

Server Log:
Code:
Information:   visiting unvisited references
Information:   visiting unvisited references
Information:   visiting unvisited references
Information:   visiting unvisited references
Information:   Portable JNDI names for EJB Greeter: [java:global/GreetingCDI/Greeter, java:global/GreetingCDI/Greeter!api.Greeter]
Schwerwiegend:   Exception while invoking class org.glassfish.ejb.startup.EjbDeployer load method
java.lang.RuntimeException: EJB Container initialization error
    at org.glassfish.ejb.startup.EjbApplication.loadContainers(EjbApplication.java:234)
    at org.glassfish.ejb.startup.EjbDeployer.load(EjbDeployer.java:291)
    at org.glassfish.ejb.startup.EjbDeployer.load(EjbDeployer.java:99)
    at org.glassfish.internal.data.ModuleInfo.load(ModuleInfo.java:206)
    at org.glassfish.internal.data.ApplicationInfo.load(ApplicationInfo.java:313)
    at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:496)
    at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:219)
    at org.glassfish.deployment.admin.DeployCommand.execute(DeployCommand.java:491)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl$2$1.run(CommandRunnerImpl.java:539)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl$2$1.run(CommandRunnerImpl.java:535)
    at java.security.AccessController.doPrivileged(Native Method)
    at javax.security.auth.Subject.doAs(Subject.java:360)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl$2.execute(CommandRunnerImpl.java:534)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl$3.run(CommandRunnerImpl.java:565)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl$3.run(CommandRunnerImpl.java:557)
    at java.security.AccessController.doPrivileged(Native Method)
    at javax.security.auth.Subject.doAs(Subject.java:360)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:556)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:1464)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl.access$1300(CommandRunnerImpl.java:109)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1846)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1722)
    at com.sun.enterprise.v3.admin.AdminAdapter.doCommand(AdminAdapter.java:534)
    at com.sun.enterprise.v3.admin.AdminAdapter.onMissingResource(AdminAdapter.java:224)
    at org.glassfish.grizzly.http.server.StaticHttpHandlerBase.service(StaticHttpHandlerBase.java:189)
    at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:459)
    at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:167)
    at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:206)
    at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:180)
    at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:235)
    at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:283)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:200)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:132)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:111)
    at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
    at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:536)
    at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:117)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:56)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:137)
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:591)
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:571)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.NullPointerException
    at com.sun.ejb.codegen.EjbOptionalIntfGenerator.generateSubclass(EjbOptionalIntfGenerator.java:280)
    at com.sun.ejb.codegen.EjbOptionalIntfGenerator.generateOptionalLocalInterfaceSubClass(EjbOptionalIntfGenerator.java:184)
    at com.sun.ejb.containers.BaseContainer.instantiateOptionalEJBLocalBusinessObjectImpl(BaseContainer.java:3860)
    at com.sun.ejb.containers.StatelessSessionContainer.initializeHome(StatelessSessionContainer.java:237)
    at com.sun.ejb.containers.StatelessContainerFactory.createContainer(StatelessContainerFactory.java:63)
    at org.glassfish.ejb.startup.EjbApplication.loadContainers(EjbApplication.java:221)
    ... 43 more

Schwerwiegend:   Exception during lifecycle processing
java.lang.RuntimeException: EJB Container initialization error
    at org.glassfish.ejb.startup.EjbApplication.loadContainers(EjbApplication.java:234)
    at org.glassfish.ejb.startup.EjbDeployer.load(EjbDeployer.java:291)
    at org.glassfish.ejb.startup.EjbDeployer.load(EjbDeployer.java:99)
    at org.glassfish.internal.data.ModuleInfo.load(ModuleInfo.java:206)
    at org.glassfish.internal.data.ApplicationInfo.load(ApplicationInfo.java:313)
    at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:496)
    at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:219)
    at org.glassfish.deployment.admin.DeployCommand.execute(DeployCommand.java:491)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl$2$1.run(CommandRunnerImpl.java:539)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl$2$1.run(CommandRunnerImpl.java:535)
    at java.security.AccessController.doPrivileged(Native Method)
    at javax.security.auth.Subject.doAs(Subject.java:360)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl$2.execute(CommandRunnerImpl.java:534)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl$3.run(CommandRunnerImpl.java:565)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl$3.run(CommandRunnerImpl.java:557)
    at java.security.AccessController.doPrivileged(Native Method)
    at javax.security.auth.Subject.doAs(Subject.java:360)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:556)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:1464)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl.access$1300(CommandRunnerImpl.java:109)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1846)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1722)
    at com.sun.enterprise.v3.admin.AdminAdapter.doCommand(AdminAdapter.java:534)
    at com.sun.enterprise.v3.admin.AdminAdapter.onMissingResource(AdminAdapter.java:224)
    at org.glassfish.grizzly.http.server.StaticHttpHandlerBase.service(StaticHttpHandlerBase.java:189)
    at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:459)
    at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:167)
    at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:206)
    at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:180)
    at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:235)
    at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:283)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:200)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:132)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:111)
    at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
    at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:536)
    at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:117)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:56)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:137)
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:591)
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:571)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.NullPointerException
    at com.sun.ejb.codegen.EjbOptionalIntfGenerator.generateSubclass(EjbOptionalIntfGenerator.java:280)
    at com.sun.ejb.codegen.EjbOptionalIntfGenerator.generateOptionalLocalInterfaceSubClass(EjbOptionalIntfGenerator.java:184)
    at com.sun.ejb.containers.BaseContainer.instantiateOptionalEJBLocalBusinessObjectImpl(BaseContainer.java:3860)
    at com.sun.ejb.containers.StatelessSessionContainer.initializeHome(StatelessSessionContainer.java:237)
    at com.sun.ejb.containers.StatelessContainerFactory.createContainer(StatelessContainerFactory.java:63)
    at org.glassfish.ejb.startup.EjbApplication.loadContainers(EjbApplication.java:221)
    ... 43 more

Schwerwiegend:   Exception while loading the app
Schwerwiegend:   Exception while loading the app : EJB Container initialization error
java.lang.NullPointerException
    at com.sun.ejb.codegen.EjbOptionalIntfGenerator.generateSubclass(EjbOptionalIntfGenerator.java:280)
    at com.sun.ejb.codegen.EjbOptionalIntfGenerator.generateOptionalLocalInterfaceSubClass(EjbOptionalIntfGenerator.java:184)
    at com.sun.ejb.containers.BaseContainer.instantiateOptionalEJBLocalBusinessObjectImpl(BaseContainer.java:3860)
    at com.sun.ejb.containers.StatelessSessionContainer.initializeHome(StatelessSessionContainer.java:237)
    at com.sun.ejb.containers.StatelessContainerFactory.createContainer(StatelessContainerFactory.java:63)
    at org.glassfish.ejb.startup.EjbApplication.loadContainers(EjbApplication.java:221)
    at org.glassfish.ejb.startup.EjbDeployer.load(EjbDeployer.java:291)
    at org.glassfish.ejb.startup.EjbDeployer.load(EjbDeployer.java:99)
    at org.glassfish.internal.data.ModuleInfo.load(ModuleInfo.java:206)
    at org.glassfish.internal.data.ApplicationInfo.load(ApplicationInfo.java:313)
    at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:496)
    at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:219)
    at org.glassfish.deployment.admin.DeployCommand.execute(DeployCommand.java:491)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl$2$1.run(CommandRunnerImpl.java:539)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl$2$1.run(CommandRunnerImpl.java:535)
    at java.security.AccessController.doPrivileged(Native Method)
    at javax.security.auth.Subject.doAs(Subject.java:360)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl$2.execute(CommandRunnerImpl.java:534)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl$3.run(CommandRunnerImpl.java:565)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl$3.run(CommandRunnerImpl.java:557)
    at java.security.AccessController.doPrivileged(Native Method)
    at javax.security.auth.Subject.doAs(Subject.java:360)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:556)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:1464)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl.access$1300(CommandRunnerImpl.java:109)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1846)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1722)
    at com.sun.enterprise.v3.admin.AdminAdapter.doCommand(AdminAdapter.java:534)
    at com.sun.enterprise.v3.admin.AdminAdapter.onMissingResource(AdminAdapter.java:224)
    at org.glassfish.grizzly.http.server.StaticHttpHandlerBase.service(StaticHttpHandlerBase.java:189)
    at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:459)
    at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:167)
    at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:206)
    at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:180)
    at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:235)
    at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:283)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:200)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:132)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:111)
    at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
    at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:536)
    at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:117)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:56)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:137)
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:591)
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:571)
    at java.lang.Thread.run(Thread.java:745)
 
K

kneitzel

Gast
Nach meinem Verständnis musst Du dem System auch mitteilen, dass TheGreeter ein bean ist. Ich hätte da jetzt ein @ManagedBean oder so erwartet.
https://docs.oracle.com/javaee/6/tutorial/doc/girch.html ist da evtl. von Interesse.

Aber hier gibt es bestimmt noch größere Experten als mich, die das bestimmt alles noch besser sagen können.

Alternative wäre statt der Annotations ein Application Configuration file.
 

denis7788

Bekanntes Mitglied
Hi!
hab versucht die Implementierung zu annotieren (@Named und @ManagedBean), hat aber leider nicht geholfen. Auch nicht das Erstellen einer beans.xml.
Die Klassen liegen bei mir in verschiedenen Paketen. Kann das zu Problemen führen?
 

denis7788

Bekanntes Mitglied
Ok, habe den "Fehler" gefunden.
In der bean.xml habe ich das bean-discovery-mode Attribut auf "all" gesetzt. Dieses war auf "annotated" gesetzt. Scheinbar wurde die Klasse zuvor nicht als Bean erkannt, also hattest du recht @kneitzel ;)
Kann mir jemand sagen, wieso? Ich hab sowohl @Named als auch @Stateless auf der Klasse TheGreeter gesetzt.
 
K

kneitzel

Gast
Sorry, dazu kann ich nicht ganz so viel sagen. Ich habe mir direkt Spring angetan und damit direkt meine ersten Schritte gemacht.

Dort gibt es dann die Möglichkeit, die Beans per Annotations oder eben per XML zu definieren. Die Annotations dort sind aber natürlich Spring spezifisch:
@Service("serviceName") wäre dann z.B. beim eigentlichen bean.

Oder eben als xml wäre es bei Spring dann sowas:
Code:
<?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">

    <bean id="serviceName" class="some.package.TheClassName" />

</beans>

Aber das Alles wird Dir leider nicht wirklich helfen fürchte ich.
 

stg

Top Contributor
GlassFish 8? Da möchte ich mal sehen, wo du den her hast. Die aktuelle Version ist 4.1.1.

Ich gehe mal davon aus, dass du GF 4.x verwendest.
Eine beans.xml brauchst du in einer JEE7 Web-Anwendung auf dem GF nicht mehr, um die Dependency Injection zu aktivieren.
Sofern du hier also keine sonstigen Konfiguration vornehmen willst/musst, lösch die Datei einfach.

Desweiteren brauchst du dein Interface Greeter gar nicht. Interfaces für Services sind nur interessant, wenn du den Service nicht nur lokal, sondern auch remote einsetzen willst, oder aber, wenn du mehr als eine Implementierung deines Services anbieten willst.
Sollte später mal eine alterntive Implementierung hinzukommen, so ist das aber kein großer Aufwand erst dann das Interface zu erstellen, wenn es wirklich benötigt wird. Interface kannst du also auch löschen.

Nun solltest du wissen, dass man mit CDI quasi nahezu alles in alles injizieren kann. Auch auf verschiedene Art und Weise. Du nennst deinen Greeter im GreetingManager "service", daher gehe ich nun einfach mal davon aus, dass es sich beim Greeter selbst um eine EJB Session Bean handeln soll.
Benennen deine Klasse TheGreeter einfach um in Greeter und streiche dort das Interface. Stattdessen annotierst du diese Implementierung einfach mit @Stateless. Damit ist es auch schon eine stateless EJB Session Bean, die von CDI erkannt wird und injiziert werden kann. Deine Klasse GreetingManager kann dann genauso bleiben, wie sie ist.
 
K

kneitzel

Gast
@stg Da würde ich dann aber mit einer Design / Verständnisfrage anknüpfen wollen. Wäre nett, wenn Du dazu noch etwas sagen könntest.

Also deine Antwort hat mich etwas zum Nachdenken gebracht. Das man das Interface prinzipiell weglassen kann, ist von der Logik her ja verständlich, aber dann müsste man doch eigentlich die ganze Dependency Injection in Frage stellen. Dann habe ich ja eh die Abhängigkeit zur Implementation. Sollte es später auch mal andere Implementationen geben, dann könnte ich ja immer noch DI zusammen mit dem Interface einbauen.

(Sehr vieles kann man halt ganz ohne DI machen. Im .Net Umfeld haben wir keinerlei Framework diesbezüglich und das, was wir in unseren Produkten so haben, sind dann maximal so eine Art Plugin-System, d.h. wir binden zur Laufzeit weitere DLLs ein (die dann Klassen haben müssen, die von unseren Klassen ableiten oder eines unserer Interfaces implementieren).

Dass das alles geht und machbar ist, ist somit verständlich. Nur eben habe ich jetzt ein kleines Verständnisproblem, dass man DI einsetzen soll ohne dass man die Dependency zur Implementation über ein Interface entfernt.

Schon einmal vielen Dank!
 

stg

Top Contributor
Die Abhängigkeit zur Implementierung hat man, aber diese ist nicht so "starr", wie man zunächst vielleicht annehmen könnte.
Zum einen ist es wie zuvor schon bereits gesagt leicht Refactoring zu betreiben und hinterher, wenn es nötig wird, ein Business-Interface für den Service hinzuzuügen. Dazu kann man dann (z.B., es gibt auch andere Möglichkeiten) einfach ein Interface mit dem ursprünglichen Namen der Klasse (hier dann also Greeter) erstellen und die Implementierung umbennen (hier von Greeter zu TheGreeter, so wie es ursprünglich war) und zusätzlich mit @Local(Greeter.class) annotieren.
Dann hat man eine EJB Session Bean mit Local Business Interface anstatt einer SB mit "no interface view", wie es vorher war.
Der Client, welcher den Service nutzt, bekommt von der Änderung aber nichts mit.

Das, was man per CDI im Client bekommt, ist nun aber eine vom Container verwaltete Instanz, was viele Vorteile bietet, die man nicht hätte, wenn der Client selbst eine Instanz erzeugt. So hat man oft im Service weitere Abhängigkeiten, wie etwa einen Persistence Context, einen Session Context und / oder Abhängigkeiten zu weiteren Services, welche dann vom Container ebenfalls automatisch gesetzt werden. Erzeugt man die Instanz selbst mit new, dann funktioniert dort die DI nicht (so ohne weiteres).
Die Instanz, die man bekommt, ist (hier im Falle einer EJB Session Bean) aber in Wirklichkeit sogar ein Proxy. Sämtliche Aufrufe des Clients beim Service gehen zunächst durchs Framework, und man bekommt zusätzliche Features wie z.B. TransaktionsManagement oder ConcurrencyManagement geschenkt. Bei einer durch new erstellten Instanz, die nicht vom Container verwaltet wird, fällt auch das weg.
 
K

kneitzel

Gast
Vielen Dank für deine Ausführungen. Das hat mir beim Verständnis weiter geholfen.
 

Ähnliche Java Themen

Neue Themen


Oben