Archive zu Kategorie 'Programmieren'
22. Februar 2010 von KG
Auch wenn es einige gewichtige Argumente gegen Git gibt: Bei der Lektüre von Scott Chacons Buch Pro Git (gedruckte Version) wird mir das ganze Potential der postklassischen Versionskontrollsysteme klar: Auch wenn mir das Offline-Branching bislang immer am wichtigsten war (auf diese Weise kann ich im Zug einfach einen experimentellen Branch erstellen), bietet die Idee, stets das Repository bei sich zu führen (von Server-Hooks abgesehen), doch erheblich mehr Vorteile.
Zudem gefällt mir besonders gut, dass man Versionen einer Datei auch dann wiederherstellen kann, wenn der Branch (sollte eigentlich “das Branch” heißen, aber dagegen sträubt sich mein Sprachempfinden) gelöscht wurde. Das ist in Subversion z.B. nicht möglich. Ebenso ist das Konzept des “Staging” (geänderte Dateien werden erst nach einem expliziten Stage-Befehl committed [kann man auch deaktivieren]) für mich sehr nützlich – in Subversion habe ich bislang (vor allem graphisch) andersherum gerade in größeren Projekten gearbeitet: Aus der Fülle der geänderten Dateien musste ich immer die “herauspicken”, die nicht committet werden sollten, was sehr zeitraubend war. Jetzt geht es andersherum: Nur die Dateien, die wirklich wieder ins gemeinsame Repository sollen, gehen nach “Staging”, alle anderen bleiben erst einmal lokal.
Nun beleuchtet Zack Voase in seiner Gegenüberstellung des Quellcodes Gits und Mercurials, dass für eine vergleichbare Funktionalität ein Quellcodeverhältnis von 10 (Git) zu 1 (Mercurlal) vorhanden ist.
Da frage ich mich natürlich, wann endlich der Git-Nachfolger programmiert wird. Und zwar in Scala
1. September 2009 von KG
Ein Umstand, der in Unternehmen auf Entscheiderebene außerhalb des IT-Umfelds gerne verdrängt wird: Softwareentwickler sind Spezialisten und benötigen deshalb spezielle Hardware. Wer denkt, dass “Software schreiben” ungefähr mit dem Schreiben von Textdokumenten vergleichbar ist, liegt in etwa so richtig wie jemand, der meint, Autofahren hieße, auf einem Stuhl zu sitzen und beide Füße unregelmäßig auf- und abzubewegen.
Oberflächlich mag der typische Softwareentwickler Quellcode schreiben, was nicht so entfernt vom Schreiben von Textdateien zu sein scheint.
Tatsächlich ist der Quellcodeeditor nur ein Bestandteil von vielen, die die Integrierte Entwicklungsumgebung (“IDE”) eines Entwicklers ausmachen: Damit der Quellcode überhaupt ausgeführt werden kann, muss er kompiliert werden. Bisweilen muss ein Entwickler während der Ausführung des Programms an bestimmten Stellen den Ausführungsfluss Schritt-für-Schritt überwachen (“debuggen”), wozu die Anwendung in den Arbeitsspeicher geladen werden muss.
Der Quelltext bewegt sich auch nicht im luftleeren Raum: Anwendungen werden in Projekte und Bibliotheken aufgeteilt, häufig handelt es sich um einige hunderte bis tausende Dateien, die gemeinsam kompiliert und in den Arbeitsspeicher geladen werden müssen. Allein das Lesen der Quelltexte und das Erstellen der Kompilate kann bei mittelgroßen Anwendungen mehrere Minuten, bei größeren sogar viele Stunden andauern.
Auch wenn IDEs inkrementelles Kompilieren ermöglichen, wird des öfteren ein “Build” (alle Kompilate und dazugehörige Dateien) wieder gelöscht und vollständig neu erstellt.Zudem sind Softwareanwendungen im Unternehmensumfeld verteilt und kommunizieren mit Datenbanken, anderen Systemen und/oder der im Unternehmen eingesetzten Middleware.
Normalerweise ist der Entwickler bestrebt, auf seinem Rechner die Bedingungen, unter denen seine Anwendung später ausgeführt werden soll, en miniature nachzubilden: Auf diese Weise ist er unabhängig von Wartezeiten und kann ggf. auch offline (z.B. im Zug) arbeiten.
Was deshalb wirklich entscheidend für einen Entwicklerrechner?
Die Leistung:
Ein Softwareentwickler benötigt ein für seine Ansprüche äußerst leistungsfähiges System, was sich insbesondere auf
a) die Festplatte
b) den Hauptspeicher
c) die CPU und
d) Grafikkarte + Display bezieht.
Die Festplatte ist deshalb so wichtig, weil zum Erstellen von “Builds” oft tausende Dateien gelesen und geschrieben werden. Normalerweise liegt in langsamen Festplatten der Schwachpunkt von Entwicklersystemen (abgesehen von Virenscanner, die die Buildverzeichnisse überwachen). Sinnvoll können hier Solid State Discs (flash-basiert) oder RAID-Systeme (RAID 0 oder 0+1, aber nicht 5) mit SATA oder SAS sein, die den Datendurchsatz erhöhen.
Der Hauptspeicher muss sehr großzügig dimensioniert sein: Zur Zeit sollte ein Rechner für die Anwendungsentwicklung verteilter Systeme über mindestens 8 GByte Hauptspeicher verfügen, besser wäre gleich das Doppelte (einige Notebook-Workstations bieten mittlerweile 16 GByte an).
Softwareseitig bedingt dies den Einsatz von 64-Bit-Betriebssystemen.Wird mit virtuellen Maschinen gearbeitet (was immer mehr zunimmt), ist ein Mehrprozessor- wenigstens ein Multicoresystem sinnvoll. Um die Fülle an Informationen einer IDE wie Eclipse, Netbeans oder Qt auf einen Bildschirm zu bekommen, empfiehlt sich zudem ein hochauflösendes Display und eine entsprechende Grafikkarte.
Wie separat dargelegt, macht sich eine Leistungssteigerung bei Entwicklerrechnern schnell bezahlt. Um Entscheidern (und nach besserer Hardware strebenden Entwicklern) eine objektivere Entscheidungsgrundlage an die Hand zu geben, würde ich mir einen Benchmark wünschen, der
a) die Leistungsfähigkeit eines Systems hinsichtlich der o.a. Kriterien für einen Entwicklerrechner misst,
b) kostenlos verfügbar,
c) plattformunabhängig und
d) einfach bedienbar ist.
Ein Benchmark der mit Referenzprojekten arbeitet, der gängige IDEs startet, auf denen kleine, mittelgroße und große Referenzprojekte mit der IDE erstellt werden, wobei dies noch mit parallel laufenden Middlewareservern kombiniert werden sollte.
Falls jemandem ein solcher Benchmark bekannt ist, wäre ich dankbar für einen Hinweis ()! Interessenten, die ein derartiges Projekt auf die Beine stellen möchten, können mich gerne ansprechen.
30. August 2009 von KG
In Unternehmen verdrängen Entscheider außerhalb des IT-Umfelds gerne, dass Softwareentwickler Spezialisten sind und deshalb spezielle Hardware benötigen. Wer denkt, dass “Software schreiben” ungefähr mit dem Schreiben von Textdokumenten vergleichbar ist, liegt in etwa so richtig wie jemand, der meint, Autofahren hieße, auf einem Stuhl zu sitzen und beide Füße unregelmäßig auf- und abzubewegen.
Tatsächlich ist das Schreiben von Quellcode nur die Spitze des Eisbergs: Auf dem Entwicklerrechner wird dieser Quellcode nicht nur zu ausführbarer Software gemacht, sondern häufig eine vollständige Simulation der Unternehmensanwendungen ausgeführt, in deren Umgebung die Software verwendet werden soll. Also Datenbanken, Webserver, E-Mail-Server etc. etc.
Für den Entwicklerrechner bedeutet dies, dass er um ein Vielfaches leistungsfähiger sein muss als die Rechner, die man zur Erfüllung von Büroaufgaben verwendet.
Im Gegensatz zu Joel Spolsky statten viele Unternehmen ihre Softwareentwickler aber mit billiger Standardbürohardware aus. Meist muss schon die Aufrüstung des Arbeitsspeichers gesondert beantragt werden.
Was bedeutet das für die Entwickler? Vor allem müssen sie längere Wartezeiten in Kauf nehmen: Beim Kompilieren, beim Debuggen und Testen ihrer Anwendungen sowie beim Starten der IDE.
Was bedeutet das für die Unternehmen? Berechnen wir das einmal an einem Beispiel (aus meiner Praxis):
Die Entwickler eines größeren Finanzdienstleisters arbeiten mit Eclipse, die Anwendung wird in der Programmiersprache Java erstellt und ist in 10 voneinander abhängige Projekte (genauer: Maven-Module) gegliedert. Insgesamt handelt es sich um über viertausend Dateien, die kompiliert werden müssen (zuzügl. einiger Konfigurationsdateien).
Der durchschnittliche Rechner der Entwickler benötigt für das Erstellen eines Builds eine knappe halbe Stunde (mit Virenscanner über zweieinhalb Stunden).
In dieser Zeit können die Entwickler zumindest nicht programmieren, häufig nicht einmal mehr E-Mails lesen, weshalb der Arbeitsalltag so ausgerichtet ist, dass vollständige Builds zum einen vermieden und zum anderen auf den Morgen (Rechnerstart – Zeit für einen Kaffee) und die Mittagspause verlegt werden.
Im Team wird verteilt gearbeitet und regelmäßig integriert (d.h., Entwickler, die an Modul A arbeiten, stellen ihre Änderungen zur Verfügung, Entwickler, die an Modul B arbeiten, holen sich die aktualisierten Quelltexte von der Versionsverwaltung, was häufiger zur Folge hat, dass ein vollständiges Build erzeugt werden muss), wodurch zwei vollständige Builds am Tag die Regel sind.
Gehen wir vorsichtig von einem Durchschnittsgehalt von 60 T EUR für einen Entwickler mit mehr als sechs Jahren Berufserfahrung aus, ergeben sich folgende Kosten (Berechnungsgrundlage 223 Arbeitstage: 365 Kalendertage abzügl. Wochenenden (104 Tage), Feiertage (8 Tage) und Urlaub (30 Tage), 40-Stundenwoche):
Stundensatz
60.000 / 223 / 8 = 33,62 EUR
Auf zwei Builds zu je einer knappen halben Stunde am Tag bezogen bedeutete dies im ungünstigsten Fall (die Entwickler warten einfach nur, während das Build erstellt wird und sind ansonsten nicht weiter produktiv) jährliche Kosten von
223 x 33,62 EUR = 7.497,26 EUR pro Entwickler und
16 x 7.497,26 EUR = 119.956,16 EUR für das aus sechzehn Personen bestehende Team.
Die Verdopplung des Arbeitsspeichers und der Einbau schnellerer Festplatten bewirkte, dass ein vollständiges Build in gut 15 Minuten erstellt werden konnte.
Vergleicht man die Kosten für die Aufrüstung pro PC (450,- EUR für die Hardware, etwa 150,- EUR Personalkosten [Einbau durch Supporttechniker, Procurement] ) sieht man sofort, dass sich selbst bei einem geringeren Produktivitätsausfall als 100 % eine Investition in bessere Hardware schnell amortisiert:
Ersparnis rein rechnerisch:
119.956,16 EUR / 2* = 59978,08 EUR abzüglich 9.600,- EUR Hardwarekosten = 50.378,08 EUR
*Halbierung der Kompilierzeit
(Aufs Jahr bezogen wird somit eine Aufrüstung rentabel, sobald die festgestellte Produktivitätseinbuße bei über 8% liegt, was in jedem Fall gegeben ist.).
Weiterhin ist interessant, dass dieselben Rechner auch allen extenen Beratern zur Verfügung gestellt wurden. Deren Stundensatz lag dabei weitaus höher, wodurch sich die Investition noch schneller amortisierte.
Positive Seiteneffekte des Einsatzes leistungsfähigerer Entwicklerrechner sind zudem verbessertes Time-To-Market (offensichtlich) sowie ein besseres Betriebsklima (lange Buildzeiten frustrieren Entwickler, schnelle Rechner hingegen erfreuen sie).
11. April 2009 von KG
Mit großer Freude kann ich mitteilen, dass endlich der Durchbruch bei meinem "Akkordpermutationsprogramm" erfolgte: Das Programm ist in der Lage, die möglichen 68.586.311 Akkorde zu berechnen und zu speichern, alle Testabfragen gegen die Datenbank liefen erfolgreich.
Der Quellcode ist auf Google Code veröffentlicht, wenn auch noch nicht "gesäubert".
Für mich rückt die Fertigstellung eines musikalischen Projekts, das mich nunmehr seit über zwanzig Jahren begleitet, wieder in den Bereich des Realen.
Die Berechnungszeit dauert nur noch etwa 2 Tage, der erforderliche Speicherplatz ~35 GByte (im Vergleich zu mehreren Wochen und mind. 120 GByte). Auch wenn ich sie liebgewonnen hatte, bin ich von der H2-DB wieder zu MySQL zurückgekehrt, da H2 offensichtlich kein Index-based Locking unterstützt und mit versetzten Transaktionen nicht zurechtkam.
Für alle Nichteingeweihten: Was das Programm bewirkt, warum es sinnvoll sein kann, über 68 Millionen Akkorde zu berechnen und zu speichern, folgt später in einem ausführlicheren Beitrag.
10. Januar 2009 von KG
Problem
Bei der Arbeit mit Maven und Eclipse an einer modular aufgebauten Anwendung (mehrere Eclipse-Projekte, Maven mit dem m2Eclipse-Plugin, "Mama-POM" und Modulprojekte) vermeide ich abhängige Projekte, da es einen Unterschied macht, ob man mit dem physikalischen Ergebnis, also dem Maven-Artefakt, oder mit einem verknüpften Eclipse-Projekt arbeitet.
Vielen Probleme damit führten dazu, standardmäßig Disable Workspace Resolution und Disable Nested Modules zu wählen.
Das macht aber das Debuggen schwierig: Beim Debuggen möchte man beim Debuggen direkt in den Quellcode der mit der Startanwendung verbundenen Modulprojekte springen.
Defaultmäßig ist das nicht möglich, vielmehr wird die .class-Datei im Editor angezeigt. Hier hilft auch nicht, den Ort des Source-Codes in den Maven-Abhängigkeiten manuell mitzuteilen.
Verlinkte Quellordner (siehe linked resources) helfen hier nicht.
Lösung
In den Debug-Einstellungen als Quellordner die Modulprojekte angeben über Debug->Open Debug Dialog->Source.
Tip
Wenns beim Debuggen von WTP-Projekten dennoch nicht funktioniert, daran denken, den Server im Debug-Modus zu starten
24. November 2008 von KG
Sometimes you need to run your unit tests using DB2 TIMESTAMP values in your test data to match specific records. You can’t just use a Date() objekt because you have to specify nanoseconds.
As I couldn’t find any code snippet via Google, this might be helpful for you, dear reader.
Example: You want to check for a timestamp of ’2006-02-15 12:05:19.861555′ (within quotes, as shown by one of my favourite SQL clients, SQuirrel SQL).
DateFormat formatter = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" );
Date theMilliDate = formatter.parse( "2006-02-15 12:05:19" );
Timestamp timestamp = new Timestamp(theMilliDate.getTime());
// Note the trailing zeros!
timestamp.setNanos(861555000);
// validFrom would be of type java.util.Date
myEntityObjekt.setValidFrom(timestamp);
This – at least – does the trick, if you know of a better solution, please share it
28. Oktober 2008 von KG
Manchmal benötigt man ein JAR, das nur Testklassen enthält, um diese in mehreren Projekten zu verwenden. Dieses erstellt man wie folgt:
1. Test-JAR im Ausgangsprojekt erstellen
In der pom.xml des Projekts, dessen Testklassen verwendet werden sollen, erstellt man ein separates JAR über eine Änderung des maven-jar-plugins:
<plugins>
<!-- Weitere Plugins -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>test-jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
2. Test-JAR verwenden
In der pom.xml eines Projekts, welches das JAR mit den Testklassen verwenden soll, trägt man eine Dependency mit einem classifier ein:
<dependency>
<groupId>de.buergel.bas</groupId>
<artifactId>bas-spring.server</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>test</scope>
<classifier>tests</classifier>
</dependency>
Siehe dazu den ausführlichen Blogeintrag von Walter Cedric (Englisch).
21. Oktober 2008 von KG
Legacy systems often contain composite natural keys, i.e. identifiers composed from different database fields.
Hibernate offers three ways to deal with it. One is the @IdClass annotation that allows you to create an annotation-free class containing all the fields you like to use and use those fields again in your annotated entity class, annotating them with @Id.
Normally you need to map the class member name with the database field name. I.e. if you use the members userId and versionId, it’s quite likely you have to map them to database fields named USER_ID and FIELD_ID.
With the JPA annotations you do so using the @Column-annotation. But there is a bug. Hibernate completely ignores the @Column annotation if used in conjunction with other annotations, e.g. @Id.
See http://opensource.atlassian.com/projects/hibernate/browse/ANN-756
Please vote for fixing this ugly, ugly bug.
13. September 2008 von KG
Ralph Bergmann, Student an der FHTW Berlin, hat mit viel Energie und Elan die Java User Group Berlin-Brandenburg (re-)vitalisiert. Höhepunkt seiner Aktivitäten ist die erste Berliner Fachkonferenz um die Programmiersprache Java, die berlin.jar.
Im Vergleich zu den großen kommerziellen Java-Konferenzen (in Deutschland die JAX, US-international die Java One) nimmt sich die berlin.jar bescheiden aus:
Alle Besucher (zumindest, die mit denen ich sprach) wurden von Ralph Bergmann persönlich begrüßt.
Nett.
Jedenfalls etwas ganz anderes als die spektakulären Bühnenbegrüßungen von Sebastian Meyen, der ansonsten auf der JAX stets recht arrogant/gestresst agiert, wenn man sich nicht durch Anzug oder Speaker-T-Shirt ausweisen kann.
An zwei Tagen werden Samstags vier Vorträge in fünf Tracks angeboten, am Sonntag drei. Daneben können Samstags noch Workshops besucht werden (v.a. Eclipse RCP und Tomcat 6).
Die Konferenz findet – naheliegend – in den Räumen der FHTW Berlin in der Treskowallee statt. Menschen von der User Group und offenbar auch Studenten (?) unterstützen die Veranstaltung, ein einem Gang sind drei Stände aufgebaut.
Essen wird an Grill und Suppenküche ausgegeben, leider alles nicht ganz mit den Veranstaltungszeiten koordiniert. Für die erste Veranstaltung dieser Art, zudem nichtkommerziell, ist das akzeptabel.
Was macht aber eine Konferenz wertvoll? Natürlich die mobile Massage in der Relax-Lounge! Mögen manche sagen. Andere finden eher die Qualität der Vorträge entscheidend. Hier braucht sich die berlin.jar nicht zu verstecken: Von Oliver Böhm über Peter Roßbach (!Tomcat Workshop!) zu Eberhard Wolff sind viele Größen der deutschen Java-Community vertreten. Die Qualität der von mir besuchten Vorträge braucht sich zumindest hinter denen der Vorträge auf der JAX nicht zu verstecken.
Alles in allem eine lohnende Veranstaltung, für den lächerlich niedrigen Eintrittspreis (15,- EUR im Vorverkauf, Verköstigung inklusive) bekommt im Vergleich zu den kommerziellen Veranstaltungen ein Vielfaches als Gegenwert.
Dieses Angebot nutzten am ersten Tag nach meiner Einschätzung (Mittagessen und "Abendparty") mehr als 100, aber sicherlich weniger als 250 Teilnehmer, davon etwa 3% Frauen (leider nicht eine einzige Vortragende, sehr schade, dass Angelika Langer nicht anwesend war).
Hochachtung verdient Ralph Bergmann und seinen Helfern für den Einsatz, der weitaus mehr von einer Begeisterung für die Technologie spricht als von reinem Profilierungsdrang. Dazu wurde zuviel gelächelt.
4. September 2008 von KG
Letztens eine Nachricht über XING erhalten. Der Absender zeigte sich erfreut über meine dort hinterlegten Interessen, als da wären:
Softwareentwicklung mit agilen Methoden, Java EE (JEE), J2EE, Java2EE, Java, Ruby, Linux, JSF, Spring, Hibernate, SCALA, JBoss Seam, Maven, Apache Software Foundation, Eclipse, Eclipse RCP, NetBeans, Rules Engines, Middleware, SOA, BPM, ITIL, TOGAF, Zachman, Lean Management, IT-Strategie, Neue Musik, Klassische Musik, Musizieren, Klavier, Klarinette, Literatur (speziell Lyrik), Literatur, Bildende Künste, Kunst, Kulturgeschichte, Kunstgeschichte, Berlin, London, Venedig, Paris, Florenz, Rechtsinformatik, Italien, Großbritannien, English Literature, English Verse. Werke u.a. folgender Personen: Fowler, Tiepolo, Eisenstein, Braudel, Schnitzler, Ligeti, Knuth, Pushkin, Satie, Bellini, Monteverdi, Adams, Veronese, Shelley, Brecht, Dowson, Brahms, Montaigne, Schumann, Kubrick, Rameau, Bartok, Huizinga, Mahler, v. Bingen, Lenau, Frisch, Lenz, Olbrisch, Brunelleschi, Lichtenberg, Turner, Günther, Trakl, Scelsi, Redon, Streeruwitz, Flaubert, Friedell, Naso, Wilde, Bernhard, Erasmus, Gernhardt, Klimt, Palladio, Rückert, Härtling, Flaccus, v.d. Weyden, Balthus, Reynaldo Hahn, Caroll, Borodin, Verlaine, Mörike, Schobert, Villon, Greenaway, Heym, Thelen, Watteau, Abschatz, Jelinek, Bach (4x), Huysmans, Schiele, Ravel, Walser, V. Klemperer, Augustinus, Kling, Mann (2x), Gombrich, Stroustrup, Auster, Brüder Limburg, Franck, Purcell, Fellini, Truffaut, Hofmannsthal, Pollock, Schubert, Bresdins, Ariès/Duby, Bulgakow, Lenz, Proust, Neruda, de Beauvoir, Brouwer, Fragonard, Degas, Kurtag, Zelenka, Pepys, Rimbaud, Giorgione, Bachmann, Vian, Wilder, Wilmot/Rochester, Brinkmann, Callot, Opitz, Couperin, Ockeghem, Giacometti, Celan, Klinger, Catull, Sterne. Laufen, Laufsport, Joggen, Marathon.
Diese hatte ich schon vor längerer Zeit einmal zusammengekramt, um einer schmerzhaft Geliebten zu erkennen zu geben, ich wäre der richtige für sie, allein meiner Interessen wegen. (Magisches Denken, Zaubersprüche der Kindheit, nur transzendiert.).
Tatsächlich erkannte ich nach einer Weile, dass diese Frau sich weder für mich noch für wenigstens 10% der aufgeführten “Inhalte” hinter den Namen interessierte.
Wär mir letzteres wiederum von Anfang an bekannt gewesen, hätte ich gar nicht damit begonnen, ihr nichtvorhandene Gemeinsamkeiten zu unterstellen (Gegengeschlechtlichkeit ist ja wirklich keine Gemeinsamkeit.).
Und auch kein ernsthaftes Interesse für sie entwickelt.
Das wirft bei mir die Frage auf, ob es nicht irgendeinen Social-Web-Dienst gibt, bei dem man solche Informationen nicht hinterlegen kann, um eine “Interest Map” zu erstellen, die man dann mit der anderer Nutzer vergleichen kann. Auf diese Weise könnte man eine Sozial-DNA erstellen, und Menschen finden, die ähnliche Interessen haben / Ziele verfolgen.
Am besten noch mobil die Sozial-DNA gegeneinander abgleichen können. Und das noch für berufliche Profile und private. Und eine “Heat Map”, die anzeigt, wo sich im Raum die Leute befinden, mit denen man zumindest die Interessen teilt. Etc. Etc. (z.B. mit sozioökonomischen und politischen Kriterien).
Datenschutz wäre da ein noch sensibleres Thema als bei den gängigen “Social Tools”. Mir erschiene so etwas jedenfalls sinnvoller als die ganzen “Legacy DNA” Startups wie Navigenics etc., die einem alles und nichts zu der eigenen DNA mitteilen. Die Möglichkeit, die “Social DNA” (die keinen Status ausdrückt, sondern mikroindividuelle Differenzierung) verändern zu können, ist hier entscheidend: Jeder Mensch hat ja die Möglichkeit, sein Profil zu verändern. Ggf. sollte man sogar von vornherein angeben können, in welche Richtung man sich entwickeln möchte, was man nicht kennt, aber kennen möchte etc.
Konkreter sollte das ganze so gestaltet sein, dass für den Grunddatenbestand eine Anzahl von etwa 100 unterschiedlichen “Leads” (Schlüsselpersonen) ihre inhaltlichen, kulturellen, religiösen, sportlichen, politischen Interessen und Kenntnisse, Ziele und Vorlieben mitteilen, am besten über eine Liste von Stichwörtern wie oben dargestellt.
Diese wird dann geparst, bestehenden Schlüsselobjekten und semantisch zugeordnet. Danach erfolgt dann eine Auswertung / Neuindexierung der ermittelten Objekte durch die Nutzer. Sind die Schlüsselbobjekte zugeordnet, werden sie bewertet: Bei “Werken”, Künstlerinnen, Musikstücken (kristalline Intelligenz) vor allem nach Vorlieben (mag ich / mag nicht / mir unbekannt), bei konzeptionellen Schlüsselobjekten (fluider Intelligenz) auch nach Fähigkeit (verstehe/kann ich, verstehe/kann ich nicht / mir unbekannt).
Dieser Grunddatenbestand kann dann von anderen übernommen und weiter angepasst werden.
Das ganze mit der Möglichkeit, sich mit anderen Nutzern “zu verbinden”, von ihnen Objekte zu übernehmen und für sich selbst zu bewerten, zu suchen und sich finden zu lassen und sich eine Timeline anzeigen zu lassen, aus der man später ermitteln kann, wie sich die eigene Social DNA verändert hat.
Falls jemand einen solchen Dienst kennt, wär ich für einen Hinweis sehr dankbar
29. August 2008 von KG
Dieser Fehler kann auftreten, wenn eine Archivdatei (*.jar) aus irgendeinem Grund ungültig ist. Abhilfe schafft hier am ehesten
- das jar noch einmal zu bauen, wenn man es selbst mit Maven, Ant oder der IDE erstellt hat;
- wenn man einen Archivmanager (insb. WinZip) verwendet hat, um das jar manuell zu erstellen, einen anderen Archivmanager, etwa 7-zip oder izarc zu verwenden;
Natürlich muss man erst einmal das schuldige *.jar ermitteln, was unter Umständen gar nicht so leicht ist. Wenn die webapp zuvor problemlos lief, am besten nach absteigendem Datum alle jars nacheinander entfernen.
12. Juli 2008 von KG
Hier einige Kniffe für Maven, die häufiger angefragt (oder von mir selbst benötigt) werden. Siehe auch die Maven-FAQ (die Code-Snippets lassen leider immer noch auf sich warten) und die FAQ vom Codehaus-Wiki.
Ein Tip: Installiert man das mittlerweile stark ausgereifte m2 Maven-Plugin von Codehaus, findet man weitere sehr nützliche Hinweise in der Eclipse-Hilfe, die den gesamten "Definite Guide" integriert, mit Suchfunktion.
Die letzten Versionen des Plugins wären eigentlich einen eigenen Eintrag wert: Es kommt jetzt mit einem schon ansprechenden POM-Editor daher, der an die Editoren für die Eclipse-RCP-Entwicklung erinnert (etc. etc. etc., WTP-Unterstützung ist im Codehaus-Wiki beschrieben), aber Achtung: Die Eclipse-Update-URL hat sich geändert zu http://m2eclipse.sonatype.org/update/ resp. http://m2eclipse.sonatype.org/update-dev !
Test umgehen
An der Kommandozeile:
-Dmaven.test.skip=true
In der pom.xml:
<plugins>
<!-- ...weitere Plugins... -->
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
Fremdes Archiv in lokales Repository deployen
Kommt insb. vor, wenn man kommerzielle Archive, die nicht öffentlich verfügbar sind, in sein lokales Repository übernehmen möchte. Oder irgendwelche obskuren Legacy-jars, die mit Ant gebaut werden
)))
Man benötigt eine rudimentäre pom-Datei, Teil-Struktur ggf. von http://www.mvnrepository.com/ holen.
Hier ein POM fürs Substance L&F:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.jvnet</groupId>
<artifactId>substance</artifactId>
<version>4.3.11</version>
<packaging>jar</packaging>
<name>Substance Look and Feel</name>
<url>https://substance.dev.java.net/</url>
<description>Private deplomyent, not from Sun!</description>
<dependencies />
</project>
Jetzt an der Kommandozeile in das Verzeichnis wechseln, in dem sich jar und Dummy-POM-Datei befinden und deployen (diesmal fürs jnlp-Servlet):
mvn deploy:deploy-file -Dfile=jnlp-servlet-1.0.jar -DpomFile=openswing-jnlp-servlet.pom -DrepositoryId=release -Durl=http://10.45.7.7:7575/archiva/repository/internal -e
Wirksame Konfiguration anzeigen
mvn help:effective-pom (Siehe die nützlichen weiteren Features hier).
War erstellen
In pom.xml (Unterelement von <project>):
<packaging>war</packaging>
Ggf. das Maven-War-Plugin verwenden und <exclusion> für JEE-Bibliotheken.
Zum Bauen
mvn package
Build ausführen (sic)
mvn compile / mvn package
(Und den "Definite Guide" lesen, um das Konzept zu verstehen <kicher>).
JDK festlegen (zum Kopieren)
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.0.2</version>
<configuration>
<source>1.6</source><!-- oder 1.4 oder 1.5 etc.-->
<target>1.6</target><!-- oder 1.4 oder 1.5 etc.-->
</configuration>
</plugin>
(Fortsetzung folgt…)
19. Juni 2008 von KG
Das Problem, das unter https://issues.apache.org/activemq/browse/AMQ-1638 beschrieben wird, nämlich, dass Spring solche Konfigurationsdateien nicht lädt, wenn keine Internetverbindung möglich ist, ist leider nicht behoben.
Der dort beschriebene Workaround, in der Spring-Konfigurationsdatei (mit XML-Schema) die Datei activemq.xsd zu referenzieren, schlug leider fehl.
Ein Kollege ermittelte einen sicheren, wenn auch manuellem Workaround: In der Datei [activemq-JAR]/META-INF/spring.schemas folgendes hinzufügen (d.h., aus dem jar extrahieren, ändern und die Datei wieder hinzufügen):
http\://activemq.apache.org/schema/core/activemq-core-5.1.0.xsd=activemq.xsd
Hier noch die Fehlermeldung für die Suchmaschinen
WARNUNG: Ignored XML validation warning org.xml.sax.SAXParseException: schema_reference.4:
Failed to read schema document 'http://activemq.apache.org/schema/core/activemq-core-5.1.0.xsd', because
1) could not find the document;
2) the document could not be read;
3) the root element of the document is not <xsd:schema>.
24. März 2008 von KG
Beim Versuch,
<el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
zu verwenden (Update auf Spring 2.5 und MyFaces 1.2), trat eine seltsame Fehlermeldung auf:
- Parse Error at line 2 column 14: Document is invalid: no grammar found.org.xml.sax.SAXParseException: Document is invalid: no grammar found. at org.apache.xerces.util.ErrorHandlerWrapper.createSAXParseException(Unknown Source) at org.apache.xerces.util.ErrorHandlerWrapper.error(Unknown Source) at org.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source) at org.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source) at org.apache.xerces.impl.XMLNSDocumentScannerImpl.scanStartElement(Unknown Source) at org.apache.xerces.impl.XMLNSDocumentScannerImpl$NSContentDispatcher.scanRootElementHook(Unknown Source) at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown Source) at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source) at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source) at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source) at org.apache.xerces.parsers.XMLParser.parse(Unknown Source) at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source) at org.apache.commons.digester.Digester.parse(Digester.java:1745) at org.apache.myfaces.config.impl.digester.DigesterFacesConfigUnmarshallerImpl.getFacesConfig(DigesterFacesConfigUnmarshallerImpl.java:186) at org.apache.myfaces.config.FacesConfigurator.feedWebAppConfig(FacesConfigurator.java:541) at org.apache.myfaces.config.FacesConfigurator.configure(FacesConfigurator.java:133) at org.apache.myfaces.webapp.StartupServletContextListener.initFaces(StartupServletContextListener.java:68) at org.apache.myfaces.webapp.StartupServletContextListener.contextInitialized(StartupServletContextListener.java:51) at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:3843) at org.apache.catalina.core.StandardContext.start(StandardContext.java:4350) at org.apache.catalina.startup.HostConfig.checkResources(HostConfig.java:1114) at org.apache.catalina.startup.HostConfig.check(HostConfig.java:1212) at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:293) at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:117) at org.apache.catalina.core.ContainerBase.backgroundProcess(ContainerBase.java:1337) at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1601) at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1610) at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.run(ContainerBase.java:1590) at java.lang.Thread.run(Thread.java:619)
Ursache waren zwei MyFaces-jars mit Version 1.1.5 im WEB-INF/lib-Verzeichnis der Webanwendung. Dies ist ein Problem beim Zusammenspiel von MyEclipse und dem Maven-Plugin (Codehaus): Hier muss man zunächst Project->Clean ausführen und dann manuell ein zweites Deployment durchführen.
Dies gilt leider in unregelmäßigen Abständen (!) für jede Änderung von Dateien, die keine Java-Klassen sind (also z.B. *.xhtml-Dateien für Facelets etc.).
Zusätzlich: Unbedingt auch die Kompatibilitätsmatrix von Tomahawk und ggf. Trinidad zur verwendeten MyFaces-Version prüfen und zwar im MyFaces-Wiki.
Dabei für Facelets und Tomahawk (allgemein dazu siehe hier) noch ggf. die Kompatibilität mit dem tomahawk-facelets-Projekt beachten. Hier können sich insbesondere die Sandbox-Tags auch nachträglich geändert haben.
19. Februar 2008 von KG
Endlich eine brauchbare, ausführliche und nach Versionen vergleichende Referenz für die JVM-Optionen gefunden:
http://blogs.sun.com/watt/resource/jvm-options-list.html
Wenn sie sich primär auch auf Solaris/SPARC beziehen mag, ist sie mehr als nützlich.
16. Januar 2008 von KG
Wird immer mal wieder angefragt: Gesetzt den Fall, man möchte in einem Ant-Script auf eine Umgebungsvariable zugreifen, was man normalerweise so macht:
<property environment="env" /> <property name="dist-conf" location="${env.DIST_PATH}/conf" />
Dann kann man diese Variable an der Kommandozeile wie folgt überschreiben:
ant -Denv.DIST_PATH=/path/to/the/dir
Um einmal gesetzte Variablen zu überschreiben, ist der Ant-Contrib-Variable-Task (siehe http://ant-contrib.sourceforge.net/) die Lösung der Wahl.
1. Dezember 2007 von KG
Beim Arbeiten mit AndroMDA auf ein Problem gestoßen, als sich ein Projekt nicht mehr erzeugen ließ; im Forum schließlich diesen Hinweis gefunden.
Der Grund: Abhängige Module benötigen ab Maven 2.06 immer in ihrer eigenen pom.xml ebenfalls die Angabe der Versionsnummer. Zur Umstellung siehe die gesonderte Seite hier.
Glücklicherweise arbeite ich mit einer Struktur, in der ich Build-Tools in ein Defaultverzeichnis "current" packe, so dass schnell auf eine andere Version gewechselt werden kann.
Nichtsdestotrotz finde ich es wenig verständlich, wenn in einem Minor-Release eine derart elementare strukturelle Veränderung vorgenommen wird. Als Maven-Anwender hätte ich mir allenfalls eine Warnung gewünscht mit Rückfall auf die ältere Funktionalität.
Wozu gibt man denn in Maven die Versionsnummer im <modelVersion>-Element der pom.xml überhaupt an, wenn nicht auch für eine Abwärtskompatibilität? Sehr merkwürdig.
30. November 2007 von KG
Eine dieser immer wieder auftauchenden, häßlichen MyEclipse-Fehlermeldungen.
Abhilfe schafft, über Windows->Preferences->Validation den jeweiligen Button in der Spalte Settings zu wählen und dann einen Validator-Typen zu wählen, danach ggf. noch Project->Clean.
Hinweis für Eclipse: Deselektiert man über Windows->Preferences->Validation eine Validierung komplett und sollte eine Datei bereits als invalid markiert sein, hilft, erneut Validate im Kontextmenü des Eintrags im Project-/Package-Explorer/Navigator zu wählen (geht mit Clean nicht weg).
17. Oktober 2007 von KG
Hier half, über Windows, Preferences, MyEclipse, Application Servers, [TC-#] folgendes hinzuzufügen:
-Djavax.xml.transform.TransformerFactory=com.icl.saxon.TransformerFactoryImpl -Djavax.xml.parsers.DocumentBuilderFactory=org.apache.xerces.jaxp.DocumentBuilderFactoryImpl-Djavax.xml.parsers.SAXParserFactory=org.apache.xerces.jaxp.SAXParserFactoryImpl-Dorg.xml.parsers.sax.parser=org.apache.xerces.parsers.SAXParser
Siehe dazu auch nur Xerces als Default-Parser setzen.
14. August 2007 von KG
Da kann man schon drüber "fallen": In der CLI-Implementierung von Jakarta darf man keinesfalls die Parameterabkürzungen gleichzeitig als Argumente verwenden. Das mag manchem vielleicht selbstverständlich scheinen, doch da CLI immer für die Parameterabkürzungen einen vorangestellten Bindestrich verlangt, ist es das IMHO nicht.
Nun ja, aber wenn das Problem bekannt ist, braucht es nur noch umgangen zu werden.
26. Juli 2007 von KG
Auf Googles Singleton-Detector gestoßen und mir noch einmal die Begründungen angeschaut, weshalb Singletons böse sind. Das ist alles nicht wirklich neu, wiewohl aus meiner Sicht ein Singleton durchaus Sinn machen kann (gilt die Kritik nicht eigentlich jeder statischen Factory-Methode?).
Wie auch immer, für mich ist guter Stil, zu begründen, weshalb man ein Singleton verwendet. Ebenso, wie man manchmal explizit nichts in einem Code-Block ausführen möchte:
if(this){ do();}else if (scary){ // empty on purpose!}else{ doOther();}
(da gäbs sicherlich bessere Beispiele, ein besseres wäre der leere private Konstruktor von nicht instantiierbaren Klassen), sollte man im JavaDoc eines Singletons erwähnen, dass es sich um eines handelt, weshalb es als Singleton verwendet wird und ggf. wie es getestet werden kann resp. welche Besonderheiten für das Testen von Klassen anfallen, die das Singleton verwenden.
Das geht höchstwahrscheinlich darüber hinaus, was z.B. in Spring mit den DAO-Klassen erfolgt (sollen die alle schlecht sein?), ist aber gerade für die Arbeit im Team nützlich.
11. Juli 2007 von KG
Wenn das Ekel LAF angezeigt wird:
UIManager.put("ClassLoader", LookUtils.class.getClassLoader()); UIManager.setLookAndFeel(new Plastic3DLookAndFeel());
9. Juli 2007 von KG
Dieser Tasks hats wegen der doch sehr dürftigen Dokumentation in sich, zumal wegen der RegExpr-Syntax für Java.
Backslash maskieren
<replaceregexp match="a:\\" replace="b:\\\\" flags="gi"> <fileset dir="${build}${/}xml" id="XmlStuff"> <include name="takeme*.xml"/> </fileset> </replaceregexp></target>
Punkt maskieren (z.B. für Paktebezeichner)
<replaceregexp match="com\.old\.style\.business" replace="org\.new\.style\.business" flags="gi"> <fileset dir="${the.path}" id="pathy"> <include name="Groov*y.java"/> </fileset></replaceregexp>
Das Flag "gi" bedeutet: global (alle Vorkommen der gefundenen Zeichenfolge), [case-] insensitive (Groß-/Kleinschreibung nicht beachten).
3. Juni 2007 von KG
Bug, Bug, Bug! http://bugs.typo3.org/view.php?id=3224, da kann man sich nicht herausreden.
Die Lösung funktioniert – einfach nur darauf achten, dass die Lib eingebunden ist, dann gehts. Hier mein TypoScript:
# Menu 1 cObjectlib.menu_1 = HMENUlib.menu_1 { ### Erste Ebene - special value ist die Startseite mit den Servicemenüeinträgen ### special = directory special.value = 50 1 = TMENU 1 { NO.allWrap = <div class="nav"> | </div> ACT = 1 ACT.allWrap = <div class="nav"> | </div> } ### Zweite Ebene ### 2 = TMENU 2 { NO.allWrap = <div class="navsub"> | </div> ACT = 1 ACT.allWrap = <div class="navsub"> | </div> } }}
[PIDinRootline = 50] lib.menu_1.special > lib.menu_1.entryLevel = 1[END]
27. Mai 2007 von KG
Weiterhin mit der Homepage für St. Hildegard beschäftigt. Das Layout notgedrungen erst einmal vom Dreispalten-CSS auf ein Tabellenlayout zurückgestellt
Das ansonsten phantastische CSS-Menü von Stu Nicholls vermochte ich nicht dazu bewegen, die überlangen <li>-Tags nicht umzubrechen.
Wie auch immer – während der Beschäftigung mit dem Layout fiel mir immer wieder auf, wie wenig standardkonform doch der Internet Explorer ist. Und dass sich Webdesigner offenbar überwiegend damit beschäftigen, ihre Seiten für alle Browser, insbesondere aber für den IE wie gewünscht präsentieren zu können.
Welch ein Wahnsinn ist das nur? Da wird ein objektiv (der W3C-Standard ist objektiv) fehlerhaftes Softwareprodukt gebündelt mit einem Betriebssystem zur Verfügung gestellt und wegen der hinter diesem Betriebssystem stehenden beherrschenden Marktposition müssen Unternehmen auf der ganzen Welt Geld ausgeben, um die Fehler dieser Software zu umgehen.
Ich glaube nicht, dass dies die Arbeitsplätze der Webdesigner sichert – deren Arbeit ist so oder so gefragt. Aber ihre Leistung wird verschlechtert, da sie sich um Dinge in der zur Verfügung stehenden Zeit kümmern müssen, die eigentlich gar nichts mit ihrer Tätigkeit zu tun haben.
All die Stunden der sinnlos mit IE-Inkompatiblitäten vergeudeten Zeit zusammengerechnet liegt hier ein betriebs- und volkswirtschaftlicher Schaden in Milliardenhöhe vor, um den sich niemand kümmert. Da glaubt man lieber Zusicherungen, der IE sei doch sehr standardkonform und belässt es dabei. Beängstigend.