\documentclass{uebung}

\author{Linus Nagel}
\chapter{1}

\begin{document}

\maketitle

\begin{exercises}
    \item \textbf{Welche Nachteile ergeben sich durch bisherige Schichtentrennung bei der Client-Server-Programmierung mit Stand-Alone Clients?}

    Bei Stand-Alone Clients ergeben sich folgende Nachteile:
    \begin{itemize}
        \item Jeder Client öffnet eigene Datenbankverbindungen, was bei vielen Clients zu einer hohen Belastung des Datenbankservers führt.
        \item Die Datenbankverbindungsdaten liegen als \texttt{.class}-Dateien auf dem Client und können per Decompiler ausgelesen werden – ein erhebliches Sicherheitsrisiko.
        \item Es fehlt eine zentrale Kontrolle über Transaktionen, Caching und Ressourcenpooling.
    \end{itemize}

    \item \textbf{Welche Nachteile ergeben sich durch bisherige Schichtentrennung bei der Client-Server-Programmierung mit Web Clients?}

    Bei Web Clients treten folgende Nachteile auf:
    \begin{itemize}
        \item Kein einfaches Clustering (Lastverteilung und Ausfallsicherheit).
        \item Kein zentraler Cache – häufig angefragte Daten müssen immer wieder neu aus der Datenbank geladen werden.
        \item Threadinterferenzen müssen manuell durch den Programmierer verhindert werden.
    \end{itemize}

    \item \textbf{Was ist ein Application Server?}

    Ein Application Server ist eine Laufzeitumgebung für Jakarta EE-Komponenten. Er stellt Container (z.B. EJB-Container, Web-Container) bereit und bietet standardisierte Dienste wie Transaktionssteuerung (JTA), Sicherheit (JAAS), Namensdienst (JNDI), Messaging (JMS) und Persistenz (JPA). Bekannte Beispiele sind WildFly, WebSphere und WebLogic.

    \item \textbf{Worum handelt es sich bei einer Session Bean?}

    Eine Session Bean ist eine Komponente der Jakarta Enterprise Beans (EJB), die die Geschäftslogik einer verteilten Anwendung kapselt. Sie wird im EJB-Container des Application Servers ausgeführt und kann von Clients (lokal, remote oder als Webservice) aufgerufen werden. Es gibt drei Typen: Stateless, Stateful und Singleton Session Beans.

    \item \textbf{Worin liegt der Unterschied zwischen Stateless und Stateful Session Beans?}

    \begin{itemize}
        \item \textbf{Stateless Session Bean:} Sie speichert keinen client-spezifischen Zustand. Der Container verwaltet einen Pool von Instanzen. Bei jedem Aufruf kann eine beliebige Instanz verwendet werden. Nach der Methode werden die Daten nicht aufbewahrt.
        \item \textbf{Stateful Session Bean:} Sie behält über mehrere Aufrufe hinweg einen client-spezifischen Zustand. Für jeden Client wird eine eigene Instanz erzeugt und bei späteren Aufrufen dieselbe Instanz wiederverwendet.
    \end{itemize}

    \item \textbf{Welche Möglichkeiten gibt es für einen Aufruf einer Session Bean?}

    \begin{itemize}
        \item \textbf{Lokaler Aufruf:} Innerhalb derselben Java Virtual Machine (z.B. von einer anderen Bean).
        \item \textbf{Remoter Aufruf:} Von einer anderen JVM (z.B. Standalone-Client).
        \item \textbf{Webservice-Aufruf:} Nur für Stateless Session Beans möglich, über SOAP oder REST.
    \end{itemize}

    \item \textbf{Wie wird eine Stateless Session Bean erstellt?}

    \begin{enumerate}
        \item Erstellen eines Business-Interfaces (mit \texttt{@Remote} oder \texttt{@Local}), das die öffentlichen Methoden deklariert.
        \item Erstellen einer Klasse, die das Interface implementiert und mit \texttt{@Stateless} annotiert wird.
    \end{enumerate}

    \item \textbf{Welche Schritte sind für einen Client notwendig, um eine Methode einer Stateless Session Bean aufzurufen?}

    \begin{enumerate}
        \item Erstellen eines \texttt{InitialContext} mit den nötigen Properties (z.B. Provider-URL, Context Factory).
        \item Aufruf von \texttt{lookup()} mit dem JNDI-Namen der Bean.
        \item Cast des zurückgegebenen Proxy-Objekts auf das Remote-Interface.
        \item Aufruf der gewünschten Methode auf dem Proxy.
    \end{enumerate}

    \item \textbf{Wie muss eine Stateful Session Bean annotiert werden?}

    Die Bean-Klasse wird mit \texttt{@Stateful} annotiert.

    \item \textbf{Wie kann bei einer Stateful Session Bean angegeben werden, dass eine Bean-Instanz nicht mehr benötigt wird und vom Server zerstört werden kann?}

    Eine Methode (z.B. \texttt{beenden()}) wird mit der Annotation \texttt{@Remove} versehen. Nach dem Aufruf dieser Methode zerstört der Container die Instanz.

    \item \textbf{Welchen Unterschied gibt es bei Stateful Session Beans bezüglich des JNDI-Namens?}

    Beim Lookup muss an den JNDI-Namen \texttt{?stateful} angehängt werden. Beispiel: \texttt{ejb:/meineBean?stateful}

    \item \textbf{Worum handelt es sich bei Singleton Session Beans?}

    Eine Singleton Session Bean wird nur einmal pro Application Server instanziiert. Diese eine Instanz wird von allen Clients gemeinsam genutzt. Sie eignet sich für globale Ressourcen oder zentrale Dienste.

    \item \textbf{Wie werden Singleton Session Beans erstellt?}

    Die Klasse wird mit \texttt{@Singleton} annotiert. Optional kann \texttt{@Startup} hinzugefügt werden, damit die Instanz bereits beim Serverstart erzeugt wird (sonst beim ersten Lookup).

    \item \textbf{Welche Probleme können durch einen gemeinsamen Zugriff von mehreren Clients auf eine Singleton Session Bean theoretisch entstehen?}

    Da mehrere Threads gleichzeitig auf dieselbe Instanz zugreifen können, kommt es zu Threadinterferenzen, wenn sie lesend und schreibend auf gemeinsame Daten zugreifen. Dies kann zu Dateninkonsistenz und unerwartetem Verhalten führen.

    \item \textbf{Wie kann diesen Problemen programmatisch entgegnet werden?}

    Es gibt zwei Ansätze:
    \begin{itemize}
        \item \textbf{Container Managed Concurrency (Standard):} Mit \texttt{@Lock(LockType.READ)} für lesende und \texttt{@Lock(LockType.WRITE)} für schreibende Methoden. Der Container sorgt dann für die nötige Synchronisation.
        \item \textbf{Bean Managed Concurrency:} Die Bean wird mit \texttt{@ConcurrencyManagement(ConcurrencyManagementType.BEAN)} annotiert und der Programmierer verwendet eigene Synchronisationsmechanismen (z.B. \texttt{synchronized}).
    \end{itemize}

    \item \textbf{Erstellen Sie eine Stateless Session Bean, die eine Methode zur Verschlüsselung eines Strings bereitstellt.}

    \textbf{Remote-Interface:} \inputminted{java}{../../server/src/main/java/org/example/demo/uebung1/aufgabe16/EncryptorRemote.java}

    \textbf{Bean-Klasse:} \inputminted{java}{../../server/src/main/java/org/example/demo/uebung1/aufgabe16/Encryptor.java}

    \textbf{Standalone-Client:} \inputminted{java}{../../client/src/main/java/org/example/demo/uebung1/aufgabe16/Client.java}

    \item \textbf{Erstellen Sie eine Stateful Session Bean, die einen Zähler zur Verfügung stellt.}

    \textbf{Remote-Interface:} \inputminted{java}{../../server/src/main/java/org/example/demo/uebung1/aufgabe17/CounterRemote.java}

    \textbf{Bean-Klasse:} \inputminted{java}{../../server/src/main/java/org/example/demo/uebung1/aufgabe17/Counter.java}

    \textbf{Client (mehrfache Aufrufe auf derselben Instanz):} \inputminted{java}{../../client/src/main/java/org/example/demo/uebung1/aufgabe17/Client.java}

    \item \textbf{Warum liefert die get-Methode aus Aufgabe 17 bei einem erneuten Aufruf der Testklasse immer wieder den Startwert des Zählers?}

    Bei jedem Aufruf der \texttt{main}-Methode wird eine neue Instanz der Stateful Session Bean erzeugt, da der \texttt{lookup} jedes Mal eine frische Bean-Instanz zurückgibt. Der alte Zustand (Zählerstand) ist nur innerhalb derselben Client-Sitzung gültig. Wird das Client-Programm neu gestartet, gibt es eine neue Instanz mit dem Anfangswert 0. Möchte man den Zähler über mehrere Programmstarts hinweg speichern, müsste man ihn in einer Datenbank oder Datei persistieren.

\end{exercises}

\end{document}
