Domino within screen session and ulimits

January 22 2015 04:58:18 PM | Tags: Domino  Administration  Linux 

I run my development and testing servers mostly on Linux. To automatically start the Domino servers, I like to run them within a screen session. This allows me to detach and attach the console session very easily.
This is my startup command line - I use it somewhere for my startup scripts:

su - notes -c "cd /local/notesdata && screen -d -m -S DOMINO /opt/ibm/domino/bin/server"


To attach to the console I have to enter
screen -r DOMINO
(the DOMINO session name is case sensitive) and
CTRL+a,d
(hold CTRL and press 'a' and 'd' one after the other) to detach from a running screen session.

Works perfect so far. But after a while, I get lots of messages that remind me to change the ulimits for the Domino user:
21.01.2015 18:21:26 WARNING: The maximum number of file handles (ulimit -n) allowed for Domino is 4096. See IBM Lotus Tech Note 1221870 and set the allowable maximum to 60000.
21.01.2015 18:26:27 WARNING: The maximum number of file handles (ulimit -n) allowed for Domino is 4096. See IBM Lotus Tech Note 1221870 and set the allowable maximum to 60000.
21.01.2015 18:31:28 WARNING: The maximum number of file handles (ulimit -n) allowed for Domino is 4096. See IBM Lotus Tech Note 1221870 and set the allowable maximum to 60000.
21.01.2015 18:36:28 WARNING: The maximum number of file handles (ulimit -n) allowed for Domino is 4096. See IBM Lotus Tech Note 1221870 and set the allowable maximum to 60000.


There is a technote, that explains what is happening, but not the underlying processes in detail. After all, you will have to dig into the pam-mechanism...
Technote 1221870 : Message 'Maximum number of file handles allowed for Domino is 1024'

...or take this shortcut and just add (if missing) or complete the /etc/pam.d/screen file to enable pam_limits.so.

[root@iodev ~]# cat /etc/pam.d/screen
#%PAM-1.0
auth    include         system-auth
session required        pam_limits.so


And as mentioned in the technote, add limits for the Domino user (here it is 'notes'):
notes           hard    nofile          60000
notes           soft    nofile          60000


Finally, the result (success!!) is shown on the server's console:
21.01.2015 23:29:00   INFO: The maximum number of file handles (60000) allowed for Domino is sufficient. 


UPDATE: If you are running your servers by an automatic startup script, you have to enable pam_limits.so for another config file:

[root@iodev ~]# tail -n 1 /etc/pam.d/systemd-user
session required        pam_limits.so



Comments [0]

 

Copy code templates

November 15 2014 10:09:06 AM | Tags: Development  Lotus Designer  Eclipse 

I move around a lot. So I have to work with different installations of Lotus Designer. Finally I am completely fed up with recreating my Lotus Script code templates. But as Designer is based on Eclipse, you will find a lot of changable settings under the workspace folder. Have a look into
[NotesData]\workspace\.metadata\.plugins\org.eclipse.core.runtime\.settings\
where you see many files that change the behavior of the whole Eclipse framework.

For example, com.ibm.designer.domino.lscript.prefs contains the settings for my code templates. I like to add some error handling and OpenLog compatible comments. Due to escaping tabs, CR/LF, whitespaces and so on it is not nice to read. But copy to another workstation just works! As far as I can see, even for different client versions.

#Sun Sep 28 10:54:44 CEST 2014
lsee.codeTemplates.SUB=\tOn Error GoTo ErrorThrower\r\n\r\n\r\n\r\n\tExit Sub\r\nErrorThrower\:\r\n\tError Err, Error & " (" & Err & "), " & Chr(10) + " Module\: " &_\r\n\t\tCStr( GetThreadInfo(1) ) & ", Line\: " & CStr( Erl )
com.ibm.designer.domino.scripting.lscript.editor.textfont=fontFamily\=Courier New;fontSize\=10;normalText\=rgb(0,0,0) 0;identifiers\=rgb(0,0,0) 0;keywords\=rgb(0,0,200) 1;comments\=rgb(0,150,0) 1;multilineComments\=rgb(0,150,0) 1;constants\=rgb(100,0,200) 2;directives\=rgb(0,200,0) 3
lsee.codeTemplates.lastEditedCodeElement=SUB
eclipse.preferences.version=1
# and much more like above...

Here is the complete file: com.ibm.designer.domino.lscript.prefs
Comments [0]

 

Upstart/Ubuntu: Startscript für Domino Server

September 11 2013 12:14:25 PM | Tags: Administration  Linux  Lotus Domino  Server 

Meine IBM Domino Testsysteme installiere ich unter Ubuntu Server. Dafür habe ich ein Startscript, dass den Domino Server in einer screen session aufruft. Nun ist das alte SysVinit, bei dem die Prozesse in der Regel nacheinander in einer festen Reihenfolge gestartet werden, überholt. Während die meisten Distributionen auf systemd setzen, hat sich Canonical entschieden, upstart einzusetzen. Ein neues Script speziell für upstart muss also her.

Die Umsetzung des bestehenden Startscripts hat sich als komplizierter herausgestellt, als ich es vorhergesehen hatte. Grund dafür ist, dass die debugging-Möglichkeiten von upstart leider sehr beschränkt sind. Eine Option auf "ich tue etwas und sehe alles, was im System passiert" gibt es leider nicht. Selbst Kerneloptionen für init in /etc/default/grup helfen nur bedingt weiter:
GRUB_CMDLINE_LINUX_DEFAULT="INIT_VERBOSE=yes init=/sbin/init -v --debug"
Das ist insbesondere dann unangenehm, wenn ein Bug im Fehlerfall den ganzen Start-Stop-Vorgang einfach anhält, ohne zu dokumentieren, warum das passiert. Nach vielen Tests und Recherchen hat sich herausgestellt, dass upstart Schwierigkeiten hat, den Status geforkter Prozesse zu überwachen. Ich kann also nur empfehlen, bei upstart init Scripten nach Möglichkeit auf forks zu verzichten. Nachdem das dann klar war, war die Umsetzung dann keine große Schwierigkeit mehr.

Hier mein Startscript für den Domino Server - welches natürlich für die jeweilige Umgebung (Pfade, userids, etc) angepasst werden muss. Anders als das upstart Script von Stephan H. Wissel, wird hier nur eine Instanz gestartet. Es sollte aber einfach möglich sein, entsprechend seiner Vorgaben mehrere Partitionen/Instanzen zu starten. Mit setuid/setguid wird der Benutzer gesetzt. Wichtig hierbei ist, dass das keine Login-Shell ist. Also muss ich die locale setzen, die bei der Installation auf diesem eingestellt war (hier - shame on me - de_de.UTF-8). Ansonsten werden die Meldungen des Domino-Servers auf der Console nur als Zahlencodes ausgegeben. Im post-stop rufe ich noch nsd auf. Das ist nicht ungedingt notwendig, stellt aber sicher, dass nach dem Beenden vom Server definitiv nichts mehr übrig ist.

# Domino Server - upstart init script 
# Changelog
# 11.09.2013, jmw - Initial version.

description "IBM Domino Server"
author "jan.michael@wrangel.de"

# When to start the service
start on (local-filesystems
  and net-device-up IFACE!=lo
  and mounted MOUNTPOINT=/var/domino)

# Stop on shutdown the machine.
stop on runlevel [!2345]

setuid notes
setgid notes
chdir /var/domino/data

# pre-start Run before process, immediately after
# firing the 'start'-event.
#pre-start script
#
#end script

# script starts your job. Related to an ugly bug,
# I don't recommend to fork here, as it
# is very hard to debug.
# @see https://bugs.launchpad.net/upstart/+bug/406397
script
    echo "Executing the server binary..."
    export LANG="de_DE.UTF-8"
    screen -D -m -S domino /opt/ibm/domino/bin/server
end script

# post-start runs imediately, when script has been invoked.
# It does not wait for a complete startup or anything else.
post-start script
end script

# pre-stop runs, when the 'stop on' event has been fired.
# It does not run, when the job has been terminated.
# You might add 'stop the daemon' stuff here.
pre-stop script
    echo "Stopping the server..."
    export LANG="de_DE.UTF-8"
    /opt/ibm/domino/bin/server -q
end script

# post-stop is executed, whenever this services stops, regardless, if it has been
# quit, it failed or the 'stop' event has been fired.
# This is the right place for cleaning up tasks.
post-stop script
    echo "Server stopped. Cleaning up..."
    /opt/ibm/domino/bin/nsd -kill
    echo "done."
end script


Weitere Informationen

http://www.wissel.net/blog/d6plinks/SHWL-8YG9KB
https://bugs.launchpad.net/upstart/+bug/406397
http://upstart.ubuntu.com/cookbook/
http://en.wikipedia.org/wiki/Upstart
http://freedesktop.org/wiki/Software/systemd/
Comments [0]

 

VirtualBox VM ohne Konsole starten

September 3 2013 11:37:50 AM | Tags: Server 

Ich nutze zum Starten einfacher Server VMs auf meinem Laptop VirtualBox. Normalerweise wird dann die Konsole mitgestartet und in einem neuen Fenster geöffnet. Ich spreche die Server allerdings immer über ssh bzw. rdp an und brauche dieses Fenster nicht.
VirtualBox lässt sich sehr umfangreich per Commandline steuern. Zentrales Tools ist VBoxManage. Dieses liegt per default unter %ProgramFiles%\Oracle\VirtualBox.

Um zunächst einmal zu sehen, welche VMs erreichbar sind, kann man sie sich mit vboxmanage list vms auflisten lassen
C:\Program Files\Oracle\VirtualBox>vboxmanage list vms
"Bowles" {5b36eb7b-e777-484f-be79-7c1e2f97bad8}
"LAMP Stack" {269818ee-55f2-4029-9b5c-fe3761f5a006}
"Linux Server" {1603546f-67de-417f-aa4d-90ae06931551}
"" {81be086a-e8f0-4269-beae-cf1342cd317a}
"Windows 3.1" {724f0917-7540-48fa-ac6b-603e1f3d9ba8}
"Windows 2008 Server" {4e7cd142-f594-4744-85f0-9b7fc35a0118}
"FreeNAS" {56b12cdf-51f1-4cf8-80b6-13ba689ae79e}


Starten der VM

Mit list vms hat man alles, was benötigt wird, die VM anzusprechen: den Namen oder die Unid. Beide können verwendet werden:

Starten per Name:
C:\Program Files\Oracle\VirtualBox>vboxmanage startvm "Linux Server" --type headless
Waiting for VM "Linux Server" to power on...
VM "Linux Server" has been successfully started.


Starten per Unid:
C:\Program Files\Oracle\VirtualBox>vboxmanage startvm {1603546f-67de-417f-aa4d-90ae06931551} --type headless
Waiting for VM "{1603546f-67de-417f-aa4d-90ae06931551}" to power on...
VM "{1603546f-67de-417f-aa4d-90ae06931551}" has been successfully started.


Auflisten der laufdenden VMs

Den Erfolg der Aktion zeigt vboxmanage list runningvms
C:\Program Files\Oracle\VirtualBox>vboxmanage list runningvms
"Linux Server" {1603546f-67de-417f-aa4d-90ae06931551}


Alternativ und gut zu wissen: Die Gui des VirtualBox Managers zeigt den Status ebenfalls an:
Image:VirtualBox VM ohne Konsole starten

Herunterfahren der VM

Wie im wirklichen Leben kann auch eine VM auf zwei Wegen heruntergefahren werden:

1 Dem Betriebssystem sagen, dass es herunterfahren soll. Das kann natürlich innerhalb der VM geschehen. Aber auch per ACPI kann das von VirtualBox aus veranlasst werden:
C:\Program Files\Oracle\VirtualBox>vboxmanage controlvm "Linux Server" acpipowerbutton

2 Stromlos machen. Manchmal reicht es aber auch/ist es notwendig, die Maschine hart auszuschalten. Das entspricht dem Ziehen des Steckers und macht die VM auf einen Schlag 'stromlos'.
C:\Program Files\Oracle\VirtualBox>vboxmanage controlvm "Linux Server" poweroff
0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%


Mit VBoxManage lassen sich sehr viele Dinge erledigten. Die gesamte Konfiguration - mehr als die Gui ermöglicht - kann dort geändert werden. Das ist z.B. interessant, wenn von bridged auf host-only Netzwerk geändert werden soll, weil man den Standort gewechselt hat.
Mehr dazu in der Dokumentation bei Oracle.
Comments [0]

 

Ubuntu: WLan mit statischer IP betreiben

September 2 2013 10:23:11 PM | Tags: Linux  Wlan  Netzwerk 

Normalerweise wird unter Ubuntu das Wlan mit dem NetworkManager betrieben. Dieser läuft unter X - und ist somit erst dann aktiv, wenn ein User angemeldet ist, der entsprechend das Netzwerk konfiguriert hat (und das auch darf).
Nun will ich aber, dass das Netz sofort nach dem Starten des Kernels verfügbar ist und mit einer statischen IP versehen. Früher war das Gelegenheit, einen Abend am Rechner zu verbringen, Logs zu analysieren, mehrfach an den Rand des Wahnsinns zu gelangen - heute ist das ganz einfach:
Quasi die ganze Konfiguration, die geändert werden muss, liegt in /etc/network/interfaces. Dort möchte die IP 192.168.1.244 in einem Klasse C Netz fest vergeben. Dann muss (als root) eingetragen werden:
auto wlan0
iface wlan0 inet static
   address 192.168.1.244
   netmask 255.255.255.0
   network 192.168.1.0
   broadcast 192.168.1.255
   gateway 192.168.1.1
   dns-nameservers 192.168.1.1
   wpa-ssid ssid
   wpa-psk 73237e345618611c50e051c8cd7ee37dca07d829c16023f55ac0ce00c159c241

Den preshared key (aka 'Passwort' oder 'passphrase') für meine WPA(2) Konfiguration ermittel ich mit dem wpa Tool 'wpa_passphrase'.
Ich habe das Passwort in einer Datei (alternativ wäre, es als zweiten Parameter mitzugeben).
cat /tmp/my-wlan-file.txt | wpa_passphrase meine-ssid
Da kommt dann eine Konfiguration heraus, von der aber nur die in HEX umgewandelte Passphrase benötigt wird:
# reading passphrase from stdin
network={
   ssid="ssid"
   #psk="plaintextpassphrase"
   psk=73237e345618611c50e051c8cd7ee37dca07d829c16023f55ac0ce00c159c241
}


Jetzt kann es noch sein, dass das Interface nicht 'wlan0' heißt.
ifconfig -a zeigt alle, auch die nicht konfigurierten Interfaces an und gibt Auskunft, was vom Kernel gefunden wurde. Bei mir stand dort z.B., dass das Wlan Interface 'eth1' bekommen hat. Das finde ich aber unschön und habe das in /etc/udev/rules.d/70-persistent-net.rules geändert.
# PCI device 0x8086:0x4224 (ipw2200)
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="00:13:ce:fd:44:89", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME="wlan0"


Das ist natürlich für jeden Rechner anders ;-) - Die Stelle zum Ändern ist der NAME.
Comments [0]

 

Rechschreibprüfung in Lotus Notes Basic Configuration

July 17 2013 08:59:06 PM | Tags: basic configuration  client 

In einem Kundenprojekt bin ich gefragt worden, wie sich eigentlich mehrere Sprachen für die Rechtschreibprüfung einstellen lassen. Das Besondere hieran (meine Kunden verwenden meistens die Standard Configuration): Es soll in der Basic Configuration funktionieren. Also schnell die Grundlagen zusammengetragen.

Welche Sprachen kennt der Client und wie füge ich welche hinzu?

Prinzipiell ist das recht einfach: "File" : "Preferences" : "User preferences" und dort dann "International" : "Spell Check". Dort sind dann die Dictionaries aufgeführt, die der installierte Client mitbringt. Wenn nun eine Sprache fehlt - ich verwende hier den Englischen Client und will Deutsch mit Schlagobers nachinstallieren - dann geht das per "Install Dictionary...".

Image:Rechschreibprüfung in Lotus Notes Basic Configuration

Das öffnet eine Liste mit den theoretisch installierbaren Sprachen.

Image:Rechschreibprüfung in Lotus Notes Basic Configuration

Nun allerdings wird es hakelig, weil dazu dic-Dateien notwendig sind, die man sich zunächst einmal besorgen muss. Es gibt per Passport Advantage MUI Installationen, in denen mehrere Sprachen in Gruppen zusammengefasst sind. Wenn das nicht schon vorhanden ist, kann das Herunterladen eine Weile dauern. Einfacher ist es da, wenn der Client in der Zielsprache bereits vorhanden ist. Da kann man sich einfach die benötigten dic-Dateien aus dem Installationsarchiv des Clients herausholen, wie ich es hier gemacht habe.

Image:Rechschreibprüfung in Lotus Notes Basic Configuration

Nun wird auch Deutsch mit Schlagobers in der Liste angezeigt. Allerdings ohne Häkchen - dieses bedeutet, dass die Sprache für jeden Text zur Pr üfung der Rechtschreibung verwendet wird, der nicht explizit als in einer anderen Sprache geschrieben markiert wurde. Das muss von Hand gemacht werden, es gibt keine Heuristik des Notes Clients oder irgendeine Hilfestellung.


Image:Rechschreibprüfung in Lotus Notes Basic Configuration

Normalerweise ist Text "untagged". Dann wird die als Default markierte Sprache zur Prüfung verwendet.

Image:Rechschreibprüfung in Lotus Notes Basic Configuration

Es gibt nun die Möglichkeit, markiertem Text eine andere Sprache zuzuweisen. Diese bleibt auch bei einem Zeilenumbruch erhalten.

Image:Rechschreibprüfung in Lotus Notes Basic Configuration

Allerdings ist das etwas hakelig und nicht immer so. Es kann sein, dass ans Zeilenende geklickt, dieses und aller weiterer Text wieder "Untagged" eingestellt ist. Wenn man den Cursor jedoch mit den Pfeiltasten dorthin bewegt, die Sprache des Absatzes bleibt. Ganz unangenehm wird es, wenn mehrere Sprachen in einem Absatz stehen und das rückgängig gemacht werden soll. Dann kann es passieren, dass beim durchwandern mit dem Cursor die Sprache hin-und-her springt und zwischen den Buchstaben eine Spracheinstellung stehenbleibt. Wenn nun alles markiert wird, lässt sich gar nichts mehr einstellen und die Spracheinstellung in den Eigenschaften des Textes sind ausgegraut.

Image:Rechschreibprüfung in Lotus Notes Basic Configuration

Also lieber die Finger davon und es einfach belassen.

Rechtschreibung prüfen


Wenn es klappt und die Rechtschreibprüfung mögliche Fehler findet, dann werden unbekannte Worte angemahnt.

Image:Rechschreibprüfung in Lotus Notes Basic Configuration

Dort besteht dann die Möglichkeit, die Sprache für die weitere Prüfung zu ändern.

Image:Rechschreibprüfung in Lotus Notes Basic Configuration

Wenn dann noch Text in einer Sprache markiert war, für die kein Dictionary installiert wurde, dann wird das am Ende der Rechtschreibprüfung angemerkt.

Image:Rechschreibprüfung in Lotus Notes Basic Configuration
Comments [0]

 

Changing a Domino server’s IP address

November 9 2012 06:26:53 PM | Tags: Administration  Lotus Domino 

Just remember, if you change an IP address of a domino server - it is cached in the server document. Every successful connect will update some fields. If you change the IP address and experience "The server is not responding" messages in the server's log, you might want to check and delete them.

 
$SavedAddresses
$SavedDate
$SavedPorts
$SavedServers
$SavedTriedDate


And yes, you find this information in the administration help database... RTFM ;-)

IBM Lotus Domino Administration Help - Changing a server's IP address
Comments [0]

 

RFC822 address validation

October 10 2012 04:06:34 PM | Tags: fun  Perl  Email  RegExp 

I just stumbled upon a regular expression to validate rfc822 email addresses:

(?:(?:\r\n)?[ \t])*(?:(?:(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t] 
)+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:
\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(
?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[
\t]))*"(?:(?:\r\n)?[ \t])*))*@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\0
31]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\
](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+
(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:
(?:\r\n)?[ \t])*))*|(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z
|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)
?[ \t])*)*\<(?:(?:\r\n)?[ \t])*(?:@(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\
r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[
\t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)
?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t]
)*))*(?:,@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[
\t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*
)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t]
)+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*)
*:(?:(?:\r\n)?[ \t])*)?(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+
|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r
\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:
\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t
]))*"(?:(?:\r\n)?[ \t])*))*@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031
]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](
?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?
:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?
:\r\n)?[ \t])*))*\>(?:(?:\r\n)?[ \t])*)|(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?
:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?
[ \t]))*"(?:(?:\r\n)?[ \t])*)*:(?:(?:\r\n)?[ \t])*(?:(?:(?:[^()<>@,;:\\".\[\]
\000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|
\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>
@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"
(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*))*@(?:(?:\r\n)?[ \t]
)*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\
".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?
:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[
\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*|(?:[^()<>@,;:\\".\[\] \000-
\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(
?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)*\<(?:(?:\r\n)?[ \t])*(?:@(?:[^()<>@,;
:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([
^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\"
.\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\
]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*(?:,@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\
[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\
r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\]
\000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]
|\\.)*\](?:(?:\r\n)?[ \t])*))*)*:(?:(?:\r\n)?[ \t])*)?(?:[^()<>@,;:\\".\[\] \0
00-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\
.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,
;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?
:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*))*@(?:(?:\r\n)?[ \t])*
(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".
\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[
^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]
]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*\>(?:(?:\r\n)?[ \t])*)(?:,\s*(
?:(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\
".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)(?:\.(?:(
?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[
\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t
])*))*@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t
])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?
:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|
\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*|(?:
[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\
]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)*\<(?:(?:\r\n)
?[ \t])*(?:@(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["
()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)
?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>
@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*(?:,@(?:(?:\r\n)?[
\t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,
;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t]
)*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\
".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*)*:(?:(?:\r\n)?[ \t])*)?
(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".
\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)(?:\.(?:(?:
\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\[
"()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])
*))*@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])
+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\
.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z
|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*\>(?:(
?:\r\n)?[ \t])*))*)?;\s*)


Lol! Thanks to Paul Warren.
Comments [0]

 

Open a tempfile with the registered application

October 9 2012 07:43:13 PM | Tags: Snippets  Java 

I use this often to create a temp file and open it with the according application. In this case, I created a pdf document as a print preview. To avoid 'save'-dialogs or forcing the user to walk through the filesystem, I directly open the document in Acrobat Reader.

To achive this I create a temp file using 'File'. This will result in a file named randomly, like 'prefix-2456730075766423086.pdf', created in %temp%. After my program terminated, the file will be deleted. This is a great functionality as it saves lot of time during development ;-)

But the real magic is done by 'Desktop'. It offers some actions like 'open', 'edit'; 'print', ... if available. To check this, first find out, if this platform supports 'Desktop' and hereafter, if 'open' action is available.

In this snippet, 'desktop.open(pdf);' will open Acrobat Reader, as this is the registered application for '.pdf'-files.

 
File pdf = File.createTempFile("prefix-", ".pdf");
pdf.deleteOnExit();

// create pdf file here...

if( Desktop.isDesktopSupported() ) {
    Desktop desktop = Desktop.getDesktop();
    if( desktop.isSupported( Desktop.Action.OPEN) ) {
            desktop.open(pdf);
    }
}

Comments [0]

 

jQuery Fundamentals

April 5 2011 03:12:00 PM | Tags: Development  JavaScript 

While exploring the benefits of jQuery, I stumbled upon the online book "jQuery Fundamentals" by Rebecca Murphey. I is a really nice introduction to this great helper for web development. It starts with JavaScript Basics, as it is good to know the background of jQuery development. And after it walks through the jQuery framework, is good to read and explains with lots of examples. Excellent work!


Comments [0]