Das ist ja sooo 200x!

Post on 23-Jun-2015

90 views 0 download

description

Das ist ja sooo 200x! Speaker: Jens Schumann Erinnert sich noch jemand an Java-Webentwicklung/Enterprise-Java-Entwicklung streng nach den Vorgaben der J2EE BluePrints und mit Struts als Web Application Framework? Ach! Nie gemacht? Glück gehabt. Diese Session wagt einen Blick zurück in die Enterprise-Java-Steinzeit und zeigt, wie viel Aufwand serverseitige Java-Entwicklung zu Zeiten von J2EE 1.3 und 1.4 wirklich bedeutete und was teilweise heute noch, wenn auch unter der Haube, bei der Verwendung von Java EE, EJB und Friends sowie klassischen Webframeworks passiert.

Transcript of Das ist ja sooo 200x!

Das ist ja sooo 200x!Jens Schumann – open knowledge GmbH

(Sorry – kurzer Werbeblock)

Was wir heute (trotz Testspiel) machen

• Klagen auf hohem Niveau...

• Ja, genau da sind wir gestartet!

• Diese Irrwege haben wir uns erlaubt. Leider.

• Genau genommen gibt es vieles noch heute.

• Das können und sollten wir davon lernen.

Enterprise Java im Jahr 2014

Enterprise Java im Jahr 2014 - Wicket

<!DOCTYPE html><html> <head lang="en"> <meta charset="UTF-8"> <title>Hello World</title> </head> <body>

<p wicket:id="message">Message goes here</p>

</body></html>

Enterprise Java im Jahr 2014 - JSF

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE ...><html ...>

<f:view> Hello World! Today is

<h:outputText value="#{currentTimeBean.currentDate}"> <f:convertDateTime dateStyle="long" timeStyle="long"/> </h:outputText> .

</f:view></html>

Enterprise Java im Jahr 2014 - Spring

@Named

public class CurrentTimeBean {

public Date getCurrentDate() { return new Date(); }

}

Enterprise Java im Jahr 2014 - CDI

@Named@ApplicationScopedpublic class CurrentTimeBean {

public Date getCurrentDate() { return new Date(); }

}

Was wir heute machen

• Jammern auf hohem Niveau...

• Ja, genau da sind wir gestartet!

• Diese Irrwege haben wir uns erlaubt. Leider.

• Genau genommen gibt es vieles noch heute.

• Das können und sollten wir davon lernen.

Am Anfang war...

New Economy

(na gut, nicht ganz am Anfang)(ob Henne oder Ei soll hier nicht geklärt werden)

Am Anfang war...

Web? Ja, mit Applets! Applets?!

public class HelloWorld extends Applet {

public void paint(Graphics g) { Date currentDate = new Date();

DateFormat formatter = DateFormat.getDateTimeInstance(...);

g.drawString( "Hello world! Today is " + formatter.format(currentDate) + "." , 50, 25); }}

Ein Servlet ist ein Applet! Hmmm?!

Although servlets can respond to any types of requests [...],

so they can be thought of as Java applets

that run on servers instead of in web browsers!

Applets mit Java Backend*

public class AppletBackendServlet extends HttpServlet {

protected void doGet(HSR req, HSR resp) throws ... { ObjectOutputStream out = ...; ObjectInputStream in = ...;

Integer customerId = (Integer) in.readObject(); Customer customer = getCustomer(customerId);

out.writeObject(customer); out.flush();

resp.flushBuffer(); ...}}

*Exception and Stream Handling omitted

Web ist Web, also HTML

<html> <head> <title>Hello World!</title> </head>

<body> <script type="application/javascript"> document.write( 'Hello World! Today is ' + new Date() + + '.') </script> </body></html>

Web ist Web, also HTML – Servlet Style

public class DynamicContentServlet extends HttpServlet {protected void doGet(HSR req, HSR resp) throws ... { ... PrintWriter writer = resp.getWriter(); writer.write("<html>"); writer.write("<head><title>Hello World</title>" + "</head><body>");

writer.write("Hello World! Today is "); writer.write(formatter.format(currentDate)); writer.write(".");

writer.write("</body></html>");

resp.flushBuffer();}}

Was wir heute machen

• Klagen auf hohem Niveau...

• Ja, genau da sind wir gestartet!

• Diese Irrwege haben wir uns erlaubt. Leider.

• Genau genommen gibt es vieles noch heute.

• Das können und sollten wir davon lernen.

Microsoft... to the rescue!

Java Server Pages. At it‘s best.

<html> <head><title>Hello World!</title></head> <body>

Hello World! Today is ! Dynamic content here ! . </body></html>

Java Server Pages. At it‘s best.

<html> <head><title>Hello World!</title></head> <body> <% Locale locale = request.getLocale(); Date currentDate = new Date(); DateFormat formatter = DateFormat.getDateTimeInstance(...); %>

Hello World! Today is <%= formatter.format(currentDate) %>. </body></html>

Java Server Pages. Ahh! - JSTL

<html> <head><title>Hello World!</title></head> <body>

<jsp:useBean id="now" class="java.util.Date" />

Hello World! Today is <fmt:formatDate value="${now}" ... />. </body></html>

Wir hatten doch auch Frameworks!

FooBarWizzBangCompany Framework

„Sobald das Framework fertig gestellt ist, wird alles wirklich gut!“

Open Source schließt die Lücke

public class TestAction extends Action {

public ActionForward execute( ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws E... {

request.setAttribute("currentTime", new Date());

return mapping.findForward("success"); }

}

Enterprise ist Enterprise

Enterprise ist Enterprise

The Enterprise JavaBeans architecture will be the standard component architecture

for building distributed object-oriented business applications in the JavaTM

programming language.

Enterprise ist Enterprise

The Enterprise JavaBeans architecture will make it easy to write applications:

Application developers will not have to understand low-level transaction and state

management details, multi-threading, connection pooling, and other

complex low-level APIs.

Verteilte Persistenz – BMP 1.1

public class Bmp11CustomerBean implements EntityBean { private Integer customerId; private String firstName; private String lastName; // getter/setter

public Integer ejbCreate(...) throws CreateException {...}

public void ejbLoad() throws EJBException {...} public void ejbStore() throws EJBException {...} public void ejbRemove() throws EJBException {...}

...

}

Verteilte Persistenz – BMP 1.1*

public class Bmp11CustomerBean implements EntityBean { ... public void ejbStore() throws EJBException { Connection con = dataSource.getConnection(); PreparedStatement ps = con.prepareStatement( "UPDATE CUSTOMER " + "CUS_FIRST_NAME=?, ... WHERE CUS_ID=?"); ps.setString(1, firstName); ... ps.setInt(4, customerId);

int i = ps.executeUpdate(); ... }}

*Exception and Resource Handling omitted

Verteilte deklarative Persistenz – CMP 1.1

public class Cmp11CustomerBean implements EntityBean { private Integer customerId; private String firstName; private String lastName; // getter/setter

public Integer ejbCreate(...) throws CreateException {...}

public void ejbLoad() throws EJBException {...} public void ejbStore() throws EJBException {...} public void ejbRemove() throws EJBException {...}

...

}

Verteilte deklarative Persistenz – CMP 1.1

<enterprise-beans> <entity> ... <persistence-type>Container</persistence-type> <prim-key-class>java.lang.Integer</prim-key-class> <cmp-field> <field-name>customerId</field-name> </cmp-field> ... <primkey-field>customerId</primkey-field> </entity>

</enterprise-beans>

Verteilte deklarative Persistenz – CMP 1.1

<orion-ejb-jar> <enterprise-beans> <finder-method partial="false" query="select * from CUSTOMER " + "WHERE $customerId = $1"> <method> <ejb-name>Cmp11CustomerEntity</ejb-name> <method-name>findByPrimaryKey</method-name> <method-params> <method-param>...</method-param> </method-params> </method> </finder-method> </enterprise-beans> </orion-ejb-jar>

Verteilte deklarative Persistenz – CMP 2.0

public abstract class Cmp20CustomerBean implements EntityBean { public abstract String getFirstName(); public abstract void setFirstName(...); public abstract String getLastName(); public abstract void setLastName(...);

public Integer ejbCreate(String firstName, String lastName) throws CreateException { this.setFirstName(firstName); this.setLastName(lastName); return null; } ...}

Verteilte (deklarative) Persistenz. Oh Gott!

Im Business Tier ist alles gut!*

public class CustomerServiceBean implements SessionBean {

public void activate(Integer customerId) {

Cmp11CustomerHome home = ...;

Cmp11Customer customer = home.findByPK(customerId); customer.activate();

}

}

*Exception and Resource Handling omitted

Wir können auch lokal*.

public class CustomerServiceBean implements SessionBean {

public void activate(Integer customerId) {

Cmp20CustomerLocalHome home = ...;

Cmp20CustomerLocal customer = home.findByPK(customerId); customer.activate();

}

}

So schlimm ist es nun doch gar nicht

Doch! Please repeat yourself!

If you can say it once, you can say it multiple times too!

EJBInterface

HomeInterface

Bean Klasse

DDSpec

DDSpecial

Das Programmier-Modell – Never implement!

public interface BmpCustomerHome extends EJBHome {

public BmpCustomer create(...) throws ...;

public BmpCustomer findByPK(...) throws ...;

}

public class BmpCustomerBean implements EntityBean { public Integer ejbCreate(...) throws ...;

public Integer ejbFindByPK(...) throws ...;

}

Das Programmier-Modell – Remoting!

public interface CustomerService extends EJBObject {

public void activate(Integer customerId) throws RemoteException;}

public class CustomerServiceBean implements SessionBean {

public void activate(Integer customerId) {...}}

Und diese Infrastruktur – JNDI Lookup

try { InitialContext ic = new InitialContext(); DataSource ds = (DataSource) ic.lookup(".../customerDS");

Connection con = ds.getConnection(); // use SQL Connection

} catch (NamingException e) { throw new EJBException(...);}

// TODO Resource Handling

Und diese Infrastruktur – Lookup & Narrow

try { InitialContext ctx = new InitialContext(); Object obj= ctx.lookup(".../CustomerHome"); CustomerHome home = (CustomerHome)PortableRemoteObject.narrow( obj, CustomerHome.class);

// do something with the EJB

} catch (NamingException e) { throw new EJBException(e);}

API-Call? Wo ist da die Fachlichkeit?

try { CmpCustomerHome home = ...; // lookup and narrow

CmpCustomer customer = home.findByPK(customerId); customer.activate();

} catch (NamingException e) {...} catch (FinderException e) {...} catch (RemoteException e) {...} finally { if (ctx != null) { try { ctx.close(); } catch (NamingException e) {/* ignored */ } }}

Oh je! Try/catch/finally!

InitialContext ic = null;DataSource ds = null; try { ic = new InitialContext(); ds = (DataSource) ic.lookup(".../customerDS");} catch (NamingException e) { throw new EJBException(...);} finally { if (ic != null) { try { ic.close(); } catch (NamingException e) { // ignored } }}

Zur Erinnerung: Das ist JDBC!

DataSource ds = ...; Connection con = null;PreparedStatement ps = null; ResultSet rs = null;

try { con = dataSource.getConnection(); ps = con.prepareStatement(...); rs = ps.executeQuery(); ... } finally { if (rs != null) { try {rs.close();} catch (SQLException e){...}}

if (ps != null) { try {ps.close();} catch (SQLException e){...}} if (con != null) { try {con.close();} catch (SQLException e){...}}}

Mit Pattern wird alles einfacher.

Mit Pattern wird das alles einfacher

> The evil ValueObject, SessionFacade, BusinessDelegate Combo

> Aus 5 mach 10!

> ServiceLocator clearance!

> FastLaneReader makes you scream.

Free

Who cares? Wir sind im Jahr 2014!

Was wir heute machen

• Klagen auf hohem Niveau...

• Ja, genau da sind wir gestartet!

• Diese Irrwege haben wir uns erlaubt. Leider.

• Genau genommen gibt es vieles noch heute.

• Das können und sollten wir davon lernen.

You care!

You care! Really!

„Java EE Programmiermode

ll versteckt Java EE

Laufzeitmodell!“

You care! Really!

> Resource Lookup

> Ressource Handling

> Remote Lookup & Remoting

> Pooling

> Interceptoren

> Proxies & Delegates

ClientClient

RoutingRouting

RoutingRouting

DispatchingDispatching

SecuritySecurity

TransactionTransaction

POJOPOJO

Was wir heute machen

• Klagen auf hohem Niveau...

• Ja, genau da sind wir gestartet!

• Diese Irrwege haben wir uns erlaubt. Leider.

• Genau genommen gibt es vieles noch heute.

• Das können und sollten wir davon lernen.

Und was lernen wir daraus?

Beware of obtrusiveness

> Anforderungen und Fachlichkeit stehen im Vordergrund

> Frameworks und Technologien mit großen Auswirkungen auf das Programmiermodell sind die falschen Frameworks und Technologien

Und was lernen wir daraus?

Beware of abstractions

> Die Zeit des Versteckens ist längst vorbei

> Frameworks und Technologie, die abstrahiert werden müssen, sind die falschen Frameworks und Technologien

Und was lernen wir daraus?

Monitor infrastructure code

> Gute Frameworks und Technologien benötigen wenig Infrastruktur-Code

> Erfordern Frameworks und Technologien einen hohen Anteil an Infrastruktur-Code, so sind es die falschen Frameworks und Technologien

Und was lernen wir daraus?

Avoid code generation

> Auch generierter Infrastruktur-Code ist schlechter Code

> q.e.d

> (Dazu gehört auch ein anemic domain Model)

Und was lernen wir daraus?

If something is too complex

to use or to introduce

and focuses on technology

rather than business requirements

it‘s just too complex!

Gibt es noch Fragen?

Dann los ...

Das ist ja sooo 200x!