Ein Kollege hat heute einen Link zu einer schönen Übersicht über die Standard Java Collections herumgeschickt.
Veröffentlicht in Technisch | Verschlagwortet mit Code, collections, java, java collections, Programmieren | Kommentar schreiben »
Wenn ihr Apache Felix nutzt und die telnet Shell aktiviert habt
osgi.shell.telnet.port=6666
Könnt ihr mit folgendem Skript einfach eure Bundles aktualisieren.
#!/usr/bin/perl
use strict;
use warnings;
use Net::Telnet;
if (@ARGV != 2) {
print "$0: [bundle name substring] [bundle jar absolute path]\n";
exit 1;
}
my $bname = shift;
my $bfile = shift;
my $host = 'localhost';
my $port = 6666;
sub get_bundle_id($$) {
my ($procs, $bname) = @_;
my @proc = grep { m/$bname/i } @$procs;
die "No bundle $bname found." unless @proc > 0;
warn "Multiple bundles $bname found." if @proc > 1;
$proc[0] =~ m/^\[\s*(\d+)\s*\]/;
return $1;
}
my $prompt = '/->/';
my $telnet = new Net::Telnet ( Timeout=>10, Errmode=>'die', Prompt => $prompt);
$telnet->open(Host => $host, Port => $port);
$telnet->waitfor($prompt);
my @procs = $telnet->cmd('ps');
my $bid = get_bundle_id(\@procs, $bname);
print "Bundle id for $bname is $bid\n";
print "Updating bundle $bid with $bfile\n";
my @result = $telnet->cmd("update $bid file:$bfile");
print "Error: ", $result[0], "\n" if (@result > 0 && $result[0] =~ m/unable|error|fail/i);
print "done.\n";
Dies kann auch einfach in Maven integriert werden, dazu muss einfach sicher gestellt werden, dass das Skript im PATH vorhanden oder der Absolute Pfad angeben wird:
<!-- Directly deploy to osgi -->
<plugin>
<artifactId>exec-maven-plugin</artifactId>
<groupId>org.codehaus.mojo</groupId>
<version>1.1</version>
<executions>
<execution>
<phase>install</phase>
<goals>
<goal>exec</goal>
</goals>
</execution>
</executions>
<configuration>
<executable>osgi_deploy.pl</executable>
<arguments>
<argument>${project.name}</argument>
<argument>${project.build.directory}/${project.build.finalName}.jar</argument>
</arguments>
</configuration>
</plugin>
Die Ausführung:
$ mvn exec:exec
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Building MyProject
[INFO] task-segment: [exec:exec]
[INFO] ------------------------------------------------------------------------
[INFO] [exec:exec {execution: default-cli}]
[INFO] Bundle id for MyProject is 5
[INFO] Updating bundle 5 with /home/bpeter/workspaces/MyProject/trunk/myproject/target/myproject.jar
[INFO] done.
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
hf
Veröffentlicht in Technisch | Verschlagwortet mit apache felix, deployment, java, maven, osgi, skript, telnet | Kommentar schreiben »
Maven ist ein build Tool und Framework für java, welches es sich zum Ziel gemacht hat dem Anwender möglichst viele Schritte abzunehmen. In der allmächtigen pom.xml werden alle relevanten Optionen konfiguriert und ansonsten mit Konventionen in Form von Verzeichnissturktur und Dateinamen gearbeitet.
Das Framework erhält durch seine Pluginfähigkeit eine gute Flexiblität und ermöglicht viele Aufgaben durch ein wenig Konfiguration zu lösen.
Ich will hier eine maven Version meines vorherigen Apache ant Beispiels zeigen, die zum gleichen Ergebnis führt. Zudem gibt es einen kleinen Unit-Test, da das Framework deren Einbindung direkt mitbringt.
(Die resource files und merge Datei liegen bewusst in einem Verzeichnis um herauszufinden wie man die Filter verwendet.)
Code
Verzeichnisstruktur
Die Grundstruktur von Maven ist dabei standardmäßig wie folgt:
pom.xml src/main src/resources src/test src/test/resources
Im Beispiel:
./pom.xml ./src ./src/main ./src/main/java ./src/main/java/de ./src/main/java/de/benjaminpeter ./src/main/java/de/benjaminpeter/print ./src/main/java/de/benjaminpeter/print/LoadFile.java ./src/main/java/de/benjaminpeter/print/Print.java ./src/main/resources ./src/main/resources/resources ./src/main/resources/resources/inputA ./src/main/resources/resources/inputB ./src/main/resources/resources/merge ./src/main/resources/resources/file ./src/test ./src/test/java ./src/test/java/de ./src/test/java/de/benjaminpeter ./src/test/java/de/benjaminpeter/print ./src/test/java/de/benjaminpeter/print/LoadFileTest.java ./src/test/resources ./src/test/resources/resources ./src/test/resources/resources/file
Java src (analog zum ant Beispiel)
import java.io.*;
import java.lang.*;
public class LoadFile {
public String load() throws FileNotFoundException, UnsupportedEncodingException, IOException {
// File file = new File("resources/file");
// FileInputStream fis = new FileInputStream(file);
// Datei ist nun im jar, also muss sie anders geladen werden
ClassLoader cl = this.getClass().getClassLoader();
InputStream fis = cl.getResourceAsStream("resources/file");
// import groovy ... file.text ... :-/
BufferedReader in = new BufferedReader(new InputStreamReader(fis));
String str = "";
String ret = "";
while ((str = in.readLine()) != null) ret += str + '\n';
return ret.substring(0, ret.length() - 1);
}
}
import java.lang.*;
public class Print {
public static void main(String[] args) {
System.out.println("Hello.");
try {
System.out.println("Content:\n"+
new LoadFile().load());
}
catch (Exception e) {
System.err.println("Error: "+ e.getMessage());
}
}
}
Ressourcen
File: resources/file A: Build @buildNumber@ If the writeList method doesn't catch the checked exceptions that can occur within it, the writeList method must specify that it can throw these exceptions. Let's modify the B: original writeList method to specify the exceptions it can throw instead of catching them. To remind you, here's the original version of the writeList method that won't compile. File: resources/inputA A: Build @buildNumber@ If the writeList method doesn't catch the checked exceptions that can occur within it, the writeList method must specify that it can throw these exceptions. Let's modify the File: resources/inputB B: original writeList method to specify the exceptions it can throw instead of catching them. To remind you, here's the original version of the writeList method that won't compile. File: resources/merge #!/bin/sh cat $1 $2 > $3
Hierbei musste ich @date@ zu @buildNumber@ ändern, da es ohne größeren Aufwand nicht möglich properties in anderen properties zu verwenden. (Falls es jemand besser weiß immer her damit, finde das durchaus wichtig)
pom.xml
<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">
<!-- Basisinformationen zum Projekt -->
<modelVersion>4.0.0</modelVersion>
<groupId>de.benjaminpeter.print</groupId>
<artifactId>Print</artifactId>
<packaging>jar</packaging>
<!-- Version des Projekts in maven, der Name des
Jars kann noch einmal extra definiert werden! -->
<version>0.0.1</version>
<name>Print</name>
<url>http://maven.apache.org</url>
<!-- Default dependency fuer Unit-Tests, bibliothek
wird automatisch herunter geladen -->
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<!-- scope:
Gibt an, dass diese Abhaengigkeit nur
zum Testen benötigt wird. Das heißt sie wird
auch nur beim Ausführen der Tests
heruntergeladen und ist im
finalen jar/war nicht enthalten. -->
<scope>test</scope>
</dependency>
</dependencies>
<build>
<!-- Binde die resource "resources/file" ein, dies
wird dynamisch erzeugt wie wir später sehen. -->
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>resources/file</include>
</includes>
<!-- Zudem soll hier das
Filtering aktiviert werden,
das heißt wir lassen maven einen
Platzhalter @buildNumber@ in der
Datei ersetzen. -->
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<!--
Binde ein Plugin ein um die Build Nummer
variabler erstellen zu können. Hiermit machen
wir die Variable buildNumber vom aktuellen
Datum abhängig.
Auch das Plugin wird von maven bei Bedarf
dynamisch herunter geladen. -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>buildnumber-maven-plugin</artifactId>
<configuration>
<format>{0,date,yyyyMMdd}</format>
<items>
<item>timestamp</item>
</items>
</configuration>
<!-- Diese Block besagt, dass das Plugin in
der validierungsphase (ganz am Anfang)
ausgeführt werden soll. create ist dabei
eine von mehreren Funktionen des Plugins
die dabei aufgerufen werden soll. -->
<executions>
<execution>
<phase>validate</phase>
<goals>
<goal>create</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- Mit dem jar Plugin können wir
die Erzeugung des jar Files etwas
anpassen. So setzen wir hier die
MainClass fest um ein einfach
ausführbares jar zu bekommen. -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>Print</mainClass>
<packageName></packageName>
</manifest>
<manifestEntries>
<mode>development</mode>
<url>${pom.url}</url>
</manifestEntries>
</archive>
</configuration>
</plugin>
<!-- exec Plugin, dies ermöglicht es alle
Schweinereien zu machen die man
sonst nicht hinbekommt.
Wird hier auch zur Verfizierungsphase
ausgeführt und ruft den Befehl "merge"
aus dem resources Verzeichnis auf
um die Datei "file" zu erzeugen.
An dieser Stelle könnte man sicher auch
ein Ant Plugin einbinden um komplexere
Abläufe zu realisieren und Abhängigkeiten
sowie bereits angelegte Dateien erkennen
zu können. -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.1</version>
<executions>
<execution>
<phase>verify</phase>
<goals>
<goal>exec</goal>
</goals>
</execution>
</executions>
<configuration>
<executable>./merge</executable>
<workingDirectory>${basedir}/src/main/resources/resources</workingDirectory>
<arguments>
<argument>inputA</argument>
<argument>inputB</argument>
<argument>file</argument>
</arguments>
</configuration>
</plugin>
</plugins>
<!-- Setze den Namen der jar Datei so, dass
auch unsere im Plugin
erzeugte buildNumber eingesetzt wird. -->
<finalName>${project.artifactId}-${buildNumber}</finalName>
</build>
<properties>
<!-- Funktioniert leider nicht :-/ -->
<date>${buildNumber}</date>
</properties>
</project>
Ausführung
Build
$ mvn install
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Building Print
[INFO] task-segment: [install]
[INFO] ------------------------------------------------------------------------
Downloading: http://repo1.maven.org/maven2/net/java/dev/jna/jna/3.0.5/jna-3.0.5.pom
Downloading: http://repo1.maven.org/maven2/net/java/dev/jna/jna/3.0.5/jna-3.0.5.pom
[INFO] [buildnumber:create {execution: default}]
[INFO] Storing buildNumber: 20091030 at timestamp: 1256918122611
[INFO] [resources:resources]
[INFO] Using default encoding to copy filtered resources.
[INFO] [compiler:compile]
[INFO] Compiling 2 source files to /home/dedeibel/proggn/java/test/mvn-example/Print/target/classes
[INFO] [resources:testResources]
[INFO] Using default encoding to copy filtered resources.
[INFO] [compiler:testCompile]
[INFO] Compiling 1 source file to /home/dedeibel/proggn/java/test/mvn-example/Print/target/test-classes
[INFO] [surefire:test]
[INFO] Surefire report directory: /home/dedeibel/proggn/java/test/mvn-example/Print/target/surefire-reports
-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running LoadFileTest
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.031 sec
Results :
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO] [jar:jar]
[INFO] Building jar: /home/dedeibel/proggn/java/test/mvn-example/Print/target/Print-20091030.jar
[INFO] [exec:exec {execution: default}]
[INFO] [install:install]
[INFO] Installing /home/dedeibel/proggn/java/test/mvn-example/Print/target/Print-20091030.jar to /home/dedeibel/.m2/repository/de/benjaminpeter/print/Print/0.0.1/Print-0.0.1.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 7 seconds
[INFO] Finished at: Fri Oct 30 16:55:26 CET 2009
[INFO] Final Memory: 31M/290M
[INFO] ------------------------------------------------------------------------
Programm
$ java -jar target/Print-20091030.jar Hello. Content: A: Build 20091030 If the writeList method doesn't catch the checked exceptions that can occur within it, the writeList method must specify that it can throw these exceptions. Let's modify the B: original writeList method to specify the exceptions it can throw instead of catching them. To remind you, here's the original version of the writeList method that won't compile.
Fazit
Den direkten Vergleich zwischen ant und maven fand ich sehr interessant. Im kleinen Beispiel kann man die Stärken von maven jedoch nur erahnen. So hätte es bei ant wieder einer extra Einbindung der Unit-Tests bedurft, die aber im Grunde für jedes Projekt gleich ist wenn man sich an die Konventionen hält. Weiterhin musste kein Finger krum gemacht werden um eine aktuelle Version der junit Abhängigkeit zu bekommen; ein großer Vorteil bei einem Umzug auf ein anderes System, sofort werden die benötigten Abhängigkeiten ohne Aufwand nachgezogen.
Der Teufel steckt im Detail, während das Anpassen des Dateinamens und Ausführen des merge Skripts bei ant ein Kinderspiel sind, da man hier direkt auf die Abhängigkeiten und jar Erstellung Einfluss hat, scheint der Weg bei Maven für alles ein Plugin installieren zu müssen doch etwas umständlich. Letztendlich ist es aber eine Gute Sache, da es Plugins für die Unterschiedlichsten Aufgaben gibt und diese einem wie maven selbst möglichst viel Arbeit abnehmen. Allgemein sollte man sich vielleicht weniger mit Details aufhalten und gerade bei Verwendung von Frameworks Kompromisse eingehen und sich an die Gegebenheiten gewöhnen. Bei großen Projekten ist es auch so schwer genug die Übersicht zu behalten.
Quellen
Apache maven
Maven getting started
Die Vernachlässigung von tollen Namespaces für meine Klassen sie mir verziehen.
Veröffentlicht in Technisch | Verschlagwortet mit Code, java, build, maven, apache maven, mvn, maven2, beispiel, maven ant vergleich | 1 Kommentar »
Apache ant ist ein build Tool, hauptsächlich für Java, was XML Dateien als Konfiguration verwendet.
Ant war früher sehr populär und ist nun z.B. durch maven erweitert oder ivy ersetzt, da diese über automatische Abhängigkeitsauflösung verfügen. Beim Umgang mit maven können einige Ant Grundlagen nicht schaden.
Das folgende Beispiel baut zwei Klassen und packt diese dann mit den Resource files in ein gemeinsames Jar. Die Resource Dateien werden zuvor noch mit einem Zeitstempel versehen und zusammengeführt um die Möglichkeiten von ant zu demonstrieren.
In einem zweiten Beitrag zeiche ich die Umsetzung des gleichen Projektes mit maven. Apache Maven Beispiel
Code
Dateien
./build.xml ./resources ./resources/inputA ./resources/inputB ./resources/merge ./src ./src/LoadFile.java ./src/Print.java
Java Source
import java.io.*;
public class LoadFile {
public String load() throws FileNotFoundException, UnsupportedEncodingException, IOException {
char[] buff = new char[10240];
// File file = new File("resources/file");
// FileInputStream fis = new FileInputStream(file);
// Datei ist nun im jar, also muss sie anders geladen werden
ClassLoader cl = this.getClass().getClassLoader();
InputStream fis = cl.getResourceAsStream("resources/file");
InputStreamReader in = new InputStreamReader(fis, "UTF-8");
in.read(buff, 0, 10240);
return new String(buff);
}
}
import java.lang.*;
public class Print {
public static void main(String[] args) {
System.out.println("Hello.");
try {
System.out.println("Content:\n"+ new LoadFile().load());
}
catch (Exception e) {
System.err.println("Error: "+ e.getMessage());
}
}
}
Ressourcen
File: resources/inputA A: Build @date@ If the writeList method doesn't catch the checked exceptions that can occur within it, the writeList method must specify that it can throw these exceptions. Let's modify the File: resources/inputB B: original writeList method to specify the exceptions it can throw instead of catching them. To remind you, here's the original version of the writeList method that won't compile. File: resources/merge #!/bin/sh cat $1 $2 > $3
Ant build.xml
<project name="Print" default="build" basedir=".">
<description>
Print example build file
</description>
<!-- set global properties for this build -->
<property name="src" location="src"/>
<property name="build" location="build"/>
<property name="dist" location="."/>
<property name="resources" location="resources"/>
<!-- Vorbereitung der Resourcen -->
<target name="prep" depends="init">
<!-- Aufruf des Merge Befehls mit den Dateipfaden als Argumenten -->
<exec executable="${resources}/merge">
<arg value="${resources}/inputA"/>
<arg value="${resources}/inputB"/>
<arg value="${build}/resources/file.in"/>
</exec>
<!-- Setze einen Filter, dieser kann das Vorkommen von @token@
in Dateien während Kopierbefehlen durch einen Wert ersetzen.
Dazu muss bei copy zum Beispiel filterting="true" angegeben werden.
Hier wird ein Vorkommen von @date@ durch einen Timestamp ersetzt.
Die property DSTAMP kommt dabei vom Befehl mkstamp, welcher im
target init ausgefuehrt wurde. -->
<filter token="date" value="${DSTAMP}"/>
<!-- Kopiere die Datei um und wende dabei die Filter an -->
<copy tofile="${build}/resources/file" file="${build}/resources/file.in" filtering="true"/>
<delete file="${build}/resources/file.in"/>
</target>
<target name="init">
<!-- Create the time stamp, verfügbar als ${DSTAMP} -->
<tstamp/>
<property name="outjar" value="${dist}/${ant.project.name}-${DSTAMP}.jar"/>
<!-- Create the build directory structure used by compile -->
<mkdir dir="${build}"/>
<mkdir dir="${build}/resources"/>
</target>
<target name="compile" depends="init"
description="compile the source " >
<!-- Compile the java code from ${src} into ${build} -->
<javac srcdir="${src}" destdir="${build}"/>
</target>
<target name="build" depends="compile, prep"
description="generate the distribution" >
<jar jarfile="${outjar}" basedir="${build}">
<manifest>
<!-- Muss angegeben werden damit java die Hauptklasse
beim Ausfuehren des jars finden kann -->
<attribute name="Main-Class" value="Print"/>
</manifest>
</jar>
</target>
<target name="clean"
description="clean up" >
<!-- Delete the ${build} and ${dist} directory trees -->
<delete dir="${build}"/>
<delete>
<fileset dir="." includes="Print*.jar"/>
</delete>
</target>
</project>
Ausführung
$ ant
Buildfile: build.xml
init:
[mkdir] Created dir: /home/dedeibel/proggn/java/test/ant/build
[mkdir] Created dir: /home/dedeibel/proggn/java/test/ant/build/resources
compile:
[javac] Compiling 2 source files to /home/dedeibel/proggn/java/test/ant/build
prep:
[copy] Copying 1 file to /home/dedeibel/proggn/java/test/ant/build/resources
[delete] Deleting: /home/dedeibel/proggn/java/test/ant/build/resources/file.in
build:
[jar] Building jar: /home/dedeibel/proggn/java/test/ant/Print-20091030.jar
BUILD SUCCESSFUL
Total time: 2 seconds
Anwendung:
$ java -jar Print-20091030.jar Hello. Content: A: Build 20091030 If the writeList method doesn't catch the checked exceptions that can occur within it, the writeList method must specify that it can throw these exceptions. Let's modify the B: original writeList method to specify the exceptions it can throw instead of catching them. To remind you, here's the original version of the writeList method that won't compile.
Quellen
Apache ant homepage
Writing a simple ant file
Die Vernachlässigung von tollen Namespaces für meine Klassen sie mir verziehen.
Veröffentlicht in Technisch | Verschlagwortet mit ant, ant example, apache ant, build, build tool, Code, example, java | 1 Kommentar »
Mich hat es heute irgendwie gepackt und ich habe meine alten Jugendsünden wieder einmal herausgekramt. BASIC heißt das Zauberwort.
Früher auf dem 486er, den ich von meinem Onkel hatte (vielen Dank an dieser Stelle noch einmal, wer weiß ob mich der PC und das Programmieren ohne dich jemals so gefessel hätte), habe ich sehr viel mit QBasic herumgespielt, ohne ein Fünkchen Ahnung davon zu haben. Es war sehr spannend was man alles mit ein paar Zeilen Text machen konnte, es machte Spaß bestehende Programme zu analysieren, die Hilfe-Funktion zu durchforsten, wilde, durch alle Farben iterierende Schleifen zu bauen. Dass ich dabei den furchtbarsten Code meines Lebens produziert habe, war damals wohl egal.
Ich bin heute jedoch froh, dass ich diese Relikte noch aufgehoben habe, samt einer Kopie von QBasic.
Mit Hilfe von dosemu bzw. xdosemu kann man das Programm (qb.exe) nämlich noch wunderbar starten und seine alten Machwerke bestauenen. Vielleicht führe ich mein großes Spieleprojekt “Hunt” einmal zu Ende … im Rentenalter.
Freebasic habe ich auch probiert zu verwenden, es war auf die schnelle aber nicht auf AMD 64 zum laufen zu bringen, 32Bit X Libs gefehlt und den Code habe ich nur als BASIC Code gefunden …
Anbei ein paar Screenshots von qb.exe auf dosemu.
(Für irgendwelche Schmerzen, geistiger oder körperliche Art dir durch den Anblick des Codes entstehen könnten übernehme ich keinerlei Haftung.)
Veröffentlicht in Technisch | Verschlagwortet mit 486, 486er, BASIC, Coding, Computerspiele, dosemu, Games, Jugendsünden, Linux, Nostalgie, Programmieren, QBASIC, Retro, Spiele, Spieleentwicklung, xdosemu | Kommentar schreiben »
Ich will hier kurz ein Gotcha vorstellen, das bei der Verwendung von Group By unter MySQL auftreten kann und dann ein Gegenbeispiel in PostgreSQL bringen.
Nehmen wir folgende Tabelle an:
O_Id OrderDate OrderPrice Customer
1 2008/11/12 1000 Hansen
2 2008/10/23 1600 Nilsen
3 2008/09/02 700 Hansen
4 2008/09/03 300 Hansen
5 2008/08/30 2000 Jensen
6 2008/10/04 100 Nilsen
Dann wäre das folgende Query gültig und hilfreich um die Summe für einen Kunden zu bestimmen:
$ SELECT Customer,SUM(OrderPrice) FROM Orders GROUP BY Customer
Customer SUM(OrderPrice)
Hansen 2000
Nilsen 1700
Jensen 2000
Hierbei befinden sich alle angezeigten Felder in dem GROUP BY Ausdruck oder in einer Aggregatfunktion.
Unter MySQL ist jedoch auch folgendes möglich:
SELECT * FROM Orders GROUP BY Customer
Hierbei würde nach Kunde Gruppiert, sowie alle anderen Felder angezeigt werden. Allerdings ist hierbei *nicht definiert welche Werte die nicht gruppierten Felder haben!* Siehe dazu auch MYSQL: GROUP BY mit versteckten Feldern. Hier wird dies “Feature” genannt und muss explizit deaktiviert werden …
Unter PostgreSQL bekommt man jedoch standardmäßig folgende Fehlermeldung die einem vor so manchem Fehler bewahren kann:
$ SELECT * FROM Orders GROUP BY Customer;
ERROR: column "Orders.O_Id" must appear in the GROUP BY clause or be used in an aggregate function
Quellen:
Veröffentlicht in Technisch | Verschlagwortet mit datenbank, gotcha, Gotchas, GROUP BY, mysql, MySQL Gotcha, PostgreSQL, SQL | Kommentar schreiben »
Beim Aufräumen bin ich gerade auf ein Handout aus einem Vortrag bei uns in der Firma zum Thema Urheberrecht bei Webseiten gekommen. Wir haben sehr gut gelacht:
Die technische Realisierung der Gestaltung von Webseiten ist urheberrechtsfähig, wenn der Webdesigner die Internetseite durch gezielte Verwendung von Sprache so optimiert, dass sie bei der Eingabe von Alltagsbegriffen in eine Suchmaschine unter den ersten Suchergebnissen erscheint.
– OLG Rostock, Beschluß vom 27.06.2007 – 2 W 12/7 (Urheberrechtsschutz von Webseiten)
So viel zu unserer Judikative.
Veröffentlicht in Nicht technisch | Verschlagwortet mit Gesetze, Judikative, Regierung, Uhreberrecht Webseiten, Urheberrecht, Web, Webseiten | Kommentar schreiben »
Ich arbeite mich zur Zeit ein wenig in verschiedene Sicherheitsframeworks für Java ein und bin gerade dabei Spring Security genauer unter die Lupe zu nehmen.
Allerdings gab es bereits Probleme beim Deployen der Beispielanwendung aus dem Quick Start Guide.
Der Tomcat Application Manager gab nachdem Installieren nur ein sehr hilfreiches: FEHLER – Anwendung mit Kontext Pfad /tutorial konnte nicht gestartet werden von sich.
Das Systemlog führte einen dann schon eher auf die richtige Fährte:
[ERROR,[/tutorial]] Exception sending context initialized event to listener instance of class org.springframework.web.util.Log4jConfigListener java.security.AccessControlException: access denied (java.util.PropertyPermission tutorial.root read)
...
SEVERE: Error listenerStart
SEVERE: Context [/tutorial] startup failed due to previous errors
Interessanterweise landete die oberste Meldung nicht in den Tomcat Logs sondern nur in der /var/log/syslog. Die SEVERE Meldungen sind auch in den Tomcat Logs zu finden aber eben nicht annähernd so hilfreich.
Um nun nicht die ganze Beispielanwendung untersuchen und die einzelnen Regeln definieren zu müssen, reicht es für Testzwecke aus die Sicherheitsprüfung im Tomcat zu deaktivieren. Für den 5.5er Tomcat untern Debian, wird dies in der /etc/default/tomcat5.5 mit dem Eintrag TOMCAT5_SECURITY=no erreicht.
hth
Veröffentlicht in Technisch | Verschlagwortet mit java, security, spring, spring security, spring securtiy tutorial, spring tomcat, tomcat, tomcat security | Kommentar schreiben »
Ich habe mir endlich mal wieder eine neue SD Karte geholt und die Chance genutzt um meinen guten alten GP2X F100 MK1 auszupacken. Damals hatte ich mir gleich einen aus den ersten Fuhren ergattert und habe mich schon riesig gefreut Emulatoren zu zocken, Videos zu schauen und selber Anwendungen zu schreiben.
Nunja an Anwendungen ist dann nicht sooo viel dabei heraus gekommen, ich habe eine Version von Game of Life für den GP2X geschrieben, sowie eine Version von einem Rubik’s Cube in 3D in der Mache. Dieser ist allerdings noch nicht fertig. Mal sehen ob das überhaupt noch was wird.
Infos über den GP2X gibt es auf der deutschen Portalseite gp2x.de. Wichtige Anlaufpunkte sind hierbei das Forum, Wiki und das Dateiarchiv.
GP2X of Life
GP2X of Life in git
GP2X of Life im GP2X Archiv
Eine Version von Game of Life für den GP2X handheld. Mit der SDL auch unter Linux ausführbar.

Man sollte jedoch nicht verheimlichen dass das gerät mittlerweile schon einige Jahre auf dem Buckel hat und es demnächst die Pandora gibt. Mit WLAN und allem Schnickschnack.
Veröffentlicht in Technisch | Verschlagwortet mit Coding, Game of Life, Gamepark Holdings, GP2X, Homebrew, Pandora, Programmieren, Rubik's Cube, SDL | Kommentar schreiben »
Groovy hat mich schon wieder erwischt. Da wollte ich doch nur eine Methode aufrufen die wahlweise einen String oder ein Array von Strings erwartet, jedoch war das Ergebnis eher überraschend.
Man nehme:
public class CallString {
private String[] books = new String[64]
public void setBook(String book) {
System.out.println("set book string")
this.books[0] = book
}
public void setBook(String[] inBooks) {
System.out.println("set book array")
for (int i = 0; i < inBooks.length && books.length; ++i) {
this.books[i] = inBooks[i]
}
}
public String toString() {
return "["+ books.findAll {it != null}.join(", ") +"]"
}
}
Und rufe folgendes auf:
CallString o = new CallString();
o.setBook("The Book")
println o
$ groovy call.groovy
set book string
[, The Book]
Okay das ist noch wie erwartet. Allerdings ist der Mensch ja faul und verwendet gerne die abgekürzte schreibweise:
CallString o = new CallString(); o.book = "The Book" println o $ groovy call.groovy set book array [, T, h, e, , B, o, o, k]
Das ist nun wirklich nicht das was ich erwartet habe und hat mich auch ein wenig Zeit gekostet. Das selbe passiert übrigens auch wenn CallString in Java geschrieben ist.
Wie dem auch sei scheint es wie auch bereits beim vorherigen Groovy Map Gotcha mit der Magie hinter dem Methodenzugriff per “.” zu stecken und man sollte direkt die gewünschten Methoden aufrufen wenn man auf der sicheren Seite sein will – oder muss wissen was man tut.
Veröffentlicht in Technisch | Verschlagwortet mit Code, gotcha, groovy, Groovy Gotchas, Methodenprototyp, Methodenzugriff, Programmieren | Kommentare deaktiviert



