Das ist ja sooo 200x!

Post on 23-Jun-2015

196 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

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

@ApplicationScoped

public 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!

EJB Interface

Home Interface

Bean Klasse

DD Spec

DD Special

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

Programmiermodell

versteckt

Java EE

Laufzeitmodell!“

You care! Really!

> Resource Lookup

> Ressource Handling

> Remote Lookup & Remoting

> Pooling

> Interceptoren

> Proxies & Delegates

Client

Routing

Routing

Dispatching

Security

Transaction

POJO

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!