Testen und Mocken statischer Methoden in Java

21 Kommentare

Immer wieder begegnet mir der Mythos vom bösen statischen Code, der schwer zu testen und nicht zu mocken ist. Architekten und erfahrene Entwickler erzählen dieses Märchen, und die Berufsanfänger greifen es auf und wiederholen es: „Statischer Code ist böse. Er ist schwer zu testen. Statische Methoden lassen sich nicht mocken.“

DAS.IST.BLÖDSINN.

Und ich werde zeigen warum.

Testen statischer Methoden

Warum sollten statische Methoden schwerer zu testen sein als nicht-statischer Code in Instanzmethoden? Werfen wir einen Blick auf das folgende Beispiel:

public final class StringUtil {
 
   public static String nullSafeTrim(String s) {
      return s == null ? "" : s.trim();
   }
}

Um dieses String Utility zu testen, schreibt man Unit-Tests so wie für jeden anderen Code. Man schreibt die Tests vor (Glückwunsch, Sie sind ein echter Agilist), während oder nach der Implementierung, immer eine hohe Testabdeckung im Hinterkopf. Wenden Sie alle Ihnen bekannte TDD- und BDD-Methoden an (sofern die Arbeit dadurch leichter wird):

public class StringUtilTest {
 
   @Test public void shouldHandleNull() {
      assertEquals("", StringUtil.nullSafeTrim(null));
   }
 
   @Test public void shouldHandleEmptyString() {
      assertEquals("", StringUtil.nullSafeTrim(""));
   }
 
   @Test public void shouldTrimWhiteSpace() {
      assertEquals("foo bar", StringUtil.nullSafeTrim("\t\n\r foo bar \r\n\t"));
   }
 
}

Man mag nun einwenden, dass eine statische Methode vielleicht Abhängigkeit zu anderen Klassen hat und man daher verloren hat. Naja, entweder rechnen wir diese abhängigen Klassen der zu testenden Unit zu (was allerdings die Komplexität erhöht) oder man mockt diese Abhängigkeiten. „Meine statische Methode verwendet den bösen new-Operator. Ich kann die abhängige Klasse nicht mocken.“

Das stimmt schon, gilt aber genauso für nicht-statischen Code! Falls sich die Abhängigkeit über ein Interface abstrahieren lässt, können wir auf Setter-Injektion zurückgreifen. Nehmen wir an, dass StringUtil von einem Interface Dependency abhängt und wir dafür eine Mock-Implementation bereitstellen wollen:

public interface Dependency {
   void doSomething();
}
 
public final class StringUtil {
 
   private static Dependency dependency;
 
   public static void setDependency(Dependency d) {
      dependency = d;
   }
   ...
}

In unserem Test können wir die Mock-Implementierung wie folgt injizieren:

public class DependencyMock implements Dependency {
 
   public void doSomething() {
   }
}
 
public class StringUtilTest {
 
   @Before public void setUp() {
      StringUtil.setDependency( new DependencyMock() );
   }
   ...
}

Mocken statischer Methoden

„Ich verwende EasyMock oder Mockito. Diese Frameworks können meine statischen Methoden nicht mocken. Statischer Code ist böse.“ Dann haben Sie keine Ahnung von der Dunklen Seite der Macht … eh … von der Macht von PowerMock!

PowerMock ist eine JUnit-Erweiterung, die die Möglichkeiten von EasyMock und Mockito um das Mocken statischer Methoden (und einigem mehr) erweitert. Gehen wir von folgendem Szenario aus:

Unsere zu testende Unit ist die Klasse Calculator, die die Berechnung zweier Integer-Werte an die Klasse MathUtil delegiert, die nur statische Methoden anbietet:

public class Calculator {
 
   public int add(int a, int b) {
      return MathUtil.addInteger(a, b);
   }
}
 
public abstract class MathUtil {
 
   public static final int addInteger(int a, int b) {
      return a + b;
   }
 
   private MathUtil() {}
}

Aus einem obskuren fachlichen Grund möchten wir das Verhalten von MathUtil mocken, weil in unserem Testszenario die Addition andere Ergebnisse als sonst liefern soll (im echten Leben müssten wir ggfs. ein Webservice-Aufruf oder einen Datenbankzugriff mocken). Wie kriegen wir das hin? Werfen wir einen Blick auf den folgenden Test:

@RunWith(PowerMockRunner.class)
@PrepareForTest( MathUtil.class )
public class CalculatorTest {
 
   /** Unit under test. */
   private Calculator calc;
 
   @Before public void setUp() {
      calc = new Calculator();
 
      PowerMockito.mockStatic(MathUtil.class);
      PowerMockito.when(MathUtil.addInteger(1, 1)).thenReturn(0);
      PowerMockito.when(MathUtil.addInteger(2, 2)).thenReturn(1);
   }
 
   @Test public void shouldCalculateInAStrangeWay() {
      assertEquals(0, calc.add(1, 1) );
      assertEquals(1, calc.add(2, 2) );
   }
}

Zunächst verwenden wir einen speziellen Test-Runner, der vom PowerMock-Framework zur Verfügung gestellt wird. Mit der Annotation @PrepareForTest( MathUtil.class ) wird die zu mockenden Klasse vorbereitet. Diese Annotation kann auch eine ganze List von zu mockenden Klassen verarbeiten. In unserem Beispiel besteht die Liste aus einem Element MathUtil.class.

In der setup-Methode rufen wir PowerMockito.mockStatic(...) auf. (Wir hätten für die Verwendung der Methode mockStatic einen statischen Import schreiben können, ohne wird aber besser sichtbar, woher die Methode stammt.)

Nun definieren wir das Mock-Verhalten unserer statischen Methode, indem wir PowerMockito.when(...) aufrufen. Danach kommen in den eigentlichen Tests die typischen Assertions.

Wie Sie sehen konnten, haben wir gerade eine statische Methode gemockt!

Um das Beispiel laufen zu lassen, fügen Sie die folgenden Abhängigkeiten in Ihre pom.xml ein (vorausgesetzt Sie verwenden Maven):

<properties>
	<powermock.version>1.4.9</powermock.version>
</properties>
 
<dependencies>
	<dependency>
		<groupId>org.powermock</groupId>
		<artifactId>powermock-module-junit4</artifactId>
		<version>${powermock.version}</version>
		<scope>test</scope>
	</dependency>
	<dependency>
		<groupId>org.powermock</groupId>
		<artifactId>powermock-api-mockito</artifactId>
		<version>${powermock.version}</version>
		<scope>test</scope>
	</dependency>
	<dependency>
		<groupId>org.mockito</groupId>
		<artifactId>mockito-core</artifactId>
		<version>1.8.5</version>
		<scope>test</scope>
	</dependency>
	<dependency>
		<groupId>junit</groupId>
		<artifactId>junit</artifactId>
		<version>4.8.2</version>
		<scope>test</scope>
	</dependency>
</dependencies>

Zusammenfasssung

Ich habe gezeigt, wie Unit-Tests für statische Methoden geschrieben werden. Das war einfach. Mit Hilfe des PowerMock Frameworks waren wir sogar in der Lage, das Verhalten von statischen Methden zu mocken.

Werfen Sie einen Blick in die Dokumentation von PowerMock, um zu sehen, was PowerMock sonst noch alles kann.

Tobias Trelle

Diplom-Mathematiker Tobias Trelle ist Senior IT Consultant bei der codecentric AG, Solingen. Er ist seit knapp 20 Jahren im IT-Business unterwegs und interessiert sich für Software-Architekturen und skalierbare Lösungen. Tobias hält Vorträge auf Konferenzen und Usergruppen und ist Autor des Buchs „MongoDB: Ein praktischer Einstieg“.

Share on FacebookGoogle+Share on LinkedInTweet about this on TwitterShare on RedditDigg thisShare on StumbleUpon

Kommentare

  • Fabian Lange

    Thanks for documenting this. As you say, there is no real testing reason to avoid statics. However statics do have a real design impact. They often violate the „I“ of SOLID. They also have very often concurrency issues and they are often a Singleton Antipattern.

    However, if you have a good reason for a static, you can test it.

  • Michael Vitz

    10. November 2011 von Michael Vitz

    But you must distinguish between static methods which are utility methods (as in your example) or if they are real business relevant methods. Utility methods should be most of the time static as they have no context and no dependencies, but business methods should use static as few as possible in my opinion.

  • Carsten Bochner

    11. November 2011 von Carsten Bochner

    Powermock is indeed a tool that might help you in certain situations. But it should never be a justification to use static-methods at all.
    Static methods break the basic principal of Java development: Object Orientation. And breaking this principal needs a really solid reason. If you encounter such reason and therefore implement a static method, then Powermock is your true friend. Otherwise Powermock might turn out to be a false friend in the long run, hiding true design problems.

    Furthermore you should mention that Powermock is really slow. The trickery it is doing with the classloader take quite some time and might slow down your Unit-Tests dramatically (at least that was my experience).

    Two other blog-posts to mention here:

  • Mirko Novakovic

    14. November 2011 von Mirko Novakovic

    Hi Carsten, hi Niklas

    this reminds me of the discussions in the 90s when talking to Smalltalk guys 🙂

    Even if I am not a big fan of static methods and I agree that they should be used carefully, I don’t see a general violation of OO principles or a big problem with static. Maybe in a very theoretical discussion (like discussing if primitive types in Java are violating OO), but in fact static methods/fields can be very useful in an OO application. A Singleton implementation is a good example for a static method usage – which is maybe the No. 1 pattern of the GoF book that defines „Elements of Reusable *Object-Oriented* Software“.

    By the way we could also discuss if dependency injection (Niklas used it as a OO paradigma) jeopardize the whole concept of OO. Most DI implementations make widely use of Setter Injection – which violates the „Good citizen“ principle of objects and makes it hard to define immutable fields etc. and can be seen as a code smell. Constructor injection is a much more OO-compatible approach but not widly used, even if it is supported by Spring and was uses by PicoContainer, one of the first Java DI implementations. Is this a big problem? No 🙂

    Another interesting question in this context: Are annotations object-oriented? Which OO concept are they implementing?

    Mirko

  • Niklas Schlimm

    Hi Mirko, all agreed. Static methods are used in many situations where they may make sense. However, there not compatible with the OO idea (which may be theory – but is NOT an academic statement if you look at some apps that seem to use static as a standard – don’t just think of clean coded apps :-)). It’s not easy to judge – for the average developer – when to use them. Can you give a sustainable list of decision parameters when to use static for the Java beginner?
    Cheers, Niklas

    • Mirko Novakovic

      17. November 2011 von Mirko Novakovic

      Hi Niklas,

      not easy – what about:

      1. If you don’t have a state in an object. (e.g. utility methods)
      2. If you have a state which scope is wider than the object. (e.g. singleton)

      Mirko

      • Niklas Schlimm

        Seriously, you need to delegate your board member position and spend some time in a real world project again 😉 this cannot be your idea of judging when to use static!!! Most EJBs and Spring services don’t have state. Are they static candidates? That you don’t get me wrong, I understand your second point, but (1) its still not a sufficient design guideline and (2) there are also OO solutions that are better cause more flexible then using static in these cases. CDI and Spring for instance use proxies to mask getters of broader scoped objects. The proxies get injected as members of the consired object and when you call the object they return the appropriate instance for your transaction. Static remains a bad code smell if you see it often in a project. Your trying to make an argument for static although its much more practical to just avoid them 😉 „avoid“ does not mean you can always do good without static. Cheers, Niklas

        • Mirko Novakovic

          21. November 2011 von Mirko Novakovic

          Niklas,

          the „problem“ is that we are discussing on a different level. I am talking about „pure Java“ and you are now discussing concepts like EJB or Spring. Stateless Session Beans (which you probably mean with EJB, as Entity and Stateful Session Beans have state) or Spring Services that are equal to Stateless Session Beans will hide the implementation from developers – which is good, but doesn’t mean that they are not using static. In fact a Spring bean is „singleton“ per default – I am not sure how they implement this internally but for sure they are „caching“ the beans in a static Map or whatever – the same is true for Session Beans – that are pooled by the container, etc. etc.

          But again, I am not argueing that static is good. I am just saying the Java as a language has not always a clean OO solution for you. Frameworks like Spring or CDI can help to hide these issues from the developer.

          By the way, how do you explain dynamic proxies or even bytecode instrumentation (which is used for the same type of problems, by the same frameworks) to a Java beginner? I am always getting confused in the debugger when I see what a simple Annotation makes of my so called „Plain Old Java Object“ at runtime 🙂

          Mirko

      • Niklas Schlimm

        PS: I love this „utility“ example. Please explain „utility“!! 😉 we’ve made enough projects together to know that we also messed up with what we mean by „utility“ ;-)) know what you mean by that but how can I explain that to a Java beginner?

  • Frank Hinkel

    Hallo Tobias,
    ich bin auch froh dass es Möglichkeiten gibt statischen Code zu mocken. Bis auf wenige wirklich primitive Methoden habe ich aber seit Jahren keine einzige statische schreiben müssen.

    Ich entdecke im Code von Web-Projekten, die etwas älter sind deutlich mehr statische „Helper“ als in moderneren Anwendungen.

    Vielleicht muss man das Gut oder Böse auch daran fest machen WAS man eigentlich programmiert. Eine RIA oder normale Applikation haben meiner Meinung nach andere Beziehungen zu statischem Code, Zuständen und Zugriffspfaden und deutlich mehr Anwendungsfälle für statics.

    Mein Eindruck in Web-Anwendungen(!) ist allerdings, dass „statics“ bei dem Versuch von Entwicklern entstehen, Verantwortlichkeiten zu separieren und Funktionalitäten zu delegieren. Was ja an sich erstmal nicht schlecht ist… endet dann aber aufgrund von fehlendem Abstraktionsvermögen oder mangelnder Erfahrung in OO Designtechniken in einer Fülle von statischen Helper klassen, die an sich zwar die reine Funktionalität erfolgreich kapseln aber im Gegensatz zu einem guten Design nicht die eigentlichen Intentionen des Entwicklers widerspiegeln. Wer ein wohlgeformtes Anwendungsdesign vor sich findet, anstatt eine Vielzahl von statischen Helpern, kennt nicht nur ihre reine Funktionalität, sondern auch ihren semantischen Zusammenhang im Gesamtgefüge. Das ist bei statischem Code nur dann in Ansätzen der Fall wenn die Zugriffsmodifikatoren eingeschränkt werden. Aber „public static“, vernichtet meiner Meinung nach (meistens) jede zielgerichtete Designabsicht.

    Der Kern ist: Semantik kann ja nicht nur durch aufeinander folgende Codezeilen und ein paar „If’s“ abgebildet werden, sondern durch komplexe Zusammenhänge und Beziehungen in unterschiedlichen Intensitäten. Der Reflex das Design damit abgeschlossen zu haben, dass Lines of Code an statische Helper separiert wurden, begegnet mir in vielen Projekten. 😉

    Ein anderes Problem weswegen statics für mich in Web-Anwedungen böse sind ist, dass sie oft aus Bequemlichkeit verwendet werden, dies geht aber auf Kosten des Verständnisses am eigentlichen vorgefunden Code. Wenn ich fremden Code warte, spare ich mir so die Mühe um über Scopes nachzudenken, über Ablaufreihenfolgen, Zugriffspfade usw. Ich komme jederzeit und von überall dran, ist doch super. Alles schön stateless, passt. Dieser kurzfristige Vorteil hält einen aber dann davon ab tiefer in den Code einzusteigen und Zusammenhänge verstehen zu müssen… und das Neue eben da zu platzieren wo es hingehört. Damit hat für mich das hinzufügen von statischen Methoden eher den Charakter des „Drum-herum-bauens“ und nicht des überlegte Integrieren in ein bestehendes Designkonzept.

  • Mirko Novakovic

    17. November 2011 von Mirko Novakovic

    Hallo Frank,

    warum soll eine RIA mehr Anwendungsfälle für static haben als normale Webanwendungen? Einerseits sind Sie aus meiner Sicht serverseitig sehr ähnlich und andererseits sehe ich keinen echten Zusammenhang zwischen statischen Methoden und dem Anwendungstyp.

    Deine Argumente bei den Zugriffsmodifikatoren würde ich sogar umdrehen – aus meiner Sicht macht eigentlich nur „public static“ bei static Methoden Sinn – wofür könnte man denn „private static“ oder „protected static“ bei Methoden gebrauchen?

    Für mich ist die Nutzung von static in erster Linie mit der Programmiersprache und den Elementen/Konzepten der Sprache verbunden. Schau Dir beispielsweise java.lang.Math an – wo würdest Du die Funktionen unterbringen? Durch die primitiven Datentypen (die ich persönlich sehr gut finde, auch wenn Sie OO Prinzipien brechen) hat man aus meiner Sicht keine Möglichkeiten die Funktionen sinnvoll ohne static abzubilden. Bei java.util.Collections sieht es ähnlich aus – wobei man die Funktionen teilweise auch in Collection Klassen unterbringen könnte.

    Die Schwierigkeit von static im Umfeld von Webanwendungen sehe ich vor allem im Bereich der Nebenläufigkeit von Webanwendungen. Hier treten bei static sehr schnell Probleme auf, die sehr oft übersehen werden.

    Grüße
    Mirko

  • Tobias Trelle

    Thank you for all your feedback so far. I have to admit I’m a little bit suprised about the direction our discussion is taking.

    My intention was to introduce you to a powerful (but not so well known) mocking framework that enables you to mock static methods at last.

    I did NOT encourage the usage of static methods with a single word. I did not say statics are a good design principle in any OO language, nor did I tell you to put your business logic in one large static method.

    But the argument that static methods are bad because they are impossible to mock is gone with PowerMock. That was my point.

    To take part in the pros and cons discussion: which code is „better“:

    A: private static final Logger LOG = LogFactory.getLogger(Some.class);

    B: private Logger LOG = LogFactory.getLogger(Some.class);

    Cheers,
    Tobias

    • Mirko Novakovic

      18. November 2011 von Mirko Novakovic

      I would say it depends on the LogFactory – if the Factory is implemented well, than A and B are very similar. If the Factory is implemented badly, than A is the only good solution otherwise you could have a logger per instance which is normally not what you want.

  • Frank Hinkel

    Hallo Mirko, danke für deine Antwort!

    Deine Skepsis bezüglich des echten Zusammenhangs teile ich. Ich hatte dabei mehrere Punkte im Kopf:

    Das fängt bei dem Einstieg (für den Entwickler) in eine Anwendung an. Normale Applikationen fangen in einem statischen Kontext an wie der klassichen „main“-Methode. In Web-Anwendungen regelt der Container das Ganze im vor hinein. Er zeugt das Servlet-Objekt, startet den Thread für den Request, übergibt dem Servlet dann Response und Request Objekte und passend dazu noch eine fertig ausgelesene Konfiguration. Es geht quasi direkt „nicht statisch“ los und man befindet sich in einem Request und Session Scope.

    Der andere Punkt ist der Gültigkeitsbereich. Wenn in RIAs oder Windows-Applikationen Clientseitig statics verwendet werden, ist das doch in der Regel eine Art Session-Scope. Das heißt Concurrency Probleme treten doch erst dann auf wenn ich selbst anfange Threads zu starten oder? (Okay mit DIR über Concurrency zu reden bringt mich gerade auf dünnes Eis.. aber ich hoffe du weißt wie ich das meine. 🙂 )

    Und es ist so wie du es selbst gesagt hast, in Web-Anwendungen können immer wieder Probleme auftreten aufgrund von gedankenloser oder unwissender Verwendung von statischem Code. (Dynamische Lastverteilung der Threads auf unterschiedliche JVMs, mehrere Requests also Threads auf der gleichen JVM usw.)

    Das andere Thema:
    Gefühlt hat sich der Entwickler bei „static“ den Gedanken gemacht, dass er komplexe Logik aufteilen will. Macht sich dafür eine Util Klasse und fertig. Damit ist der Designprozess abgeschlossen. Wenn das dann noch eine Public Methode ist erkennt man außer „jeder darf alles“ keine Implikation. Wenn man mehr wissen will, muss man eine Referenzprüfung machen. Und wenn man nicht alles im Workspace hat was die eigene public static verwendet? Klar, sowas kann einem immer bei „public“ passieren aber in der Regel ist die Ausführung ja an Objekte gebunden, die man erstmal erzeugen oder organisieren muss und da ist der Griff ins statische Klo schneller und leichtfertiger gemacht finde ich und hat nicht mehr viel mit dem Integrieren in bestehendes Design zu tun. 😉

    Private möchte ich an der Stelle nicht in Schutz nehmen, die Anwendungsfälle die mir da öfter vor die Flinte laufen sind z.B. das Vermeiden von doppeltem Code in einer Klasse mit statischen Methoden. Neben selbst produziertem Code findet man die Kombination aber auch in Klassen wie z.B. java.util.Arrays.

    Aber um ehrlich zu sein wundert mich auch die zweistellige Anzahl der protected static Methoden in meinem aktuellen Workspace (Klassen aus unserem Framework von alt bekannten Autoren). 🙂

    Komm uns doch mal wieder besuchen, dann schauen wir uns das an!

    Viele Grüße,
    Frank

  • Mirko Novakovic

    18. November 2011 von Mirko Novakovic

    Hallo Frank,

    ehrlich gesagt glaube ich, dass Du da was bei Webanwendungen durcheinander bringst. Der „Scope“ (Request, Session, Conversation, App, etc.) hat nichts mit dem Laufzeitverhalten (Thread Handling etc.) direkt zu tun, sondern nur mit dem Lebenszyklus von ganz speziellen Daten, die Du in Deiner Anwendung verwenden möchtest und entsprechend kennzeichnest. Dabei spielt static aus meiner Sicht keine Rolle.

    RIAs sind i.d.R. entweder Javascript auf der Client-Seite oder eine Plugin-Technologie wie Flash, JavaFX oder Silverlight. Das ist auch dann so, wenn man GWT nutzt, weil man den Client Code zwar in Java programmiert – dieser aber mit einem Compiler in Javascript übersetzt wird. Auf dem Server passiert eigentlich das Gleiche wie bei normalen Webanwendungen, d.h. man ruft einen Service (Servlet, Webservice, etc.) auf, der dann im Webcontainer verarbeitet wird.

    Ich verwende static eigentlich nur wenn mir die Sprache (in diesem Fall Java) kein anderes Konstrukt ermöglicht oder es aus anderen Gründen (Performance, Wartbarkeit, etc) sinnvoller ist, statische Methoden zu nutzen und da kann es viele geben.

    Beispielsweise nutzen ja auch viele Anwendungen den static import in Java, um der Mehrfachvererbung aus dem Weg zu geben, die es in Java nicht gibt und die Nutzbarkeit einfachere zu gestalten. Bei JUnit kann man diesen Weg gut sehen – bis Version 3 hast Du die assert* Methoden über eine Vererbung aus einer abstrakten Superklasse bekommen, ab Version 4 machst Du einen statischen import der assert* Methoden aus einer Assert-Utility Klasse. Sicherlich nicht OO-Lehre, aber sinnvoll und angenehm für den Entwickler. Viele Mocking und Assertion Frameworks nutzen das gleiche Konzept.

    Interessant ist auch, dass man in Java statische Variablen schon rein konzeptionell (und damit dann i.d.R. auch statische Methoden) nutzen muss, wenn man die Daten länger oder ausserhalb eines Thread-Stacks halten möchte. Die so genannten GC Roots, die verhindern, dass ein Objekt ansonsten vom GC abgeräumt wird, sind ja nur temp. Variablen auf dem Thread-Stack, statische Variablen und JNI Referenzen aus nativem Code. Sprich: Immer wenn Du in Webanwendungen ein Objekt länger als einen Request halten möchtest, brauchst Du statischen Code. In diesem Fall wird das dann der Session Verwalter des WebContainers sein, der dann irgendwo auf eine statische Variable verweist (wahrscheinlich eine Collection) – alles andere wäre PHP (share nothing) 🙂

    Komme aber gerne mal vorbei und schaue mir das mit den static Methoden an, aber denke immer daran: wenn es von mir ist, dann muss es richtig sein 😉

    Mirko

    • Frank Hinkel

      Magic, dont touch. 😉

      Ich sehe da schon einen Zusammenhang zwischen dem Gültigkeitsbereich eines Requests und der Laufzeit, da für einen Request immer genau ein Thread existiert (ohne Pool sogar explizit dafür gestartet wird). 10 Request = 10 Threads

      http://books.google.de/books?id=15wp6fmAy4sC&pg=PA101&lpg=PA101&dq=kathy+sierra+%22thread+per+request%22&source=bl&ots=SNxCUncotO&sig=gCFXQ7MGlKLeAnVxGY5yojepp4I&hl=de&ei=QnbGTvzNL8eBhQfemo3IDw&sa=X&oi=book_result&ct=result&resnum=1&ved=0CCIQ6AEwAA#v=onepage&q&f=false

      Ich meine damit nicht das EL implizite Attribut requestScope mit seinen „speziellen“ Daten, sondern alle Objekte die im Thread des Requests erzeugt werden und abgeräumt werden können wenn der Thread durch ist.
      Das bedeutet doch im Umkehrschluss, dass man keine Sychronitzationsprobleme hat, wenn man innerhalb dieses Request-Threads Objekte anlegt und dort mit Daten und Zuständen arbeitet.
      Also: Sobald man Singletons verwendet oder Zustände von statischen Variablen setzt, muss man sich um Nebenläuftigkeit gedanken machen.

      • Mirko Novakovic

        21. November 2011 von Mirko Novakovic

        Hallo Frank,

        das ist nicht nur für Web-Applikationen richtig, sondern für jeden Thread in Java. Im Prinzip bleibst Du autark, wenn Du dann alle Objekte innerhalb des Threads neu generierst (ausser Reuqest und Response, die laut Spec auch nicht Threadsafe sind). Damit hast Du wie ich schon oben geschrieben hatte praktisch eine „share nothing“ Architektur, wie bei PHP (mit Außnahme der Session, die aber wie das Servlet auch nicht Threadsafe sind).

        Das bedeutet Dinge wie Spring, Hibernate & Co fallen für quasi aus, weil sie mit „share nothing“ nicht funktionieren, viele andere Dinge gehen dann auch nicht, wie beispielsweise Caches oder Singletons, etc. etc. – ist also auch für Webanwendungen in der Praxis praktisch nicht wirklich durchführbar.

        Andererseits hat ein „share nothing“ Modell natürlich große Vorteile, weil man die Anwendung quasi sehr einfach skalieren kann und sich wenig sorgen um Nebenläufigkeit machen muss.

        Mirko

  • Niklas Schlimm

    Also, das hat sich jetzt vom thema des blogs etwas entfernt aber es klingt für sich genommen fast richtig 😉

Kommentieren

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.