« Schon-immer-mal | Main

Samstag, Juni 16, 2012

Tino forscht

Nach diversem Hinundher bastle ich weiter am "Medienbotenkatalog auf AppEngine". Trotz der guten Apache-Bibliothek POI/HSSF um Excel-Daten zu verarbeiten, kommt man bei den Ausgangsdateien zu so einfachen wie grundsätzlichen Fragen: Wann ist Schwarz eigentlich Schwarz? Wer definiert hier in welcher Palette, dass Font.COLOR_NORMAL Schwarz bedeutet? Und wieso hält sich die Datei nur manchmal daran? Zugegebenermaßen sind die Daten verschieden formatiert, aber immer irgendwie Schwarz - technisch leider nicht :-(

Wenn man dann alles gefärbt hat, kann man sehe, wie fleissig/ineffizient ich Datenbank-Operationen gebaut habe - innerhalb von 5min alles verbraucht - "Your application is near is free resource limit" - also einen Tag warten und bis dahin besser werden, d.h. Batch-Operationen beachten.

 

Erstellt von tixus um 5:41 PM Kategorien: Software + Java

Donnerstag, Mai 24, 2012

OrmHate

Irgendwie hat MF immer die richtigen Dinge zu sagen: Gerade ist bei uns eine DBA vs. Dev-Team-Diskussion entfacht und sie dauert noch an.

Many people treat the relational database "like a crazy aunt who's shut up in an attic and whom nobody wants to talk about"[3]. In this world-view they just want to deal with in-memory data-structures and let the ORM deal with the database.

Unsere Tante heisst Onkel Torsten; und ja, ich bin im Prinzip auch der Ansicht, dass die DB das Objekt-Modell unterstützen soll und nicht umgedreht.

Es wird hoffentlich weniger hässlich als Vietnam, aber dieses Essay hat einige Zustände sehr prägnant zusammen gefasst:

Discussions of inheritance-to-table and association mapping schemes also reveals a basic flaw: At heart, many object-relational mapping tools assume that the schema is something that can be defined according to schemes that help optimize the O/R-M's queries against the relational data. But this belies a basic problem, that often the database schema itself is not under the direct control of developers, but instead is owned by another group within the company, typically the database administration (DBA) group.

In many cases, developers begin a new project with a "clean slate", an empty relational database whose schema is theirs to define as they see fit. But, soon after the project has shipped, it becomes apparent that the developers' ownership of the schema is temporary at best--various departments begin clamoring for reports against the database, DBAs are held accountable to the performance of the database thereby giving them cause to call for "refactoring" and denormalization of the data... Before too long, the schema must be "frozen", thereby potentially creating a barrier to object model refactoring ... In addition, these other teams will expect to see a relational model defined in relational terms, not one which supports an entirely orthogonal form of persistence--for example, the "discriminator" column ...

So, then, the next task is to create a "Query-By-Language" approach, in which a new language, similar to SQL but "better" somehow, is written to support the kind of complex and powerful queries normally supported by SQL
The problem here is that frequently these languages are a subset of SQL and thus don't offer the full power of SQL.

Was bleibt also: Es gibt viele Wege nach Rom - der gutklingende führt interessanterweise als Beispiel db4o an, ein OO-Datenbanksystem, mit dem wir 2008 mächtig baden gegangen sind.

Summary: Wholehearted acceptance. Developers simply give up on relational storage entirely, and use a storage model that fits the way their languages of choice look at the world. Object-storage systems, such as the db4o project, solve the problem neatly by storing objects directly to disk. ... While many DBAs will faint dead away at the thought, in an increasingly service-oriented world ... it becomes entirely feasible to imagine developers storing data in a form that's much easier for them to use, rather than DBAs.

Andere, eher elementare aber trotzdem gut illustrierte Fakten zum Object-Relational Impedence Mismatch :

Object systems are typically characterized by four basic components: identity, state, behavior and encapsulation
[Date04] and [Fussell] define the relational model as characterized by relation, attribute, tuple, relation value and relation variable.

JOINs are among the most expensive expressions in RDBMS queries.... As a result, developers typically adopt one of the other two approaches ...: they either create a table per concrete (most-derived) class, preferring to adopt denormalization and its costs, or else they create a single table for the entire hierarchy, often in either case creating a discriminator column to indicate to which class each row in the table belongs.
Unfortunately, the denormalization costs are often significant for a large volume of data, and/or the table(s) will contain significant amounts of empty columns, which will need NULLability constraints on all columns, eliminating the powerful integrity constraints offered by an RDBMS.

Inheritance mapping isn't the end of it; associations between objects, the typical 1:n or m:n cardinality associations so commonly used in both SQL and/or UML, are handled entirely differently: in object systems, association is unidirectional, from the associator to the associatee ..., whereas in relational systems the association is actually reversed, from the associatee to the associator (via foreign key columns).

Allgemeine Regeln oder Grundsätze werden auch gestreift: Law of Diminishing Returns, "the Slippery Slope", "the Drug Trap", "the Last Mile Problem"

Erstellt von tixus um 6:20 PM Kategorien: Software + Java

Donnerstag, April 26, 2012

Vaadin

Meine Versuche mit GWT/GAE/Roo sind ins Stocken geraten - das unreife Zusammenspiel von roo und GAE, welches die komplizierte Architektur von GWT mit zig Klassen mit echtem Boilerplatecode für ein simples Frontend halbwegs akzeptabel machen könnte, hat den Ausschlag gegeben: Am Ende kommt eine Menge Code heraus, der nicht übersichtlich und erweiterbar ist sondern irgendwie die eigentliche Domäne vernebelt....

Aber ich will an einer Java-Hosting-Lösung festhalten, ohne einen eigenen Server zu mieten oder Amazon-Services zu nutzen (tja, warum eigentlich nicht?) - da kommt bisher als anfangs freie Variante nur GAE in Frage, wenn auch um den Preis eines NoSQL-Datastores. Aber man kann auch mal AWS anschauen:Ein eigener Server und gut, allerdings sind mir die Preismodelle unübersichtlich, dann lieber eine freie Quota bei GAE.

So nebenbei lerne ich, was was ist ("Schlagwörter: Hosting, Cloud Computing, Azure, SaaS, Amazon, 1&1, domainfactory, Online-Speicher, Google App Engine, NIST, IaaS, PaaS"), passend dazu hat die c't eine Artikelserie und kommt darin zu dem Schluss: "Google mit seiner AppEngine als Zwischending zwischen Platform-as-a-service und Software-as-a-service ist von den Dreien {EC2, MS Azure, GAE} noch am leichtesten zu beherrschen..."

Vaadin vs GWT/GAE

  • klares Framework, einfache Erweiterung
  • GAE nicht beste Plattform: performance, ui-state in session, server load, datastore mapping?
  • ->addressbuch als beispiel, mit GAE
  • plain GWT - too much boilerplate code for MVP/RFactory Model, roo code generation immature
  • vaadin with good tutorial and halfway app
  • Vaadin-Buch: Beispiel mit Roo und anpassbaren Views sowie deployment auf den Java-Hoster CLoudfoundry (inkl. MySQL) ( https://vaadin.com/book/-/page/rapid.cloudfoundry.html)

Vaadin-Plugin: Kurzes Beispiel mit in Memory DB (https://vaadin.com/springroo); Vaadin-Tutorial: Gute Beispielanwendung AddressBook ohne Roo ohne DB ohne Deployment.

Ach ich weiss es doch auch nicht - warum hab ich damals aufgehört, die GWT 1.x Variante zu verfolgen?

Erstellt von tixus um 4:23 PM Kategorien: Software + Java

Donnerstag, März 01, 2012

State of Play

Ach ja: roo 1.2 bedingt -> GAE 1.6.0 mit datanucleus-appengine plugin 2.0.0-RC2 welches datanucleus 3.0.4 welches JPA 2.0 braucht: ätz...

Die GAE-datanucleus-Integration scheint überschattet und aktuell stark limitiert zu sein:

Unowned relations sind plötzlich nicht möglich:

testCountCustomers(de.tixus.mb.roo.gwt.shared.domain.CustomerIntegrationTest): Error in meta-data for field de.tixus.mb.roo.gwt.shared.domain.Staff.id : Cannot have a primary key of type java.lang.Long and be a child object (owning field is "de.tixus.mb.roo.gwt.shared.domain.Customer.servedBy").; nested exception is javax.persistence.PersistenceException: Error in meta-data for field de.tixus.mb.roo.gwt.shared.domain.Staff.id : Cannot have a primary key of type java.lang.Long and be a child object (owning field is "de.tixus.mb.roo.gwt.shared.domain.Customer.servedBy").

testFindCustomer(de.tixus.mb.roo.gwt.shared.domain.CustomerIntegrationTest): java.lang.Long cannot be cast to java.lang.Integer

Datanucleus weiss das und schlägt was vor, aber das hört sich kompliziert an:

By default in GAE/J all relations are owned meaning that any child objects have the parent object Key as part of their Key, and persisted as part of the same entity-group. This is obviously useful in optimising retrieval of data, but there are times when you simply want your model persisting and not have imposition of ownership. In v2 of the plugin you can have unowned relations, where each object is in its own entity-group. To define a relation like this, see the following example

@PersistenceCapable
public class A {
@Persistent(primaryKey="true", valueStrategy=IdGeneratorStrategy.IDENTITY)
long id;

@Unowned
B b;
}

@PersistenceCapable
public class B
{
@Persistent(primaryKey="true", valueStrategy=IdGeneratorStrategy.IDENTITY)
long id;

@Unowned
@Persistent(mappedBy="b")
A a;

String name;
}

So when we persist an object of type A with related B it will do the following:
PUT the A, generating its Key, but without property for B
PUT the B, generating its Key, and with a property referring to the key of A
PUT the A with the property referring to the key of B.

Jesus!

DIe JPA 2.0-Integration hat einen bug: "Result class is simple, but field value [Ljava.lang.Object;@135afd61 not convertible into that;"

Darin (verständliches) fehlendes GAE-Commitment der roo-Leute:

Given that GAE and GWT are not high on our priorities due to their restrictions of what you can do, we are expecting GAE to allow JPA 2.0 compliant applications to run like other platforms such as EclipseLink and Oracle for example.

Für eclipse fehlen die GAE, GWT runtimes

<classpathentry kind="con" path="com.google.gwt.eclipse.core.GWT_CONTAINER"/>
<classpathentry kind="con" path="com.google.appengine.eclipse.core.GAE_CONTAINER"/>

Kann man per Hand hinzufügen, aber dasroo-plugin schmeisst sie immer raus:
Roo regenerates gwt-maven-plugin in pom.xml deleting edits done by the user

Erstellt von tixus um 12:57 PM Kategorien: Software + Java

Montag, Februar 27, 2012

Work bits

Hmm, muss ich mir Sorgen machen, wenn bei unseren (großenteils externen) Entwicklern sowas als Motto "Please keep quit?" im Raum hängt?!

Ansonsten ist es immer gut zu wissen, wer man ist:

Und das M$Office auch lustig sein kann, beweisen diese Meldungen:

 

Erstellt von tixus um 1:21 PM Kategorien: Software + Java

Donnerstag, Dezember 22, 2011

roo+SpringMvc

roo + SpringMVC: Fuck, ein Standard-Deploy endet so:

tsps-MacBook-Pro:mb-mvc tsp$ mvn gae:deploy -DskipTests=true
Dec 21, 2011 1:51:01 PM org.apache.jasper.compiler.AntCompiler generateClass
SEVERE: Error compiling file: /var/folders/rA/rAI3y8hfFQuztePwrkEL5U+++TI/-Tmp-/appcfg6923119542883762797.tmp/WEB-INF/classes/org/apache/jsp/tag/web/util/panel_tagx.java
[javac] Compiling 1 source file
[javac] error: Bad service configuration file, or exception thrown while constructing Processor object: javax.annotation.processing.Processor: Provider org.datanucleus.enhancer.EnhancerProcessor could not be instantiated: org.datanucleus.exceptions.NucleusException: Error reading manifest file "jar:file:/var/folders/rA/rAI3y8hfFQuztePwrkEL5U+++TI/-Tmp-/appcfg6923119542883762797.tmp/WEB-INF/lib/datanucleus-core-1.1.5.jar!/plugin.xml"

Also googlen und frickeln..... Und ja, nach dem Entfernen aller dependencies von datanucleus-enhancer loop et endlich:

tsps-MacBook-Pro:mb-mvc tsp$ mvn clean gae:deploy -DskipTests=true
[INFO] Scanning for projects...
Beginning server interaction for medienboten...
0% Created staging directory at: '/var/folders/rA/rAI3y8hfFQuztePwrkEL5U+++TI/-Tmp-/appcfg3602209683130921361.tmp'
5% Scanning for jsp files.
8% Compiling jsp files. Dec 21, 2011 2:15:35 PM com.google.apphosting.utils.config.AbstractConfigXmlReader readConfigXml
INFO: Successfully processed /var/folders/rA/rAI3y8hfFQuztePwrkEL5U+++TI/-Tmp-/appcfg3602209683130921361.tmp/WEB-INF/web.xml
20% Scanning files on local disk.
25% Scanned 250 files.
28% Initiating update.
Email: xxx@gmail.com
Password for xxx@gmail.com:
77% Initializing precompilation...
90% Deploying new version.
95% Will check again in 1 seconds.
98% Will check again in 2 seconds.
99% Will check again in 4 seconds.
99% Closing update: new version is ready to start serving.
99% Uploading index definitions.
Update completed successfully.
Success.

Und Browser auf und schauen - erstmal nix, aber nachdem ich den alten Datenbestand gelöscht habe:

Bis zur nächsten Untiefe:

 

Ok, ein bekannter Fehler: "These break all list pages. The following exception is generated:JspException: java.lang.NoSuchMethodError: "

Also scope ändern und redeploy, das übt ja...

<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
<scope>provided</scope><!-- Added -->
</dependency>

 

Natürlich lasse ich auch die Datastore-Fallstricke nicht aus: Index fehlt, erstmal also Beng:

Caused by: com.google.appengine.api.datastore.DatastoreNeedIndexException: no matching index found.
The suggested index for this query is:
<datastore-index kind="MediaItem" ancestor="false" source="manual">
<property name="mediaKind" direction="asc"/>
<property name="title" direction="asc"/>
</datastore-index>

Aber auch hier sehr gute Hilfe im Netz: datastore-indexes.xml anlegen, obige Fehlermeldung hineinkopieren, re-deploy und los:

Nun muss ich mal klären, wie das mit der freien Quota läuft, also ob eine mässige Benutzung gedeckt ist oder es bald Scheine regnen muss:

 

Erstellt von tixus um 1:36 PM Kategorien: Software + Java

Mittwoch, Dezember 21, 2011

Roo+X

Tja, ich fühle mich wie ein Hamster, der ständig den Hype-Zyklus durchrattert: Mein Hauptproblem ist es, die GUI für das Backend GAE auszuwählen; mit roo als Modellierungstool/-sprache bin ich ganz zufrieden. Aber wie weiter

  • roo + GWT: nettes CRUD aber unheimlich aufwendige Implementierung des an sich guten GWT-Webmodells (Acitivities, Places)
  • roo + JSF: zukunftsorientiert, aber die aktuelle roo-Version generiert nicht mal fehlerfreie poms
  • roo + SpringMVC: Standard-JSP-MVC, nicht sexy aber solide, deploy-Fehler

Mal sehen, welches der Modelle ich mal durchgehend zum Laufen und deployed bekomme um gemäß dieser Folie feiern zu können:

Erstellt von tixus um 3:57 PM Kategorien: Software + Java

Donnerstag, November 03, 2011

Customize spring roo gwt

Ab hier wirds anstrengend, weil, wie Cengiz sehr richtig bemerkt:

... the trouble lies beyond this point in customizing the Roo-generated scaffold application into a Web application that functions as required. The reason for this is a combination of the highly complex code generated by Roo and the lack of comprehensive documentation on it.

Man muss also was über Acitivities, Places, RequestFactory und modules wissen, um weiterzukommen - tough, Digger, finden auch andere.

Also liest du hier RequestFactory, hier Activities und Places, und hier sowieso IBM.

Aber ich vertraue auf Cengiz und versuche eine Anpassung durch ein neues Modul:

Erstmal neuen Finder dazu bauen - vorerst easy mit einem Like und einem Equals:

~.server.domain.MediaItem roo> finder add --finderName findMediaItemsByTitleLikeAndMediaKind

Die GUI wird erweitert um einen Menu-Eintrag mit der Suchanfrage: (Keine Sorge, kann man noch selbst beschriften...)

No API environment is registered for this thread.

mvn gae:run

JPA query to GAE ersetzt mir roo auch nicht; aber man kann ja die generierten Finder in die Hauptklasse "pushen" und dann anpassen:

Alter, SCARY - in einem Forum auf Dzone hat der irre Norweger gepostet...

Erstellt von tixus um 6:28 PM Kategorien: Software + Java

Sonntag, Oktober 23, 2011

GWT spring roo ts

Warum roo?

Ich will Spring IOC, DI und frameworks. Ich will eine Java-Umgebung als Hoster, möglichst kostengünstig: GAE. Ich will GWT und GAE und CRUD. ohne dafür GUIs bauen zu müssen. Ich will die neuesten GWT-Sachen (Eventbus, Activity, Places). Ich will mich mit einer einfachen DSL auf die Domäne konzentrieren, nicht auf den Request-Zyklus oder Persistenz.

Aber wie immer gilt auch hier: Besser man ist mal zu Fuß den Weg gegangen, eine Web 2.0 App mit GAE, GWT, Spring zu bauen, ansonsten steht man bei den ersten roo-Fehler im Regen. Und man sollte das "roo-Undo" mit git unbedingt nutzen. Sonst ist schnell mal was hingeneriert, was keiner braucht... In jeden Fall ist post-generatem immer mal gut, zu wissen was roo so alles raushaut.

Basic building blocks:

Editor Framework

You might be wondering how the generated application reads and writes entity objects from and to the view. It is all hidden away inside the GWT Editor Framework, which provides the functionality implicitly, using the marker interface pattern.

The RequestFactory

The RequestFactory and JPA provide an easy way to build data-oriented CRUD applications and together make up the data-access layer of our Roo-generated application.Built to complement the service-oriented GWT RPC and not replace it, the data-oritented RequestFactory is GWT's new mechanism that provides more efficient client/server data transfer. It allows us to define data-centric Entity classes on the server side and to define business logic with EntityProxy on the client side.

Entity

Entity s are server-side Data Access Objects (DAO) in our RequestFactory mechanism and should be placed in a package that will not be converted to JavaScript by GWT.

EntityProxy

Objects that implement the EntityProxy interface are Data Transfer Objects (DTO) and client-side representations of corresponding Entity objects. The exclusive use of EntityProxy interface on the client side relieves us from the requirement of writing GWT-compatible code in our Entity implementations.The BaseProxy interface, along with others that extend EntityProxy interface, enables RequestFactory to determine fields that have changed and send only these changes to the server.

Activity Pattern

In the application that Roo has generated for us, the Activity is the implementation of the Presenter component and IsWidget is the implementation of the View component of our MVP pattern.

Activity

An Activity is completely isolated from the view and contains no widgets or UI code. This isolation greatly simplifies the testing of logic contained within an Activity.

Place

A Place is a bookmarkable state for a Web application. An Activity needs a corresponding Place in order to be accessible via a URL. It has an associated PlaceTokenizer that serializes the Place's state to a URL token.

PlaceController

The PlaceController manages the current Place and navigation between Places in a Web application and makes the back-button and bookmarks work as users would expect.

Also ans Werk mit meinem Medienboten-Projekt und diesem Script:

project --topLevelPackage de.tixus.roo.mb

persistence setup --provider DATANUCLEUS --database GOOGLE_APP_ENGINE

enum type --class ~.shared.domain.Gender

enum constant --name MALE

enum constant --name FEMALE

enum type --class ~.shared.domain.TypeOfPerson

enum constant --name CUSTOMER

enum constant --name STAFF

enum type --class ~.shared.domain.MediaKind

enum constant --name BOOK

enum constant --name BIGFONT

enum constant --name CD

entity --class ~.server.domain.Person --testAutomatically

field string --fieldName displayName --notNull

field string --fieldName userName --sizeMin 3 --sizeMax 30 --notNull

field string --fieldName firstName

field string --fieldName lastName

field reference --type Person staff

field enum --fieldName gender --type ~.shared.domain.Gender

field enum --fieldName type --type ~.shared.domain.TypeOfPerson

field boolean --fieldName admin --notNull

entity --class ~.server.domain.MediaItem --testAutomatically

field string --fieldName mediaNumber --notNull

field string --fieldName title --notNull

field string --fieldName shortDescription

field number --type java.lang.Integer publicationYear

field enum --fieldName mediaKind --type ~.shared.domain.MediaKind

field number --type java.lang.Integer amount

field reference --type ~.server.domain.Person lentTo

web mvc setup

web mvc all --package ~.web

-- web mvc language --code de

security setup

gwt setup

logging setup --level DEBUG

>mvn gwt:run

Probleme:

Plugin execution not covered by lifecycle configuration: org.datanucleus:maven-datanucleus-plugin:1.1.4:enhance (execution: default, phase: compile) pom.xml /mb line 710 Maven Project Build Lifecycle Mapping Problem

->Use quick fix

Project configuration is not up-to-date with pom.xml. Run project configuration update mb line 1 Maven Configuration Problem

->maven->update project configuration

->Add roo project nature

Enables roo shell and allows for Google WebApplication

->Run As ... Google WebApplication -Tataa:

Erstellt von tixus um 11:57 PM Kategorien: Software + Java

Donnerstag, Juli 28, 2011

Tools on *nix

Nachdem ich hier über den Systemwechsel und die damit verlorenen Tools gejammert habe, hat sich alles wieder eingespielt auf der neuen Umgebung:

Prune sieht vernünftig aus als Geosetter-Ersatz für KML/KMZ-Dateien.

 Sitecopy macht einen tollen weil unkomplizierten Eindruck: update Kommando raus und Verzeichnisse werden abgeglichen - geht nicht einfacher!

Erstellt von tixus um 3:01 PM Kategorien: Software + Java

Mittwoch, Juli 27, 2011

GWT secured

Mann mann mann - choose your filter carefully: Ich brauche einige Versuche und kostbare Zeit um die GWT-SpringSecurity-Verknüpfung hinzukriegen - nun gehts:

Das hier verlangt für den allgemeinen Zugriff "/" (also auch die Anmeldungsseite!) einen anonymen User, sonst einen angemeldeten User und für "/mbopac/admin" eben einen Admin:

<http access-denied-page="/access-denied.html">

<intercept-url pattern="/" access="IS_AUTHENTICATED_ANONYMOUSLY" />

<intercept-url pattern="/mbopac/admin/**" access="ROLE_ADMIN" />

<intercept-url pattern="/**" access="ROLE_USER" />

<form-login login-page="/login.html" default-target-url="/Mbopac.html"

always-use-default-target='true' />

</http>

Das o.g. Tutorial ist ganz nett weil es Spring Security und GWT vereint, aber es läuft nicht auf der AppEngine: Das Problem ist die Spring autogenerierte Login-Seite, eine einfache eigene Seite "login.html" und Konfiguration in applicationContext.xml hilft dann endlich:

<html>

<head>

<meta http-equiv="content-type" content="text/html; charset=UTF-8">

<link type="text/css" rel="stylesheet" href="Mbopac.css">

<title>OPAC Medienboten B&uuml;cherhallen Hamburg</title>

</head>

<body>

<h2>Bitte melden Sie sich an.</h2><br>

<form method="POST" action="j_spring_security_check">

Benutzer: <input type="text" name="j_username"><br>

Passwort: <input type="password" name="j_password"><br>

<input type='checkbox' name='_spring_security_remember_me'/> Auf diesem Computer eingeloggt bleiben?.<br>

<input type="submit" value="Anmelden >>">

</form>

</body>

</html>

Mit diesem Tipp und einer Ableitungsebene mehr ist dann auch Springkonfiguration mit autowire erhältlich:

public class SpringGwtServlet extends RemoteServiceServlet {

@Override

public void init(ServletConfig config) throws ServletException {

super.init(config);

WebApplicationContextUtils.

getRequiredWebApplicationContext(getServletContext()).

getAutowireCapableBeanFactory().

autowireBean(this);

}

}

Das hier (Double brace initialization) mag ja nett aussehen ist aber too "cute":

final Set<String> rolesAdmin = new HashSet<String>() {
{
add(CustomAuthenticationProvider.ROLE_USER);
add(CustomAuthenticationProvider.ROLE_ADMIN);
}
};

Es ist hat eben die Implementierungsdetails, dass das erste Klammerpaar eine anonyme Innerclass erzeugt und das zweite Paar einen static initializer deklariert: Somit ist die Klasse unbekannt wird im Serialisierungskosmos von GWT hiermit quittiert:

[ERROR] javax.servlet.ServletContext log: Exception while dispatching incoming RPC call

com.google.gwt.user.client.rpc.SerializationException: Type 'de.tixus.mb.opac.server.DataImporter$1' was not included in the set of types which can be serialized by this SerializationPolicy or its Class object could not be loaded. For security purposes, this type will not be serialized.: instance = [ROLE_ADMIN, ROLE_USER]

Erstellt von tixus um 7:11 PM Kategorien: Software + Java

Dienstag, Juli 26, 2011

WhenType?

Ich bin immer wieder fasziniert von solchen Beiträgen, wenn jemand kleine, scheinbar simple Wahrheiten so formuliert und kombiniert, dass sie etwas Neues ergeben: Martin Fowlers schon älterer Artikel zur Frage, wann man einen Typ/Klasse erstellen sollte, statt bei Primitiven oder allzu generischen Typen zu bleiben.

When should you make your own type? To begin with, make a type if it will have some special behavior in its operations that the base type doesn’t have.
...
Often you’ll find things such as product codes that are numeric in form. However, even though they look like a number, they don’t behave like one. Nobody needs to do arithmetic on product codes— with a special type you can avoid bugs.
...
Even if a currency code looks like a string, if it doesn’t behave like one, it should get a different type. Look at the string’s interface and ask how much of it applies to a currency code? If most of it doesn’t, then that’s a good argument for a new type.
...
Indeed, communication is one of the biggest reasons to use a type. If you have a method that expects to take a cur- rency parameter, you can communi- cate this more clearly by having a currency type and using it in the method declaration.

Eine Übersicht aller Perlen von ihm gibts hier:Immer mal lesen!

Erstellt von tixus um 2:41 PM Kategorien: Software + Java

Samstag, Juli 02, 2011

Watch your packages

Dieser Mist hat mich einen schönen ruhigen Vormittag gekostet, ohne dass ich vorangekommen wäre - grrrh:

15:27:00.763 [ERROR] [mbopac] Failed to create an instance of 'de.tixus.mb.opac.client.MbopacMainView' via deferred binding

java.lang.RuntimeException: Deferred binding failed for 'de.tixus.mb.opac.client.PersistenceService' (did you forget to inherit a required module?)

at com.google.gwt.dev.shell.GWTBridgeImpl.create(GWTBridgeImpl.java:53)

at com.google.gwt.core.client.GWT.create(GWT.java:98)

at de.tixus.mb.opac.client.MbopacMainView.<init>(MbopacMainView.java:57)

Und was ist das PROBLEM, gwt?

Erst meinte ich oberschlau, dass man auf die Packages achten muss:

Alles was der Client benötigt und kennen muss, muss auch im client-zugreifbaren package definiert sein; der Pfad dafür wird hier gesetzt.

  Application.gwt.xml
 <!-- Specify the paths for translatable code --> 

<source path='client' /> <source path='shared' />

Dazu gehört alles, was im (Client-)Interface PersistenceService referenziert wird:

package de.tixus.mb.opac.client;
@RemoteServiceRelativePath("greet")
public interface PersistenceService extends RemoteService {
...
MediaItem lend(String mediaNumber, Person person, Boolean isOverride) throws MediaItemAlreadyLentException;
...
  

Das war leider doch nicht das Problem, sondern der fehlende Default-Constructor in einer Exception! Den habe ich versehentlich überschrieben, als ich beim Refactoring einen neuen Constructor brauchte:

  public class MediaItemAlreadyLentException extends RuntimeException {

	private Person person = null;

	private static final long serialVersionUID = 1L;

	public MediaItemAlreadyLentException() {
	}

	public MediaItemAlreadyLentException(final Person person) {
		this.person = person;
	}

}

Die OPAC-Anwendung nimmt jedoch Formen an: Nun kann man bereits den Katalog durchsuchen, Medien ausleihen und zurückgeben. Es fehlt zum ersten Start noch die Suche nach dem Kunden eines ausgeliehenen Mediums sowie eine Einschränkung der Suche auf noch nie ausgeliehene Titel für einen Kunden - man will schliesslich immer mal was Neues lesen.

Erstellt von tixus um 5:39 PM Kategorien: Software + Java

Donnerstag, Mai 05, 2011

MBP 2

Mein zweiter Versuch mit nem MBP ist vieel besser! Mattes Hires-Display, und gleich mal wieder den Hibernate-Modus auf den Windows-bekannten echten Ruhezustand gebracht - dauert beim Aufwachen ca. 20s, der Rechner ist zwischendurch aber wirklich aus und nicht auf Batterie, heisst beim Mac "always safe-sleep with secure virtual memory":

sudo pmset -a hibernatemode 5

Ansonsten schön schnelle *nix-Maschine, git und strings und ls alles da!

Gaaanz wichtig bei Hires-Displays - die Auflösung versaut die Augen, wenn man den Standard-Font von 10-13px belässt. Viele Anwendungen benutzen die System-Vorgaben, welche man sinnigerweise nicht besonders gut mit den System-Tools ändern kann - aber Tinkertool ist das TweakUI fürn Mac:

Alles auf z.B. 16pt ändern und Anwendung neustarten - voila!

Aber man verzweifelt eher an liebgewonnenen Programme für Alltagsaufgaben - Total Commander und das Directory-Sync waren eine super Sache - der für Mac verfügbare Filezilla kann auch Ordner abgleichen aber nicht rekursiv.

Zum Glück erinnere ich mich daran, dass IrfanView ein Windows -Clone von XnView ist - dieses gibts für Mac auch und es funktioniert wie gewohnt - toll!

Erstellt von tixus um 6:40 PM Kategorien: Software + Java

Freitag, April 29, 2011

MBP 1

  Ok, ich habe es getan: Ein neues Notebook muss her, also geschaut und verglichen - die Überraschung war, dass ein MBP mit Core i7 und 15 Zoll dann preislich sogar mit Lenovo und Konsorten mithalten kann. Also ein "MACBOOK PRO 15" QUAD-CORE I7 2000 SD DEUTSCH, 4 GB RAM, 500 GB HD" bei Gravis gekauft. Schick, schnell und spiegelnd: Das Foto ist nach dem Aufklappen entstanden - wie kann man sowas herstellen? Ok, nachdem ich so eine Diskussion von Apple-Jüngern gelesen habe, hab ich schon bereut, mein Geld dahin getragen zu haben - wie kann man im wahrsten Sinne des Wortes so oberflächlich sein? Andererseits - kann man einen Hersteller ablehnen, aber seine Waren kaufen? Hier gibts nen guten Eindruck von beiden Modellen... Da ich aber die 150 EUR Aufpreis für die entspiegelte Version sparen wollte, bin ich mit dem o.g. nach Hause. Alles installiert und rumgespielt, aber am Sonntag mit mulmigem Gefühl wieder vorsichtig eingepackt und Montag zu Gravis: "Äh, ich möchte den gern gegen den teureren umtauschen" Gravis in Ehren, man lässt sich darauf ein und nun warte ich auf die neue Lieferung - einen Geldabzug wirds wohl geben weils nun keine Neuware mehr ist - mal sehen.

Erstellt von tixus um 9:34 PM Kategorien: Software + Java

Sonntag, Januar 23, 2011

Widgettime: Tatort+Privatleihe

Es gibt Fixpunkte im erwachsenen Leben, bei uns gehört der Tatort dazu. Und dank Tatort-Fans verpassen wir nie wieder eine Wiederholung, denn so richtig sind wir erst seit ~4 Jahren dabei.


Powerd by tatort-fans.de

Eine andere schöne Sache ist eine Auflistung unserer DVDs - so könnt ihr sie gerne mal (kostenlos natürlich) ausleihen, wenn ihr nichts mehr zu kucken habt. Aktuell sind nämlich die DVD-Boxen "Loriot", "Kommissarin Lund -Das Verbrechen I" sowie Pedro Almodovar "Die große Edition" im Angbot.

Erstellt von tixus um 2:24 PM Kategorien: Film, Software + Java

Memo-Apps

Ich bin weiter begeistert vom webOS und verwirrt von meiner Prägung durch frühere Handy-Betriebssysteme: Wie viel leichter kann man es bitte noch machen einen Screenshot zu erstellen, als es so zu implementieren:(ok, iOS erlaubt ähnliches...)

Screenshots of the Palm WebOS can be taken by simultaneously pressing "Orange Key + Sym + P". Screenshots will be saved to your "Screen captures" folder in the "Photos" app.

Darum kann ich auch gleich mal bebildern, was mir an den angebotenen freien Memo-Apps nicht gefällt:

ClassicNote: Eine äusserst umfangreiche Anwendung, viele Formatierungen und Einfügen verschiedenster Elemente (Text, Links) sind möglich, aber leider unergonomisch nur über die Auswahl des Kontextmenüs erreichbar, also kein Rich-Text-Editor direkt bei der Eingabe. Viel schlimmer ist jedoch, dass man Schlagworte bzw. Kategorien jedesmal umständlich neu anlegen muss und immer nur eine Kategorie auswählen kann - dismissed.

Evernote hat im Prinzip alles was ich brauche: Bookmarking wie Delicious; ein Platz für alle Schnipsel (Mail, Text, Foto, Links); Schlagworte filtern, zusammenstellen - mehr braucht man gar nicht fürs erweiterte Gehirn.

... und erstmal nicht brauche: OCR aus Fotos, Bildern; Online Synchronisierung zwischen Desktop-Anwendung, Smartphone und gleichzeitig Online-Backup; read-it-later Offline-Speicher.
Und trotzdem ist die Bedienung auf Pixie unhandlich (evlt. besser mit der Pro-Version): Schlagworte muss man erst einblenden; man muss immer online sein, sonst werden Notizen nur zur Synchronisierung vorgemerkt und erscheinen gar nicht in der Übersicht.

Sorting Thoughts und textPress! lite mangelt es leider an Verschlagwortung, auch wenn die Reading List sehr gute Bücher enthält!

Also selbst machen:

... oder 5$ ausgeben für Notes - mal sehen.

Erstellt von tixus um 2:05 PM Kategorien: Software + Java

Sonntag, Januar 02, 2011

Lifestreams

Es ist immer wieder interessant, den richtigen Cracks hinterher zu lesen: David Gelernter und Eric Freeman, dieser Eintrag aus "Head First Design Patterns" hat mich auf die Spur gebracht:
Why do I have to give a file a name?

Die Idee der Ablage von allen Dingen auf einem PC ohne Dateistruktur nur auf einem Zeitstrahl ist toll, gerade habe ich noch gesehen, dass Cover Flow darauf basiert. In dem Screenshot aus ScopeWare Vision bzw. der Doktorarbeit von Eric Freeman S.86 sieht man schön die namen-lose Anordnung von Informationshappen streng nach Zeit. Tja, evlt. kann man das ja für was Eigenes nutzen.

 

Erstellt von tixus um 6:43 PM Kategorien: Software + Java

Dienstag, Dezember 28, 2010

It's fresh so fresh - exciting

Ich krieg nen Rappel und muss neu machen! Vorher hab ich mal ein paar alte Layouts rausgekramt - über die Jahre kommt schon was zusammen, aber nicht soviel wie man denken könnte:

Neuerungen: Ich setze mal auf intuitives Design - keine Überschriften auf der Startseite sondern nur noch die Teaser-Bilder. Was ich schon lange im Kopf hatte und nun mit einer geeigneten Vorlage und ein wenig CSS ("thank god its floating") umgesetzt habe, ist das flexible oder auch fluid-Design - die Seite passt sich der Browser-Größe an! Und das mit ganz wenigen CSS-Befehlen, ohne Javascript und sogar im IE siehts ganz passabel aus - toll! Dann habe ich die Kommentare weggelassen, hat eh keiner benutzt, und das etwas gierige Feedjit ist geschrumpft.

Einiges ist mit meinem Blogsystem Thingamablog nur durch Code-Änderung möglich, darum bin ich zum einen noch auf der Version 1.1: Der gute Bob Tantlinger hat für die neue Version 1.5 leider den Sourcecode nicht veröffentlicht.

Ich habe im wesentlichen 2 Anpassungen vorgenommen: Ein weiteres BlogEntry-Tag ist hinzugekommen: Mit $EntryTeaserImage$ kann das erste Bild eines Eintrags referenziert werden - es ist genau das, welches ich auf der Startseite in den Kacheln anzeige.
Beispiel:

<BlogEntry>
  <EntryTitle>
  <a title="<$EntryTitle$>" href="<$EntryPermalink$>">
<img src="<$EntryTeaserImage$>"></a>
  </EntryTitle>
</BlogEntry>
Die zweite Änderung ist nur eine konsequentere Implementierung des Containers ArchiveYears: Er verarbeitet nun auch alle Attribute des enthaltenen Containers ArchiveList.
<ArchiveYears sort_order="descend" glue=" " format="MMMM" span="1">
	<$Year$>
	<ArchiveYear>
		<$ArchiveLink$><$ArchiveName$>
	</ArchiveYear>
</ArchiveYears>

Es ist in Bobs Sinne für die "alte" Version, dass ich mein Release und das Template-Set dazu hier wieder zur Verfügung stellen muss (GNU-GPL). Für die neue Version gibt es eine wesentlich restriktivere Lizenz, darum auch keinen Sourcen mehr (er wird seine Gründe haben...):

Restrictions on Use
You may not decompile, "reverse-engineer", disassemble, or otherwise attempt to derive the source code for the Software Product.

Restrictions on Alteration
You may not modify the Software Product or create any derivative work of the Software Product or its accompanying documentation.

Erstellt von tixus um 6:51 PM Kategorien: Software + Java

Mittwoch, Dezember 22, 2010

Palm Developer

Ich verstehe erst langsam, warum webOS webOS heisst: Ich vermisste eine Java-ME (MIDP) Installation, nun wird mir klar, dass es "nur" HTML+JavaScript gibt - auch gut, Google (-Maps, -GWT) braucht nichts anderes und es ist leichter portierbar auf sowas wie iOS oder Android. Schön ist, dass ich Eclipse weiter benutzen kann.

Die neuste iX 1/2011 hat einen Artikel zum selben Thema unter iOS.(Tutorial: iPhone-Apps mit Webtechniken, Teil II) Wer Webseiten fürs iPhone optimiert hat, wie es der erste Teil dieses Tutorials gezeigt hat, kann gleich den nächsten Schritt gehen und seine Webseite als "Webapp" nativ auf dem iPhone-Desktop starten lassen – ohne Apples AppStore-Prozedur durchlaufen zu müssen.

Wie immer stehen längliche Downloads an: Die offizielle Seite verlangt auch noch eine VirtualBox-Installation (für den Emulator?), seis drum. Die VirtualBox 3.2.12 crashed schon mal WinXP, na herrlich - dann probier ich mal das System Restore - läuft! Version 3.2.10 funktioniert besser.

Mit Eclipse baue ich die Beispiel-App nach, es tippt auf dem Bildschirm. Nun will ich das um GPS-Benutzung und -Logging erweitern; was mir auch sinnvoll erscheint ist eine Art Offline- oder persönliches Qype fürs Taggen von Orten oder Routen: Man kann sich den Spaziergang merken, den Currywurststand, den Fischladen, die Tischtennisplatte oder den Fahrradladen., dazu braucht man keine Empfehlung von anderen - einfach Foto machen, Schlagworte vergeben, Ort bestimmen und beim nächsten Besuch von ausserhalb ist das Programm fertig. Es gibt ja auch immer so Places-Dienste wie Spielplatz, aber eben für jeden Art von Ort nen neuer Dienst, ist doch blöde...

Ah, kurze Webrecherche und dadah: MyPlaces-App is there. Nur Android und iOS, dann kann ich ja webOS machen ;-) Aber genau so isses: Create your own database of places you like, find them back in a few clicks and share with your friends

Witzig, es gibt noch ne App die genauso heisst...

Erstellt von tixus um 7:13 PM Kategorien: Software + Java

Tino Palm

Also new kid on the block - trotz Bedenken ein neues Handy: Kein iPhone, kein Android, Palm/HP-webOs sollte es sein: Auftritt Palm Pixie Plus.

Pro:

Kontra:

Absolut problemlos funktioniert die Einbindung und Synchronisierung mit einem GMail-Konto - alles Kontakte, Emails, Kalender - aber das ist ja auch Teufelswerk. Hab ich dann trotzdem gemacht, weil man dann Outlook-Kontakte exportieren als CSV, GMail-Kontakte importieren von CSV, Palm sync aufs GMail-Konto machen kann. Aber eine ständige synchronisierte Lösung zwischen Firma-PIM und Handy ist das nicht.

Leider gibt es nicht den einen App-Shop, sondern 1000 PalmPreCentralen oder AppCatalog und dt. Seiten und palm.com-Seiten. Aber wenn man auf letzterer etwas findet, dann geht der Download von "Apps" aus dem AppCatalog per WLAN (der Link wird sogar von der Webseite aufs Handy geschickt, s.Abb.)

Erstellt von tixus um 6:50 PM Kategorien: Software + Java

Sonntag, August 15, 2010

Javatar

Lustig lustig die Jungs von DZone: Einen full-fletched Kino-Trailer im Stile von "Brokeback mountain" für Java vs. M$.NET. Aber wird dabei nicht irgendwie auch transportiert: Java==schwul?

Erstellt von tixus um 2:58 PM Kategorien: Software + Java

Freitag, August 06, 2010

XML jemand?

Was macht man, wenn man aus einem XSD möglichst viele sinnvolle XML-Testdaten mit ausreichender Varianz/Kombination automatisiert erzeugen möchte? Man googlet, aber die Kunst ist eben auch, etwas zu finden.
Aber man kann auch was lernen, wenn man will: "Combinatorial test data" , "Partition testing" und "Controllable combinatorial coverage in grammar-based testing" sind Bereiche, die sich mit sinnvoller Testdaten-Generierung befassen.

Dabei bin ich auf TAXI gestoßen, welches zumindest eine Varianz von optionalen Attributen und Elementen erzeugen kann und somit Vorlagen liefert. Leider (weils auch schwierig ist) ist nur rudimentäre Unterstützung für RegEx-Pattern: "Currently TAXI can not generate Strings that conform to the pattern grammar. So If there is any element that has the restriction with "pattern", please put the values that conform to that pattern into the database. Otherwise TAXI will put "prefix:string" as the value for the element."

Forschungsarbeiten dazu kann man auch lesen:

Ralf Lämmel and Wolfram Schulte "Controllable combinatorial coverage in grammar-based testing "

Abstract. Given a grammar (or other sorts of meta-data), one can trivially de- rive combinatorially exhaustive test-data sets up to a specified depth. Without further efforts, such test-data sets would be huge at the least and explosive most of the time. Fortunately, scenarios of grammar-based testing tend to admit non- explosive approximations of naive combinatorial coverage. In this paper, we describe the notion of controllable combinatorial coverage and a corresponding algorithm for test-data generation. The approach is based on a suite of control mechanisms to be used for the characterization of test-data sets as well-defined and understandable approximations of full combinatorial coverage. The approach has been implemented in the C#-based test-data generator Geno, which has been successfully used in projects that required differential testing, stress testing and conformance testing of grammar-driven functionality

Leider ist Geno nicht freigegeben oder ich habs nur nicht gefunden...

Erstellt von tixus um 2:52 PM Kategorien: Software + Java

Sonntag, April 11, 2010

Computer

Man was es nicht alles gibt: Netbooks haben naturgemäß keine optischen Laufwerke, also gibt es bei Neuinstallation des Betriebssystems einige Schwierigkeiten, die ich natürlich nicht zu erst und alleine habe.

WinToFlash ist die Antwort - darauf bin ich aber auch erst nach dieser 7-Punkte-Liste gekommen.

Das wird vom ansonsten tollen WinToFlash leider vergeigt: Die erzeugte boot.ini (die immer noch als Bootmenu benutzt wird) sieht so aus und macht die Partitionseinstellung falsch:

[Boot Loader]
Timeout=30
Default=multi(0)disk(0)rdisk(1)partition(1)\WINDOWS
[Operating Systems]
C:\$WIN_NT$.~BT\BOOTSECT.DAT = "1st, text mode setup (Boot from flash again after finished)"
multi(0)disk(0)rdisk(1)partition(1)\WINDOWS="2nd, GUI mode setup, continue setup + 1st start of Windows" /fastdetect
C:\ = "---> DEBUG options. Try if you have hal.dll error <---"
multi(0)disk(0)rdisk(1)partition(2)\WINDOWS="Debug boot rDisk 1 partition 2" /fastdetect
multi(0)disk(0)rdisk(1)partition(3)\WINDOWS="Debug boot rDisk 1 partition 3" /fastdetect
multi(0)disk(0)rdisk(1)partition(4)\WINDOWS="Debug boot rDisk 1 partition 4" /fastdetect
[...]

Das Booten schlägt auf furchterregende Weise fehl, wenn man den 2nd GUI mode benutzt (hal.dll not found)...

... funktioniert aber, wenn man die erste DEBUG-Option auswählt. (<--Hier hätte man also schonmal drauf kommen können...)
(Schön auch diese spiegelnden Displays)

(M)eine funktionierende boot.ini sieht dagegen so aus - und so hab ich 2 und 2 zusammengezählt und dann gings auch.

[boot loader]
timeout=30
default=multi(0)disk(0)rdisk(0)partition(2)\WINDOWS
[operating systems]
multi(0)disk(0)rdisk(0)partition(2)\WINDOWS="Microsoft Windows XP Professional" /noexecute=optin /fastdetect

Erstellt von tixus um 3:32 PM Kategorien: Software + Java

Computer II

Meine zweite Computer-Tat diese Woche war die Installation von XP auf einem Mac. Das zu lösende Problem war jedoch die Installation eines Dreamweavers auf einem Mac, wenn man nur eine Windowsversion hat. Jetzt kann man eine Menge über "The Transition" lesen (Apple setzt nach 10 Jahren PowerPC auf CISC, weil Intel weniger Energie für gleiche Geschwindigkeit bietet) oder sich an meinen MacMini-Kauf erinnern und daran, dass da eine Parallels-Vollversion dabeilag. Denn die üblichen Virtualisierungsverdächtigen sind auf dem Mac irgendwie auch nicht kostenlos:VmWareFusion, CrossOvermac. Anschauen könnte man nochmal Virtualbox.
Mit frischem Mut und wackeligen Fingern also Parallels gemacht und darin dann WinXP installiert - 45 min warten und läuft wie geschmiert! Dann Auftritt Dreamweaver: Installation geht noch, dann wollen die Serververzeichnisse ja synchronisiert werden und das ging nicht sofort.

Trotz sichbaren Serververzeichnisse kam immer die Fehlermeldung:

"Dreamweaver kann die Remote-Server-Zeit nicht ermitteln"

Damn. Wieder einmal: Was hat man nur ohne Internet gemacht? (Naja, zugegeben, dann hätte man diesen Fehler auch nicht ...) Die ersten Hinweise haben noch nicht viel gebracht und somit hab ich mal weiter in die Logs des DW geschaut und siehe da: Es gibt eine FTP-Fehlermeldung:

COMMAND: PORT 192,168,1,101,4,170
SERVER-ANTWORT: 500 I won't open a connection to 192.168.1.101 (only to 217.80.184.242)

Damit konnte man sehen, dass es an der NAT-Verbindung der virtuellen Windowsmachine zum Hostrechner scheitert. Und damit spuckt das Internet richtig gute Tipps aus:

The FTP protocol can correct this problem by using PASV (Passive) mode where the FTP client connects to the server for the data connection instead of the server connecting to the client.

FTP-Optionen suchen und "Use passive FTP" einstellen - läääääuft! Hätte man auch mal so draufkommen können...

 

Erstellt von tixus um 10:15 AM Kategorien: Software + Java

Sonntag, März 21, 2010

IT weekly

So richtig flüssig läufts nicht mit dem selbstgesteckten Ziel, jede Woche oder so die c't und iX auszuwerten und zumindest Linksammlungen anzulegen - aber nun ein neuer Versuch.

Executable Specifications: (Vorsicht Binse) Nur ein Teil der Erstellung von Software ist die Programmierung. Viel Zeit und Denkarbeit geht in die Spezifikation bzw. Anforderungsanalyse (Requirements). Das Resultat ist häufig ein unglaublicher Wust an Text, manchmal mit einer Grafik, selten mit Beispielen. Und bei allen besten Absichten der Schreiber ist die Spez voll von mehrdeutigen Formulierungen und leer von "Selbstverständlichkeiten" - in letzter Zeit habe ich es mehrfach erlebt, dass nach der Implementierung bei den ersten Tests absolut grundlegende Missverständnisse bgzl. der Funktion auftraten. Kann das mit Exectuable Specifications/User written Acceptance Tests besser sein?

Concordion - turning specifications into active specifications.
Plain English specifications: Rather than forcing product owners to specify requirements in a specially structured language, Concordion lets you write them in plain English using paragraphs, tables and proper punctuation. This makes the specifications much more natural to read and write, and helps everyone to understand and agree about what a feature is supposed to do.
Always bang up-to-date: Concordion specifications are active. Behind the scenes, they are linked to the system under test and therefore do not go out-of-date. If a change is made to the system's behaviour then the tests associated with the relevant specification will fail and let you know.

GreenPepper is an Agile Requirements Definition and Management (RDM) tool.

Causes of inaccuracy (Accurate software development)

Having all your system specifications strictly defined 12 months earlier and expecting that today you deliver software that fully satisfies its requirements imply that nothing special happened last year in your business ecosystem.
Distilled at its essence, the art of developing valuable systems rely on the successful translation of the business expert’s knowledge into a working piece of software created by the developer.

Dazu passt auch BDD (Behavior Driven Development). Stefan Roocks Post hat mich dann noch zu Poppendieck geführt, die viele Essays haben (zuviele fürn armen Entwickler...)

Und das gabs auch noch in dem Umfeld: "Die Sapir-Whorf-Hypothese besagt, dass die Sprache das Denken formt."

Classicist or Mockist? M.Fowler ist immer wieder für eine Leserunde gut.

Erstellt von tixus um 2:41 PM Kategorien: Software + Java

Freitag, März 19, 2010

Clean out

Ich war allein bei der JUGHH zum Thema "Clean Code Developer" - meine Kollegen fanden das Thema wichtig, aber irgendwie nicht relevant für sie. Interessant dann auch, dass auf dem Treffen nur 3-4 IT-Architekten und wenige Projektleiter waren: Heisst das, dass die Top-Programmierer, die häufig zu IT-Architekten/Projektleitern werden, das Thema uninteressant finden, weil sie sich sowieso schon als CCDs sehen? Das wäre fatal, denn gerade sie als Leiter sollen die Notwendigkeit von CCD für die Gesamtqualität ihres Teams und damit Systems sehen.

Ich habe im Kuba-Urlaub das Buch "Clean Code" gelesen, es hat zur Initialenzündung des CCDs geführt. Die im Vortrag aufgezählten Prinzipien und Praktiken sind hilfreich, Tag für Tag und auch darüber hinaus. Mir gefällt die tägliche Reflexion und die Pfadfinderregel ("Den Platz ein bisschen sauberer verlassen als du ihn vorgefunden hast") - auch wenn ich mich nicht immer daran halte. Aber innerhalb eines Team können diese Prinzipien im Zusammenspiel mit den angegebenen Tools zu guter Software führen. Das ist sowieso der Hauptgrund für mich, dass Ganze anzuschauen: Da ich eher nicht so der naturbegabte Star-Programmierer bin, brauche ich viele Richtlinien und Praktiken, die meine Ergebnisse einfach gut werden lassen. Ich glaube ich, dass es für eine Firma wichtig ist, dass mit allen im Team eine hohe Qualität erreichnen zu können. Wenn man die CCD-Regeln beherzigt, hat man schon mal ein Korsett, das weniger Fehler zulässt. Joel hat man einen schönen "The Joel Test: 12 Steps to Better Code" aufgestellt:

But, all else being equal, if you get these 12 things right, you'll have a disciplined team that can consistently deliver.

Meine Firma besteht recht gut (8/12) - darum sind wohl auch noch so viele dabei...

Es können einfach nicht alle Firmen nur die 10% Besten eines Jahrgangs bekommen. Auch wenn das den Anschein der frühen Kapitulation auf dem Markt der Talente hat, ist es doch realistisch. Man kann natürlich, wie es Bruce Eckel als Beispiel gehört, ständig Heuern+Feuern wie bei Kayak.com. Aber welche Firma die ausser einer Website echte Kunden, Terminverpflichtungen und ein vertikales Geschäftsfeld hat (mit entsprechender Einarbeitung), kann sich das leisten? Und "Talente" sind auch eher rah gesät, zumal auch bei ihnen gilt: 5% Inspiration 95% Transpiration. Wichtiger ist daher doch eher, innerhalb eines Teams gemeinsam Masstäbe, Regeln und Verbindlichkeiten zu Qualität und Zielen zu finden. Dann kann man immer noch die "poisonous person" identifizieren/entfernen, und vielleicht ist das sogar der Star-Programmer-Loner mit dem schwierigen "Interface". Clean Code kann ein Mittel sein, im Team eine gleich hohe Qualifizierung und Stimmung zu erreichen.

Der Kayak-CTO hat aber einen interessanten Artikel geschrieben (mirror):

We work really hard for 40 to 45 hours a week, but we believe in people having strong personal lives. Over the past six years, there have been maybe five times I've spoken with Steve before 8 a.m., after 5 p.m., or on the weekend.

A lot of companies have the "no assholes" rule. So if the greatest programmer ever is also a jerk, he's fired. Our rule is "no neutrals."

Erstellt von tixus um 7:23 PM Kategorien: Software + Java

Sonntag, Februar 28, 2010

Integrate me

Man lernt ja immer ne Menge Neues, wenn man mal was Altes machen will; heute: Windows XP installieren. Ok, gültige Lizenz und bootfähige CD hab ich noch, klick, ist ne Weile her, aber Radfahren verlernt man ja nicht, booten, schnipp - BSOD. Grrrh, Suse verwünscht und M$ und usw. Dann das Internet gepriesen, ich weiss WIRKLICH nicht was man früher gemacht hat? (Jemanden angerufen? Auf die nächste c't gewartet? Radio gehört? In den Computerclub gegangen? Am Sonntag?)

Ca. 163.000 mal hat jemand was dazu gesagt - die Lösung ist gaanz einfach: 1) Service Pack 2/3 slipstreamen, 2) CD brennen, 3) booten - 4) läuft. Naja, slipstreaming? D:\WINDOWSXP-KB936929-SP3-X86-DEU.EXE /integrate:D:\WXPVOL_DE

Aber es gibt gute Anleitungen, die bis Schritt gut geklappt haben, jedoch hatte ich dann nur eine slipstream-Version meines XPs mit SP3 auf einer nicht bootbaren CD ("Could not find NTLDR" - das haben ca. 263.000 Leute)

Der harte Weg war dann: Installation eines Windows XP, das nach 30 Tagen aktiviert werden muss, dann die o.g. CD eingelegt und XP davon noch einmal installiert, mit Lizenz und so. Nun hat Suse mein Laptop, das Ubuntu da drauf harrt noch seiner Auferweckung und ich bin irgendwie ausgelaugt... GParted und ein Knoppix sind übrigens treue Helfer bei aller Art von Festplatten-Massage...

Erstellt von tixus um 11:24 PM Kategorien: Software + Java

Dienstag, Februar 02, 2010

AdamEE

Leicht ungeplant schaffe ich es doch noch zu Adam in die LOB: "Real World Java EE Patterns - Rethinking Best Practices"

Auf den ersten Blick sieht aber alles ziemlich chaotisch aus. Java Context and Dependency Injection (CDI) (JSR-299), Dependency Injection for Java (JSR-330) und EJB 3.1 definieren Dependency Injection. Managed Beans (aus JSF), CDI-Beans und EJBs verfügen über einen definierten Lebenszyklus.

Es war unterhaltsam, wenn auch etwas atemlos. Adams große Stärke ist die Besinnung auf das Einfache, Undogmatische. Nicht umsonst zeigt er die "Simplest possible EJB", eine Enterprise Bean mit gerade 5 Zeilen.

@Stateless
public class HelloService {
public String getHello(){
return "Hello from EJB / CDI";
}
}

Er fragt, wozu man ohne Grund einfach immer ein Interface erstellt, selbst wenn es niemals mehr als genau eine Implementierung geben wird. Das verschmutzt nicht nur den Namensraum ("ICustomer" oder "CustomerImpl" wenn "Customer" reichen würde) und es bringt fürs Testen auch keine Vorteile, denn auch Klassen kann man mocken (ok, sie dürfen nur nicht final sein).

Er fragt, warum man die Datenbank (ausser generiertem Mapping) abstrahieren muss, wenn man sie im Griff hat bzw. verwaltet? Niemand hat jemals Oracle ausgetauscht :-)

Er fragt, wozu man 5 Layer hat, wenn bei der neuen Anzeige eines Datenbank-Felds alle 5 geändert werden müssen. Adam benutzt häufig nur 1 Entität in allen Schichten.

Zum Beispiel JSF-to-EJB: Die o.g. EJB und die Verwendung in JSF:

@Stateless
public class HelloService {
@EJB ClockService clockService;
public String getHello(){
return "Hello from EJB / CDI: " + clockService.currentTime();
}
}

<h:body>
<h:form>
<h:outputLabel value="#{helloService.hello}"/>
</h:form>
</h:body>

Ganz allgemein schwimmt er gegen den Strom: Setzt EJB ein und progagiert Windows Vista, auch wenn er mit einem MacBook auflief, weil Lenovo ihn versetzt hat. Und es fiel auch die Frage, wer ausser Adam überhaupt noch EJB macht :-)?

Aber die gute Nachricht ist, dass es mit der neue EJB-Spec ein bisschen egal geworden ist, ob Spring oder EJB: Annotations sind z.T. identisch, Konvention over Konfiguration sorgt in beiden Umgebungen für schlanken Code. Konfiguration mit XML ist in EJB tot, eine leere beans.xml ist das jämmerliche Relikt, in Spring kommt man mittlerweile auch mit viel weniger applicationContext.xml aus.

SOA ist bei Managern beliebt, in der Praxis aber nicht so einfach bzw. leichtgewichtig: Datentypen konvertieren zwischen .NET und Java ist hakelig. Wenn man es ROA nennt (Resource oriented architecture) und REST over HTTP macht, kommt man weiter: String/JSON läßt sich gut konvertieren.

Ein vergnüglicher Abend, der Herdentrieb und Hypes kritisch beleuchtet und die scheinbar chaotische und komplexe Welt der Enterprise Anwendung ein wenig heller macht.

Erstellt von tixus um 2:20 PM Kategorien: Software + Java

Mittwoch, Januar 13, 2010

Weekly IT

Um mich selbst zu disziplinieren, um die Stapel c't, iX und Javamagazin neben meinem Bett zu reduzieren und ohne schlechtes Gewissen ("da könnte noch was Interessantes drin stehen) will ich jede 1-2 Wochen die besten Artikel in einem Blog-Eintrag zusammenfassen. Dann kann man sie mit Stichworten oder Datum wiederfinden.

Und los geht's: c't 02/10


Wolke 7/ Programmieren für die Google App Engine/ Artikel S. 174

"Um eine Anwendung ins Web zu hieven, muss man nicht unbedingt einen Vertrag mit einem Web-Hoster abschließen. In der Cloud von Google bekommt man CPU-Zeit, Speicher und Bandbreite kostenlos -- ausreichend für satte fünf Millionen Seitenaufrufe pro Monat."

Der Artikel hat in mir die alte Idee wiederbelebt, doch endlich mal einen Hoster zu benutzen, der auch eine Java-Umgebung anbietet: GAE verspricht genau das gratis:

Und das klingt auch vertraut - die gute alte Servlet-API im WebContainer-Layout:
"App Engine Java applications use the Java Servlet standard for interacting with the web server environment. An application's files, including compiled classes, JARs, static files and configuration files, are arranged in a directory structure using the WAR standard layout for Java web applications. You can use any development process you like to develop web servlets and produce a WAR directory."

Und da ich sowieso gerade ein wenig mit Webanwendungen rumbastele scheint es die ideale Ergänzung - mal anschauen.


Hotline: Kann ich irgendwie zwei Firefox-Fenster mit verschiedenen Einstellungen und Add-ons parallel offen haben?

Um das Profil direkt aufzurufen und parallel zu einem anders konfigurierten Firefox-Fenster zu benutzen, rufen Sie den Browser mit zwei zusätzlichen Parametern auf, nämlich -no-remote und -P „Profilname“. Der erste sorgt dafür, dass ein neues Fenster geöffnet wird, der zweite wählt das darin zu nutzende Profil aus. Ohne -no-remote öffnet ein schon laufender Firefox einfach ein neues Fenster, ohne das Profil zu ändern.

Hotline: GMX-MediaCenter ohne Zusatz-Software?

Befehl „Netzlaufwerk verbinden“ im Menü „Extras“ des Windows Explorer). Starten Sie dort über den Link „Verbindung mit einer Website herstellen, auf der Sie Dokumente und Bilder speichern können“ den Assistenten zum Einrichten einer WebDAV-Verbindung: https://mediacenter.gmx.net

Und ruck-zuck hat man ein Laufwerk G:\ dass im Netz ca. 1GB Speicher kostenfrei zur Verfügung stellt - sehr bequem, wenn man eh schon GMX-Mitglied ist.


Buchempfehlung: Gewissensbisse - Ethische Probleme der Informatik: Biometrie -- Datenschutz -- geistiges EigentumDebora Weber-Wulff, Christina Class, Wolfgang Coy, Constanze Kurz, David Zellhöfer, ISBN 978-3-8376-1221-9
Mist, brauch ich so ein Gadget etwa auch noch? Chumby One  
Erstellt von tixus um 7:08 PM Kategorien: Software + Java
Powered by
Thingamablog 1.1b6