tag:blogger.com,1999:blog-1448054605413533592024-03-13T19:55:38.960+01:00Seb's Tec-BitesSeb's information about technologies, esp. in the environment of software design and development.Sebhttp://www.blogger.com/profile/06553111406739261461noreply@blogger.comBlogger38125tag:blogger.com,1999:blog-144805460541353359.post-9236617873201672702010-10-25T05:53:00.002+02:002010-10-25T07:10:14.089+02:00Ubuntu Karmic Koala and VLCIt's been some time since I last posted here .. nothing happened to me that's interesting for a broader audience, it seems ... Well, I found something.<br />
<br />
On my notebook, I am forced to use nothing more current than ubuntu Karmic Koala (9.04), because KMS+old intel graphics doesn't really work - see more below. Luckily, many of the packages are still being updated (including firefox), but one is missing for me ... a current version of vlc aka video lan client. So, I had to compile it. Only took about 30mins of CPU time ;)<br />
<br />
There are no packages on launchpad for vlc/karmic, so I offer them for download, if anyone is interested. This is not an apt repository, but just a folder with .deb files. I compiled them from the lucid sources from <a href="https://launchpad.net/~ferramroberto/+archive/vlc">Ferramosca Roberto's LffL VLC</a><br />
<br />
To install, download the files from <a href="http://www.tecbites.de/ubuntu/karmic/vlc">http://www.tecbites.de/ubuntu/karmic/vlc</a>, and use the following to install:<br />
<pre>sudo dpkg -i libmtp8_1.0.2-1ubuntu1_i386.deb
sudo dpkg -i vlc_1.1.4.1-1~lffl~lucid~ppa1_i386.deb \
vlc-data_1.1.4.1-1~lffl~lucid~ppa1_all.deb \
libvlc5_1.1.4.1-1~lffl~lucid~ppa1_i386.deb \
libvlccore4_1.1.4.1-1~lffl~lucid~ppa1_i386.deb \
vlc-nox_1.1.4.1-1~lffl~lucid~ppa1_i386.deb
</pre>These are the packages you need, at least - some of the plugins may be handy, the -dev packages you probably won't need.<br />
Oh, they are called lucid because I compiled them from the ppa launchpad lucid dsc sources ... I should fix this, and the maintainer name also ;)<br />
<br />
<br />
Just for information - my experiences with ubuntu, old intel graphics (82852/855GM), kernel based mode setting (KMS) and XVideo acceleration were quite free of successes.<br />
Depending on the distribution and the current update state, <br />
* KMS+XVideo is not supported (and not planned to be supported, I believe)<br />
* nomodeset+XVideo either doesn't work, or crashes the X11 server<br />
My experiences with opensuse were similar, so, it appears to be something the old hardware has to live with (IBM Thinkpad X40).Sebhttp://www.blogger.com/profile/06553111406739261461noreply@blogger.com0tag:blogger.com,1999:blog-144805460541353359.post-61256191757403084242009-12-05T13:39:00.002+01:002009-12-06T09:41:11.890+01:00Qt 4.6.0 on AVR32 and it’s bugs: Error: symbol `.L987' is already defined<p>Qt 4.6.0 is out – there is only one source archive now, “-everywhere-“, which includes the linux embedded version also. I tried to build it for the avr32 embedded system; but, a nice compiler error prohibited it.</p><h4>Error: Symbol `.L987' is already defined</h4><h2></h2><div><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet">compiling painting/qbrush.cpp
{standard input}: Assembler messages:
{standard input}:5426: Error: symbol `.L987' is already defined
{standard input}:5544: Error: symbol `.L1012' is already defined
{standard input}:6236: Error: symbol `.L1129' is already defined
{standard input}:6353: Error: symbol `.L1154' is already defined
make: *** [.obj/release-shared-emb-avr32/qbrush.o] Fehler 1</pre></div><h4>Googling it</h4><p>This error is usually based on using “inline” and “asm” statements in combination – see <a title="http://archives.devshed.com/forums/development-94/new-assembler-message-symbol-is-already-defined-1269938.html" href="http://archives.devshed.com/forums/development-94/new-assembler-message-symbol-is-already-defined-1269938.html">http://archives.devshed.com/forums/development-94/new-assembler-message-symbol-is-already-defined-1269938.html</a>, e.g. It looks like an internal compiler error, but is usually a coding error.</p><blockquote> <p>“This is not a gcc bug, you cannot declare a label in an inline-asm that is going to be exposed.”</p><p>“Is there a reference of some sort? I was unable to find one with google.” <br />
”No, just a general rule as inline-asms will be copied when inlined or cloned. What is happening here is clon(n)ing is happening so we generate two copies of that function.”</p></blockquote><p>So, there is some inline method that contains assembler code – the code is duplicated b/c of the inline interpretation – and thus, the assembler labels are duplicated.</p><h4>Different Compiler?</h4><p>I do not think that Nokia explicitly inserted the inline+asm-combination. It is probably some gcc optimization. Unfortunately, it is not possibly to use a different compiler than the one provided by atmel in “buildroot-avr32-2.3.0” (<a title="http://www.atmel.com/dyn/products/tools_card.asp?tool_id=4401" href="http://www.atmel.com/dyn/products/tools_card.asp?tool_id=4401">http://www.atmel.com/dyn/products/tools_card.asp?tool_id=4401</a>)</p><p> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"><p>Using built-in specs.
Target: avr32-linux-uclibc
Configured with: /avr32/buildroot-avr32-v2.3.0/toolchain_build_avr32/gcc-4.2.2/configure --prefix=/avr32/buildroot-avr32-v2.3.0/build_avr32/staging_dir --build=x86_64-pc-linux-gnu --host=x86_64-pc-linux-gnu --target=avr32-linux-uclibc --enable-languages=c,c++ --enable-__cxa_atexit --enable-target-optspace --with-gnu-ld --with-gmp=/avr32/buildroot-avr32-v2.3.0/toolchain_build_avr32/gmp --with-mpfr=/avr32/buildroot-avr32-v2.3.0/toolchain_build_avr32/mpfr --enable-shared --disable-nls --enable-threads --disable-multilib --enable-sjlj-exceptions --disable-libmudflap --disable-libssp --with-build-time-tools=/avr32/buildroot-avr32-v2.3.0/build_avr32/staging_dir//bin
Thread model: posix
gcc version 4.2.2-atmel.1.1.3.buildroot.1</p></pre></p><h4>Change Optimisation Level</h4><p>So, we have to find a way to avoid the above error. If it is an optimization problem, let’s just use some other one.</p><p>goto src/gui, patch Makefile, add –O to the end of CXXFLAGS, call make .obj/release-shared-emb-avr32/qbrush.o, and it runs through – now, you can remove the –O again, and compile the rest of it.</p><p>Alternatively, remove the @ in the beginning of CXX = …, call make, get the avr32-linux-uclibc-g++ statement, and add –O there.</p><p>Using –O3 does not work – then, the inlining is done even more often, resulting in triple definitions (or rather duplicate errors about duplicate defintions).</p><p>No idea where the error stems from, but at least, Qt 4.6.0 now compiles.</p><h4>package/qtopia4/qtopia4.mk</h4><p>Btw … to get that far, a few more changes are necessary. Those are, in short, in package/qtopia/qtopia4.mk:</p><div> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet">QTOPIA4_VERSION:=4.6.0
QTOPIA4_CAT:=zcat
QTOPIA4_SOURCE:=qt-everywhere-opensource-src-$(QTOPIA4_VERSION).tar.gz
QTOPIA4_TARGET_DIR:=$(BUILD_DIR)/qt-everywhere-opensource-src-$(QTOPIA4_VERSION)</pre></div><div>and you have to remove all the mouse driver statements – I have no idea how those are configured, now … most of them compile automatically, I may still be missing the tslib driver</div><div id="codeSnippetWrapper"> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet">### Mouse drivers
# remove all of them for Qt460
ifeq ($(BR2_PACKAGE_QTOPIA4_MOUSE_PC),y)
[...]
QTOPIA4_CONFIGURE += -no-mouse-qvfb
endif
</pre><br />
</div><h4>Fixing 4.5.x Colour Depths</h4><div>The previous version(s), 4.5.x, had a bug concerning a code optimisation that relied on non-aligned access – OK for i386 and followers, not OK for many other systems. Some were explicitly excluded, avr32 was not. The bug triggered when converting bitmaps between 24 and 16 bit colour depth, e.g., when connecting via vnc, or when using certain display depths directly.</div><div>See <a href="http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=79740">http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=79740</a> about fixing qt_blend_argb24_on_rgb16() in qblendfunctions.cpp.</div><div>Seems that fix is in 4.6.0, at least.</div><h4>PS: QtScript</h4><p>I get a compile error in QtScript – some problem with pthread_getattr_np:</p><div id="codeSnippetWrapper"> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet">compiling ../3rdparty/javascriptcore/JavaScriptCore/runtime/Collector.cpp
../3rdparty/javascriptcore/JavaScriptCore/runtime/Collector.cpp: In function 'void* QTJSC::currentThreadStackBase()':
../3rdparty/javascriptcore/JavaScriptCore/runtime/Collector.cpp:682: error: 'pthread_getattr_np' was not declared in this scope
</pre><br />
</div><p>Interestingly, the code does take care of uclibc 0.9.xx:</p><div id="codeSnippetWrapper"> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"><span style="color: #cc6633">#if</span> defined(__UCLIBC__)
<span style="color: #008000">// versions of uClibc 0.9.28 and below do not have</span>
<span style="color: #008000">// pthread_getattr_np or pthread_attr_getstack.</span>
<span style="color: #cc6633">#if</span> __UCLIBC_MAJOR__ == 0 && \
(__UCLIBC_MINOR__ < 9 || \
(__UCLIBC_MINOR__ == 9 && __UCLIBC_SUBLEVEL__ <= 30))
<span style="color: #cc6633">#define</span> UCLIBC_USE_PROC_SELF_MAPS 1
<span style="color: #cc6633">#include</span> <stdio_ext.h>
<span style="color: #0000ff">extern</span> <span style="color: #0000ff">int</span> *__libc_stack_end;
<span style="color: #cc6633">#endif</span>
<span style="color: #cc6633">#endif</span>
</pre><br />
</div><p>Oops, there are two different Collector.cpp: <br />
3rdparty/webkit/JavaScriptCore/runtime/Collector.cpp <br />
3rdparty/javascriptcore/JavaScriptCore/runtime/Collector.cpp</p><p>One does define UCLIBC_USE_PROC_SELF_MAPS etc. as a workaround for uclibc 0.9.30, the other doesn’t – another bugreport to Nokia.</p><p>Just add -no-script to the configure options, for the moment.</p><p>Just a short note - I published both problems as Qt bug reports: <a href="http://bugreports.qt.nokia.com/browse/QTBUG-6550">QTBUG-6550</a> and <a href="http://bugreports.qt.nokia.com/browse/QTBUG-6551">QTBUG-6551</a> <br />
<p>Have fun with it … <br />
Sebastian</p>Sebhttp://www.blogger.com/profile/06553111406739261461noreply@blogger.com10tag:blogger.com,1999:blog-144805460541353359.post-72292905405364649242009-09-18T22:13:00.003+02:002009-09-22T09:18:33.101+02:00Single to Dual/Multi Core with Windows XP (ACPI HAL)<h3></h3><h4>Introduction</h4>Sometimes, people have the problem that their Windows XP is running as a “single core” system, only, although there are two or more cores installed. This can usually be seen in the task manager, where performance shows only a single graph, although “one diagram per CPU” is selected.<br />
I talk about cores here, the same applies to multiple processors. Those are usually used on servers, though, where few people would start “fixing” the HAL.<br />
<h4></h4><h4>Hardware Abstraction Layer – HAL</h4>The reason is usually, that the normal ACPI HAL (Hardware Abstraction Layer) has been installed which does not support more than one core. In theory, XP recognises when a new CPU is installed, re-checks, and installs the correct hal. This does not always work, though. <br />
The usual HALs are<br />
<ul><li>Standard PC </li>
<li>ACPI PC </li>
<li>ACPI Uni-Processor (UP) </li>
<li>ACPI Multi-Processor (MP) </li>
<li>MPS Multi-Processor (APIC) </li>
</ul>(<a href="http://support.microsoft.com/?scid=kb%3Ben-us%3B309283&x=10&y=9">http://support.microsoft.com/?scid=kb%3Ben-us%3B309283&x=10&y=9</a>)<br />
Especially in the context of virtual machines running under SUN VirtualBox, this does not work. When a windows XP system is installed with only one core active, and more core(s) is/are added later on, the CPU “id” does not change … no redetection is done, the other cores are not recognised. Another reason may be that the “ACPI PC” is not the same as “ACPI UP”, and only ACPI UP is able to support, and thus detect, more than one CPU. In the case of VirtualBox, the situation may also be caused on the IO-APIC not being enabled on install. According to SUN, XP Uniprocessor with IO-APIC is slower than without.<br />
Officially, there is no way to upgrade the HAL. You can downgrade it, though, which is not a good idea … there is no way back.<br />
<h4>Using devcon.exe: Forced HAL Upgrade</h4>I found a very interesting post about the “devcon.exe”, a tool provided by MS as “the command line version of the device manager”, and its application to the HAL switch problem.<br />
<ul><li>The Post: <br />
<a href="http://www.nforcershq.com/forum/updating-the-hal-for-multiprocessor-support-t70331.html">http://www.nforcershq.com/forum/updating-the-hal-for-multiprocessor-support-t70331.html</a> </li>
<li>Download devcon.exe: <br />
<a href="http://support.microsoft.com/?scid=kb%3Ben-us%3B311272&x=13&y=11" title="http://support.microsoft.com/?scid=kb%3Ben-us%3B311272&x=13&y=11">http://support.microsoft.com/?scid=kb%3Ben-us%3B311272&x=13&y=11</a> </li>
<li>The post describing the forced hal upgrade: <br />
<a href="http://www.nforcershq.com/forum/updating-the-hal-for-multiprocessor-support-t70331.html" title="http://www.nforcershq.com/forum/updating-the-hal-for-multiprocessor-support-t70331.html">http://www.nforcershq.com/forum/updating-the-hal-for-multiprocessor-support-t70331.html</a> </li>
</ul>The important stuff:<br />
Just execute the following commands in a cmd.exe shell …<br />
<div id="codeSnippetWrapper"><pre id="codeSnippet" style="background-color: #f4f4f4; border-style: none; color: black; direction: ltr; font-family: 'Courier New',courier,monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding: 0px; text-align: left; width: 100%;">devcon sethwid @ROOT\ACPI_HAL\0000 := +acpiapic_mp !acpiapic_up
devcon update c:\windows\inf\hal.inf acpiapic_mp</pre><br />
</div>Of course, this may completely break your system. Make backups, find out beforehand how to restore, etc. Using a virtual box system, this is easy, just make a snapshot and restore if the upgrade does not work.<br />
After running devcon, you reboot the system; after the reboot, XP re-detects all hardware, and the requests another reboot. This may change some of the hardware names, especially the LAN connection may get the number 2.<br />
<h4></h4><h4>Hidden Devices</h4>You can use the show-hidden trick of the device manager to display the old devices and remove them: <a href="http://support.microsoft.com/?scid=kb%3Ben-us%3B315539&x=14&y=11" title="http://support.microsoft.com/?scid=kb%3Ben-us%3B315539&x=14&y=11">http://support.microsoft.com/?scid=kb%3Ben-us%3B315539&x=14&y=11</a><br />
<div id="codeSnippetWrapper"><pre id="codeSnippet" style="background-color: #f4f4f4; border-style: none; color: black; direction: ltr; font-family: 'Courier New',courier,monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding: 0px; text-align: left; width: 100%;">set devmgr_show_nonpresent_devices=1
start devmgmt.msc</pre><br />
</div><h4>Switching the HAL</h4>Once you get a ACPI MP hal, you can switch it to whatever you like using the device manager. Just select “new driver” for the “Computer” device.<br />
<h3>Doing it manually</h3>Before I found the post by “hedrums” above, I tried to do it manually. Interestingly, none of the files is locked by windows. They are loaded so early and completely in the boot process that they are no longer “needed” (used) in a running system, and can just be replaced.Yet, I never managed to copy and rename the files correctly. <br />
Afterwards, by comparing the file sizes between the used versions (in system32) and the restore/backup versions (in ServicePackFiles\i386), I recognised the following:<br />
• ntoskrnl.exe == ntkrnlmp.exe (2,04MB) <br />
• ntkrnlpa.exe == ntkrpamp.exe (1,93MB) <br />
• hal.dll == halmacpi.dll (131kB)<br />
So, by copying the three files ntkrnlmp.exe, ntkrnlmp.exe and halmacpi.dll to system32 and renaming them to ntoskrnl.exe, ntkrnlpa.exe and hal.dll, respectively, you may be running an ACPI MP hal. I have not tried this, though.<br />
Alternatively, using the correct ACPI UP files (whichever they are), you may get a UP system that, in turn, is automatically able to detect the multicore and again, install the correct drivers …<br />
<a href="http://lh6.ggpht.com/_JdRjQOBe9RE/SrPq91SzzSI/AAAAAAAABaQ/MUnm6DBkuY0/s1600-h/ACPI%5B4%5D.png"><img alt="ACPI" border="0" height="367" src="http://lh6.ggpht.com/_JdRjQOBe9RE/SrPq-kMUsLI/AAAAAAAABaU/8G9sKPdfppE/ACPI_thumb%5B2%5D.png?imgmax=800" style="border: 0px none; display: inline;" title="ACPI" width="475" /></a><br />
<h4>Hardware.Info<br />
</h4>I now found a tool that does the same stuff, a bit more comfortable: <br />
<a href="http://www.hardware.info/en-US/news/ym2cmZqYwp2a/Problems_updating_to_a_dualcore_CPU_Not_anymore/">http://www.hardware.info/en-US/news/ym2cmZqYwp2a/Problems_updating_to_a_dualcore_CPU_Not_anymore/</a>Sebhttp://www.blogger.com/profile/06553111406739261461noreply@blogger.com3tag:blogger.com,1999:blog-144805460541353359.post-73927712307548681902009-09-12T11:22:00.003+02:002009-09-13T10:40:57.225+02:00Ubuntu Display Manager<strike></strike> <br />
Just some notes about the display manager(s) on Ubuntu I found out over time, and about their startup settings.<br />
The display manager – that’s usually gdm, the gnome d.m.; alternatively kdm on kubuntu/kde, or even the good old xdm when using a lightweight desktop. In any case, it’s usually started to show a user login screen ;)<br />
<h4>Text mode</h4>It is often practical to boot into text only mode – at least, when you know a bit about linux. I’m not talking about removing gdm forever (<tt>apt-get remove gdm</tt> or <tt>update-rc.d -f gdm remove</tt> do this), but to use text mode in certain situations – including when you know your Xorg or gdm setup to be broken. Or, when you really want to save battery power ;)<br />
The gdm startup allows this by putting <tt>text</tt> into the kernel command line. If this parameter is found, <tt>/etc/init.d/gdm</tt> just exits again. This can be achieved by:<br />
<ul><li>stop the bootup in the grub menu, then <br />
<br />
<ul><li>press “e” to edit the wanted entry </li>
<li>use the cursor keys to select the “kernel” line </li>
<li>press “e” again to edit the line </li>
<li>go to the end of the line and add “text” </li>
<li>press return to leave the line editing </li>
<li>press “b” to boot the edited entry </li>
</ul></li>
<li>create a grub entry for text mode <br />
<br />
<ul><li><tt>sudo gedit /boot/grub/menu.lst </tt></li>
<li>copy the first real boot entry (that starts with “title”) into another one below </li>
<li>change the title – append “text mode” or such </li>
<li>add “text” to the end of the “kernel” line </li>
<li>next time you boot the system, you can select the text mode and have tun. </li>
</ul></li>
</ul>This also disallows to start the gdm via the init script later on, because the entry is part of the kernel command line that cannot be changed. Yet, starting <tt>gdm</tt> directly achieves the same result.<br />
By the way: I have not hardly anything about this on the web. Of course, you just need to look into /etc/init.d/gdm … the only post I found referring to this is <a href="https://bugs.launchpad.net/ubuntu/+source/gdm/+bug/294980">https://bugs.launchpad.net/ubuntu/+source/gdm/+bug/294980</a><br />
<h4>gdm, kdm and xdm</h4>Ever wondered how the various display managers that can be installed on (k)ubuntu stay out of each others hair?<br />
<ul><li>each of them may be added to the runlevels </li>
<li>when starting, they each check whether they are the “preferred display manager” via /etc/defaults </li>
<li>if no, they exit; if yes, the one that should starts. </li>
</ul>This way, it should not be possible to start more than one display manager – which you usually don’t want to. Opensuse, on the other hand, uses just one rc-script which decides which dm to start.<br />
<h4>sysv-rc-conf<br />
</h4>As a side note – I never know how to edit the /etc/rc.d?/scripts. This changed over time, mainly because of the linux standard base (LSB), I believe. The current command-line tool is <i>update-rc.d</i> which is not really nice to use.<br />
But, the package <b>sysv-rc-conf</b> contains a textmode ui tool of the same name which seems to be usable, at least.<br />
<br />
There is also chkconfig and insserv as I know from opensuse; yet, their packages refuse to install on Jaunty due to some sysv-init package conflicts. Probably because ubuntu migrated from sysvutils to sysvinit-utils. Or rather to <i>upstart</i>, where sysvinit-utils only contains some utilities.Sebhttp://www.blogger.com/profile/06553111406739261461noreply@blogger.com0tag:blogger.com,1999:blog-144805460541353359.post-65612504360746218132009-09-12T08:16:00.003+02:002009-09-14T15:12:06.538+02:00Webservices with Axis2/Java - the simple POJO way<p></p> <p>There are many ways to create web services in Java; the most common implementation, nowadays, is using <a class="external text" title="http://ws.apache.org/axis2" href="http://ws.apache.org/axis2" rel="nofollow">Apache Axis2/Java</a> and a servlet container such as <a class="external text" title="http://tomcat.apache.org" href="http://tomcat.apache.org/" rel="nofollow">Apache Tomcat</a> or <a class="external text" title="http://www.eclipse.org/jetty/" href="http://www.eclipse.org/jetty/" rel="nofollow">Jetty</a>. <br>On the Axis2 web site, there are a number of tutorials and explanations of the various concepts; yet, somehow, I'm missing a description of the "most easy way" of creating a web service. That's why I write it here. The tutorials are based on using the provided <tt>build.xml</tt> files instead of explaining <i>how to do it</i>. This makes it very hard to work in a different context. </p> <h2>A POJO in an .aar </h2> <p>Axis2 is able to "interpret" any <i>Plain Old Java Object (POJO)</i> as a web service, given the right hints. A Pojo is just a java class with some public method(s). </p> <h3>A POJO </h3> <div id="codeSnippetWrapper"><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"><span style="color: #0000ff">package</span> tecbites.ws;<br><span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> Echo {<br> <span style="color: #0000ff">public</span> String echo(String input) {<br> <span style="color: #0000ff">return</span> input;<br> }<br>}</pre><br></div>
<p>To tell Axis2 that this is a web service, you need additionally </p>
<ul>
<li>a services.xml that defines this class as a POJO RPC web service
<li>an echo.aar that contains (at least) the <tt>services.xml</tt> in the <tt>META-INF</tt> directory, and usually, the web service code (.class file(s)). </li></ul>
<h3>services.xml </h3>
<div id="codeSnippetWrapper"><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"><service name=<span style="color: #006080">"Echo"</span> scope=<span style="color: #006080">"application"</span> ><br> <description><br> Tecbites Echo POJO web service<br> </description><br> <messageReceivers><br> <messageReceiver mep=<span style="color: #006080">"http://www.w3.org/2004/08/wsdl/in-only"</span><br> <span style="color: #0000ff">class</span>=<span style="color: #006080">"org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver"</span>/><br> <messageReceiver mep=<span style="color: #006080">"http://www.w3.org/2004/08/wsdl/in-out"</span><br> <span style="color: #0000ff">class</span>=<span style="color: #006080">"org.apache.axis2.rpc.receivers.RPCMessageReceiver"</span>/><br> </messageReceivers><br> <parameter name=<span style="color: #006080">"ServiceClass"</span>>tecbits.ws.Echo</parameter><br></service></pre><br></div><pre></pre>Put this file into META-INF. <br><a id="creating_an_.aar_-_jar" href="http://www.blogger.com/post-edit.g?blogID=144805460541353359&postID=6561250436074621813" name="creating_an_.aar_-_jar"></a><br>
<h3>creating an .aar - jar </h3>One way to create an .aar is just using the jar-tool that is part of the JDK. Using the following folder structure: <br>
<div id="codeSnippetWrapper"><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet">tecbites/ws/<br> Echo.class<br>META-INF/<br> services.xml</pre><br></div>, a jar can just be created that is named <tt>echo.aar</tt>. Check that the jar/aar does not contain the files in a subdirectory named echo!. <br>
<div id="codeSnippetWrapper"><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet">javac tecbites/ws/Echo.java<br>jar cf echo.aar .</pre><br></div><a id="creating_an_.aar_-_build.xml" href="http://www.blogger.com/post-edit.g?blogID=144805460541353359&postID=6561250436074621813" name="creating_an_.aar_-_build.xml"></a><br>
<h3>creating an .aar - build.xml </h3>
<p>Another way of creating an .aar is using build.xml, the same as creating any other .jar. See the following example: </p>
<div id="codeSnippetWrapper"><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"><span style="color: #0000ff"><?</span><span style="color: #800000">xml</span> <span style="color: #ff0000">version</span><span style="color: #0000ff">="1.0"</span> <span style="color: #ff0000">encoding</span><span style="color: #0000ff">="UTF-8"</span>?<span style="color: #0000ff">></span><br><span style="color: #0000ff"><</span><span style="color: #800000">project</span> <span style="color: #ff0000">name</span><span style="color: #0000ff">="tecbites.echo"</span> <span style="color: #ff0000">default</span><span style="color: #0000ff">="aar"</span> <span style="color: #ff0000">basedir</span><span style="color: #0000ff">="."</span><span style="color: #0000ff">></span> <span style="color: #0000ff"><</span><span style="color: #800000">target</span> <span style="color: #ff0000">name</span><span style="color: #0000ff">="build"</span><span style="color: #0000ff">></span><br> <span style="color: #0000ff"><</span><span style="color: #800000">javac</span> <span style="color: #ff0000">debug</span><span style="color: #0000ff">="true"</span> <span style="color: #ff0000">srcdir</span><span style="color: #0000ff">="."</span> <span style="color: #ff0000">destdir</span><span style="color: #0000ff">="."</span> <span style="color: #ff0000">failonerror</span><span style="color: #0000ff">="true"</span> <span style="color: #0000ff">/></span><br><span style="color: #0000ff"></</span><span style="color: #800000">target</span><span style="color: #0000ff">></span> <span style="color: #0000ff"><</span><span style="color: #800000">target</span> <span style="color: #ff0000">name</span><span style="color: #0000ff">="aar"</span> <span style="color: #ff0000">depends</span><span style="color: #0000ff">="build"</span><span style="color: #0000ff">></span><br> <span style="color: #0000ff"><</span><span style="color: #800000">property</span> <span style="color: #ff0000">name</span><span style="color: #0000ff">="aar"</span> <span style="color: #ff0000">value</span><span style="color: #0000ff">="echo.aar"</span><span style="color: #0000ff">/></span><br> <span style="color: #0000ff"><</span><span style="color: #800000">delete</span> <span style="color: #ff0000">file</span><span style="color: #0000ff">="${aar}"</span> <span style="color: #ff0000">failonerror</span><span style="color: #0000ff">="false"</span><span style="color: #0000ff">/></span><br> <span style="color: #0000ff"><</span><span style="color: #800000">jar</span> <span style="color: #ff0000">destfile</span><span style="color: #0000ff">="${aar}"</span><span style="color: #0000ff">></span><br> <span style="color: #0000ff"><</span><span style="color: #800000">manifest</span><span style="color: #0000ff">></span><br> <span style="color: #0000ff"><</span><span style="color: #800000">attribute</span> <span style="color: #ff0000">name</span><span style="color: #0000ff">="Built-By"</span> <span style="color: #ff0000">value</span><span style="color: #0000ff">="Tecbites http://tecbites.blogspot.com/"</span><span style="color: #0000ff">/></span><br> <span style="color: #0000ff"></</span><span style="color: #800000">manifest</span><span style="color: #0000ff">></span><br> <span style="color: #0000ff"><</span><span style="color: #800000">fileset</span> <span style="color: #ff0000">dir</span><span style="color: #0000ff">="."</span> <span style="color: #0000ff">></span><br> <span style="color: #0000ff"><</span><span style="color: #800000">include</span> <span style="color: #ff0000">name</span><span style="color: #0000ff">="**/*.class"</span> <span style="color: #0000ff">/></span><br> <span style="color: #0000ff"><</span><span style="color: #800000">include</span> <span style="color: #ff0000">name</span><span style="color: #0000ff">="META-INF/**"</span> <span style="color: #0000ff">/></span><br> <span style="color: #0000ff"></</span><span style="color: #800000">fileset</span><span style="color: #0000ff">></span><br> <span style="color: #0000ff"></</span><span style="color: #800000">jar</span><span style="color: #0000ff">></span><br><span style="color: #0000ff"></</span><span style="color: #800000">target</span><span style="color: #0000ff">></span><br><span style="color: #0000ff"></</span><span style="color: #800000">project</span><span style="color: #0000ff">></span></pre><br></div>
<p>Just run <tt>ant</tt>. You have got <a class="external text" title="http://ant.apache.org/" href="http://ant.apache.org/" rel="nofollow">ant</a> installed, have you? </p>
<h3>Deployment </h3>
<p>The installation of an Axis2 webapp and the deployment of an .aar is explained quite well <a class="external text" title="http://ws.apache.org/axis2/1_5/installationguide.html" href="http://ws.apache.org/axis2/1_5/installationguide.html" rel="nofollow">on the site</a>. Just a short version here, based on Tomcat6: </p>
<ul>
<li>download the Axis2 webapp
<li>deploy (copy) the <tt>axis2.war</tt> into <tt>webapps/</tt> of a servlet container (tomcat, jetty, jboss, glassfish, ...) </li></ul>And start the servlet container. Then, copy the <tt>echo.aar</tt> into the <tt>webapps/axis2/WEB-INF/services</tt> directory (the servlet container should automatically unpack <tt>axis2.war</tt> into <tt>axis2/</tt> <br>If you need additional jars or java code you don't want to pack into the .aar itself, there is space in <tt>axis2/WEB-INF/lib</tt> (for the jars) and <tt>axis2/WEB-INF/classes</tt> (for any <tt>package/name/Class.class</tt> files). <br>Usually, Axis2 is configured for "hot deployment". This means that any .aar copied newly into the services directory of a running server is directly deployed as a new web service. There is also "hot update" which is usually disabled, but can be enabled in <tt>axis2/WEB-INF/conf/axis2.xml</tt>. Then, the .aars are automagically reloaded when replaced. Of course, any code in lib/ or classes/ is not. <br>By the way - it should also be possible to deploy the web service by copying the unjared folder structure into a subdirectory of the services dir, thus creating <tt>webapps/axis2/WEB-INF/services/Echo/META-INF/services.xml</tt> etc. <br><a id="Testing" href="http://www.blogger.com/post-edit.g?blogID=144805460541353359&postID=6561250436074621813" name="Testing"></a><br>
<h3>Testing </h3>
<p>The web service should then be visible on <a class="external free" title="http://localhost:8080/axis2/services/listServices" href="http://localhost:8080/axis2/services/listServices" rel="nofollow">http://localhost:8080/axis2/services/listServices</a> (replace port 8080 with the correct one of your servlet container installation). There, you can see all deployed services and list their methods. <br>The <tt>WSDL</tt> can be accessed via <a class="external free" title="http://localhost:8080/axis2/services/EchoService?wsdl" href="http://localhost:8080/axis2/services/EchoService?wsdl" rel="nofollow">http://localhost:8080/axis2/services/EchoService?wsdl</a>. <br>Axis2 supports a part of REST, named POX - Plain Old XML documents over http. This allows to call the web service via <a class="external free" title="http://localhost:8080/axis2/services/EchoService/echo?input=Good%20Morning" href="http://localhost:8080/axis2/services/EchoService/echo?input=Good%20Morning" rel="nofollow">http://localhost:8080/axis2/services/EchoService/echo?input=Good%20Morning</a>. A web page should be returned reading </p>
<div id="codeSnippetWrapper"><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"><span style="color: #0000ff"><</span><span style="color: #800000">ns:echoResponse</span> <span style="color: #ff0000">xmlns:ns</span><span style="color: #0000ff">="http://ws.tecbites"</span><span style="color: #0000ff">></span><br> <span style="color: #0000ff"><</span><span style="color: #800000">ns:return</span><span style="color: #0000ff">></span>Good Morning<span style="color: #0000ff"></</span><span style="color: #800000">ns:return</span><span style="color: #0000ff">></span> <br><span style="color: #0000ff"></</span><span style="color: #800000">ns:echoResponse</span><span style="color: #0000ff">></span></pre><br></div>
<p>By the way - the following error message when accessing <a class="external free" title="http://localhost:8080/axis2/services/EchoService" href="http://localhost:8080/axis2/services/EchoService" rel="nofollow">http://localhost:8080/axis2/services/EchoService</a> means the service is working correctly: ;) </p>
<div id="codeSnippetWrapper"><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"><p><span style="color: #0000ff"><</span><span style="color: #800000">soapenv:Reason</span><span style="color: #0000ff">></span><br> <span style="color: #0000ff"><</span><span style="color: #800000">soapenv:Text</span> <span style="color: #ff0000">xml:lang</span><span style="color: #0000ff">="en-US"</span><span style="color: #0000ff">></span><br> The endpoint reference (EPR) for the Operation not found <br> is /axis2/services/EchoService and the WSA Action = null<br> <span style="color: #0000ff"></</span><span style="color: #800000">soapenv:Text</span><span style="color: #0000ff">></span><br><span style="color: #0000ff"></</span><span style="color: #800000">soapenv:Reason</span><span style="color: #0000ff">></span></p></pre><br></div><pre></pre>
<h2>Direct POJO deployment </h2>
<p>There is also the description of deploying the POJO .class file directly into a specially configured axis2 directory. In the <tt>axis2/WEB-INF/conf/axis2.xml</tt>, there is usually a line reading </p>
<div id="codeSnippetWrapper"><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"><span style="color: #008000"><!--POJO deployer , this will alow users to drop .class </span><br><span style="color: #008000"> file and make that into a service--></span><br><span style="color: #0000ff"><</span><span style="color: #800000">deployer</span> <span style="color: #ff0000">extension</span><span style="color: #0000ff">=".class"</span> <span style="color: #ff0000">directory</span><span style="color: #0000ff">="pojo"</span> <br> <span style="color: #ff0000">class</span><span style="color: #0000ff">="org.apache.axis2.deployment.POJODeployer"</span><span style="color: #0000ff">/></span></pre><br></div>This should allow to deploy the ws by copying <tt>tecbites/ws/Echo.class</tt> into the <tt>pojo</tt> directory. In the context of the jetty servlet container inside the <a class="external text" title="http://sourceforge.net/apps/trac/gsn/" href="http://sourceforge.net/apps/trac/gsn/" rel="nofollow">Global Sensor Networks (GSN)</a> project, I was unable to get this to run. <br><a id="JAXWS_.40WebService_annotations" href="http://www.blogger.com/post-edit.g?blogID=144805460541353359&postID=6561250436074621813" name="JAXWS_.40WebService_annotations"></a><br>
<h2>JAXWS @WebService annotations </h2>
<p>The JAXWS standard allows to "create" web services by annotating the class with the <a class="external text" title="http://java.sun.com/javaee/5/docs/api/javax/jws/WebService.html" href="http://java.sun.com/javaee/5/docs/api/javax/jws/WebService.html" rel="nofollow"><tt>@WebService</tt></a> tag. In the axis2+service.xml context, this is not necessary, but supported. <br>Yet, this is helpful when the web service class contains public methods that should <i>not</i> be accessible as web service methods. </p>
<div id="codeSnippetWrapper"><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"><p><span style="color: #0000ff">package</span> tecbites.ws;<br><span style="color: #0000ff">import</span> javax.jws.WebService;<br><span style="color: #0000ff">import</span> javax.jws.WebMethod;</p><p>@WebService<br><span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> Echo {<br> <span style="color: #0000ff">public</span> String echo(String input) {<br> <span style="color: #0000ff">return</span> input;<br> }<br> @WebMethod(exclude=true)<br> <span style="color: #0000ff">public</span> <span style="color: #008000">/*static*/</span> String helper(String input) { <span style="color: #0000ff">return</span> input; }<br>}</p></pre><br></div><a id="Note" href="http://www.blogger.com/post-edit.g?blogID=144805460541353359&postID=6561250436074621813" name="Note"></a>
<h2>Side note </h2>
<p>You might think I'm working for the Apache project, the way I propose their products/projects here. No, I'm not, it's just a fact that "they" are developing open source Java projects for many purposes, from development support (log4j, ant, ...) over utilities (commons, ...) to enterprise technologies (tomcat, axis2). </p> Sebhttp://www.blogger.com/profile/06553111406739261461noreply@blogger.com0tag:blogger.com,1999:blog-144805460541353359.post-57790965621407215162009-09-12T08:11:00.001+02:002009-09-12T08:13:26.991+02:00Eclipse Galileo 3.5.0 as packages for Ubuntu Jaunty<div id="globalWrapper">
<div id="column-content">
<div id="content">
<div id="bodyContent">
<a href="http://www.blogger.com/post-edit.g?blogID=144805460541353359&postID=5779096562140721516" id=".7EYogarine" name=".7EYogarine"></a><br />
<h2>
~Yogarine </h2>
The eclipse packages delivered with ubuntu are usually very, very old (3.2.x on jaunty).
This is mainly due to the rule of debian that everything(!) needs to be compiled by the
maintainers. Also, they use a completely different Java compile setup than the eclipse
developers - gcj (which is <i>really open source</i>) instead of Sun JDK.
<br />
I just found someone who maintains the eclipse-provided binaries as a set of packages for ubuntu jaunty.
<br />
<a class="external free" href="https://edge.launchpad.net/%7Eyogarine/+archive/eclipse" rel="nofollow" title="https://edge.launchpad.net/~yogarine/+archive/eclipse">https://edge.launchpad.net/~yogarine/+archive/eclipse</a>
<br />
Quite easy to install and use - just note that the JEE tools are inside eclipse-wtp (web tools project).
<br />
It may be that there is stability problem ... I had one crash so far ... no idea whether this was related
to the packages or the Java setup itself on my system (it was somewhere in the subversion->libsvnjavahl->libapr stuff).
</div>
</div>
</div>
</div>
<script type="text/javascript">
if (window.runOnloadHook) runOnloadHook();
</script>Sebhttp://www.blogger.com/profile/06553111406739261461noreply@blogger.com1tag:blogger.com,1999:blog-144805460541353359.post-66821598310849885852009-07-14T10:50:00.003+02:002009-07-14T10:58:15.435+02:00Wisdoms of the day<ul><li>Wenn du den Kaffee nicht aufschüttest, läuft er nicht durch</li> <li>tar cf file.tar --- "cowardly refusing to create empty archive." <br/> Has saved a lot of archives when typing tar cf instead of tar xf ...</li> <li>Ever found a good editor for this blog system?</li> <li>Why am I the only person unable to create a debugging environment for the AVR32?</li></ul>Sebhttp://www.blogger.com/profile/06553111406739261461noreply@blogger.com0tag:blogger.com,1999:blog-144805460541353359.post-82208791811557683332009-07-06T15:40:00.001+02:002009-07-06T15:40:49.914+02:00Using module_param_call for Linux kernel module parameters<p>My first foray into linux kernel programming – writing a module to drive an external buzzer, using the high resolution timer. Not my first action on the linux kernel, though: <a title="http://www.lm-sensors.org/changeset/3613/i2c/trunk" href="http://www.lm-sensors.org/changeset/3613/i2c/trunk">http://www.lm-sensors.org/changeset/3613/i2c/trunk</a></p> <p>Found a nice feature that is not yet well documented.</p> <blockquote> <pre>ushort enabled =0;
module_param(enabled, ushort, <br /> S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH);
MODULE_PARM_DESC(enabled, " Enabled or not");</pre>
</blockquote>
<ul>
<li>Defines a module parameter that can be set on insmod </li>
<li>giving it rights (S_*** equals 0664 aka rw-rw-r-- in this case) allows to set the value via <tt>/sys/module/modulename/parameters/parameter</tt> for both reading and writing </li>
<li>Unfortunately, the module is not notified when the value is set. </li>
</ul>
<p><a title="http://lwn.net/Articles/85443/" href="http://lwn.net/Articles/85443/">http://lwn.net/Articles/85443/</a> only says: <em>“It is worth noting, however, that there is no mechanism for notifying a module that one of its parameters has been changed”.</em></p>
<p>Well, there is a method. <strong>module_param_call</strong>. Or rather a macro. It’s hard to find anything about it on the web, the only(?) source currently are the linux kernel source files … especially <tt>include/linux/moduleparam.h</tt> and <tt>kernel/params.c</tt>.</p>
<blockquote>
<pre>static int param_set_buzzer_enabled(const char *val,
struct kernel_param *kp);
unsigned int buzzerenabled = 0;
module_param_call(buzzer_enabled, param_set_buzzer_enabled, param_get_int,
&buzzer_enabled, 0664);
MODULE_PARM_DESC(buzzer_enabled, " Buzzer enabled? default: 1 (yY)");</pre>
</blockquote>
<p>When the value is queried, the pre-defined method param_get_int is called which directly accesses the <tt>(&)buzzer_enabled</tt> value. When the value is set, the spezial method param_set_buzzer_enabled is called. Of course, it is also possible to do it another way, e.g., to create a read-only parameter which does not have a variable backing.</p>
<p>The role of the <tt>param_set_buzzer_enabled</tt> method is best passed to one of the predefined methods – in this case, <tt>param_set_bool</tt>:</p>
<blockquote>
<pre>static int param_set_buzzer_enabled(const char *val, struct kernel_param *kp)
{
int hr;
// 1yY 0nN
hr = param_set_bool(val, kp);
if (hr!=0) {
printk("Unable to set buzzer_enabled to value '%s'\n", val);
return hr;
}
// do the job, here ;-)
printk("New value: %d\n", buzzer_enabled);
return 0;
}</pre>
</blockquote>
<p><tt>val</tt> is <tt>char*</tt>, always – in some cases, special care needs to be taken of trailing newlines produced by <tt>"echo 0 > /sys/..."</tt>. At least some implementations of the conversion routine (using <tt>simple_strtol</tt>) fail in this case – <tt>"echo –n 0"</tt> needs to be used, then.</p>
<p>I’d say, far easier to use than defining your own kobject instances, attributes and files, and place them in the appropriate <tt>/sys/</tt>-folders. By the way – the macro used above, <tt>module_param</tt>, does nothing else than calling the other one with the correct <tt>param_set_##type</tt> methods based on the given type (ok, I admin, <tt>module_param_named</tt> also participates).</p>
<p>Yours,
<br />Sebastian</p> Sebhttp://www.blogger.com/profile/06553111406739261461noreply@blogger.com1tag:blogger.com,1999:blog-144805460541353359.post-11531245492602150642009-03-15T14:04:00.003+01:002009-03-15T14:13:18.844+01:00UPnP via python<h1>Controlling your DSL Router via UPnP</h1>
When I was looking for a commandline tool to create port mappings on my broadband/DSL router, I detected the <b>miranda.py</b> script on <a href="http://www.sourcesec.com/2008/11/07/miranda-upnp-administration-tool/">http://www.sourcesec.com/2008/11/07/miranda-upnp-administration-tool/</a>.
I needed some functionality not yet provided by the script, namely, the possibility of passing arguments to host send commands. Usually, the script asks nicely for all required arguments; this is hard to automate. Using the patch provided below, a command such as
<pre>host send 0 WANConnectionDevice WANIPConnection AddPortMapping ssh2 0 192.168.32.32 1 22 80.80.80.80 tcp 22</pre>
is now possible.
This also allows bash scripting:
<pre>
cat <<EOF | miranda.py -s ~/.miranda/struct_data.mir
host get 0
host send 0 WANConnectionDevice WANIPConnection AddPortMapping ssh2 0 192.168.32.32 1 22 80.80.80.80 tcp 22
EOF
</pre>
I also fixed a nondescript exception message when no host had yet been loaded/found.
Have fun with it,<br>
yours,<br>
<em>Sebastian</em><br>
<pre>
--- miranda.py.orig 2009-03-15 13:51:03.000000000 +0100
+++ miranda.py 2009-03-15 13:58:37.000000000 +0100
@@ -1065,11 +1065,15 @@
#Send SOAP requests
index = False
inArgCounter = 0
-
- if argc != 6:
+
+ #sbr: allow to pass arguments to the call
+ numReqArgs = 6
+ if argc < numReqArgs:
showHelp(argv[0])
return
+ # number of arguments in addition to the send cmd
else:
+ extraArgs = argc-numReqArgs
try:
index = int(argv[2])
except:
@@ -1078,7 +1082,12 @@
deviceName = argv[3]
serviceName = argv[4]
actionName = argv[5]
- hostInfo = hp.ENUM_HOSTS[index]
+ try:
+ hostInfo = hp.ENUM_HOSTS[index]
+ except Exception, e:
+ print "You need to discover or load some hosts, first"
+ return
+
actionArgs = False
sendArgs = {}
retTags = []
@@ -1106,11 +1115,18 @@
print "Are you sure you've specified the correct action?"
return False
+ extraArgsUsed = 0
for argName,argVals in actionArgs.iteritems():
actionStateVar = argVals['relatedStateVariable']
stateVar = hostInfo['deviceList'][deviceName]['services'][serviceName]['serviceStateVariables'][actionStateVar]
if argVals['direction'].lower() == 'in':
+ if extraArgs-extraArgsUsed > 0:
+ arg = argv[numReqArgs+extraArgsUsed]
+ print "Using ", arg, " for ", argName
+ sendArgs[argName] = (arg,stateVar['dataType'])
+ extraArgsUsed += 1
+ else:
print "Required argument:"
print "\tArgument Name: ",argName
print "\tData Type: ",stateVar['dataType']
</pre>Sebhttp://www.blogger.com/profile/06553111406739261461noreply@blogger.com6tag:blogger.com,1999:blog-144805460541353359.post-80482464189409393462008-02-28T12:18:00.002+01:002008-02-28T13:26:43.315+01:00ZIM, the Desktop-Wiki - or "Taking Notes 2.0"<p>
For the stuff I'm writing here, there are two important roots.<br />
One is the common note taking everyone does, on paper, on computer, or on whatever medium available.<br />
The other are wikis - web 2.0 knowledge management systems for sharing ideas, documentation, or notes with others in a community.<br />
I tend to structure my ideas hierarchically by topic, but easy linking between pages is a must. I need simple text formatting, the possibility to link in external documents or web pages -- all features available with most wikis. Yet, a web-based solution is not very appropriate for personal notes, especially as I'm currently sitting in a hotel room w/o any network connection.</p>
<p>Some time ago, I had a look for desktop wikis. The one I found best is <b>ZIM</b>; since then, I've been using it for nearly all my notes about quite a bunch of topics. Even this blog page I'm writing in it, because I got used to the easy text formatting and html export, far more than the WYSIWYMG editor of this blog site (as in <i>What You See is What You (or your visitors) Might Get</i>).
</p>
<p><a href="http://picasaweb.google.co.uk/csbac74/Blog/photo?authkey=avVuzh__ZaI#5171966802790233154"><img src="http://lh6.google.co.uk/csbac74/R8aEZ6ZstEI/AAAAAAAAACY/KSN9Lq3bBv0/s144/ZIM1.png" align="left" border="4"/></a>Time to show you an image of the stuff I wrote so far, in ZIM. On the left, you can see the top-level structure of my notes, and the "usual" assortment menu items and buttons. And in the main text, you can see the image you are looking at which contains the text which ... ... ... just ignore it.
</p>
I don't want to write too much about it, the you can find more information on <a href='http://pardus-larus.student.utwente.nl/~pardus/projects/zim/'>Jaap's web page</a>. Just an unsorted list of the features I like most ...
<ul>
<li>Stores each page in a .txt file, the directory structure reflects the note hierarchy</li>
<ul>
<li>easy network sharing, backup, version control and all this stuff</li>
<li>there is even an integration with subversion and cvs</li>
<li>pages can be edited externally, e.g., when you just have the .txt files, but no ZIM; and reloaded later on</li>
<li>I use it at home, at work, and on my notebook, and merge it via subversion - no problem with it.</li>
</ul>
<li>works on Linux, Windows, and any other OS that supports Perl and Gtk</li>
<li>text formatting by shortcuts, yet also by manually using the wiki format statements, and reloading the page</li>
<li>pages can be exported to html; this is what is going to happen to this page as well when it is finished</li>
<ul>
<li>keeps the directory and link structure, image embedding, and everything</li>
</ul>
<li>the help is written in ZIM itself</li>
<li>linking in both web pages and files from the current directory is as easy as typing "./document.pdf"</li>
<li>uses CamelCase and similar features for page linking</li>
<li>has a pane with a folder and page structure </li>
</ul>
<p>Anything forgotten? Quite a lot, I'm sure, have a look at the author's page, you'll find it there ;-)</p>
For those of you who have seen tiddlywiki: The latter does not need a application of its own, yet has a lot of severe (IMHO) drawbacks:<ul>
<li>everything is saved in one large file which contains both the java script code (~200kB) and the notes</li>
<li>saving takes a lot of time on a non-local drive</li>
<li>version management, especially merging between different systems, does not really work</li>
</ul>Sebhttp://www.blogger.com/profile/06553111406739261461noreply@blogger.com3tag:blogger.com,1999:blog-144805460541353359.post-90035894914471957372008-02-28T10:34:00.002+01:002008-02-28T10:40:03.827+01:00Another Crashed Train Information System - Linux, this Time<p>
I've seen quite a bunch of crashed visitor information systems, ATMs, and similar, on my my daily what-the-f__k page <a href='http://www.dailywtf.org/'>http://www.dailywtf.org/</a>, all of them Windows based ... now it is time to show the Linux version of it!<p>
<p><a href="http://picasaweb.google.co.uk/csbac74/Blog/photo?authkey=avVuzh__ZaI#5171636640064254994"><img src="http://lh5.google.co.uk/csbac74/R8VYH6ZstBI/AAAAAAAAACA/YsCdt63F8gk/s144/Departure-Linux-500.jpg" align="left"/></a><a href="http://picasaweb.google.co.uk/csbac74/Blog/photo?authkey=avVuzh__ZaI#5171636644359222306"><img src="http://lh6.google.co.uk/csbac74/R8VYIKZstCI/AAAAAAAAACI/SrzJ_IRolRY/s144/Departure-Working-400.jpg" align="right"/></a>As every Linux-user will recognise from the photo, there is <b>only one way</b> to crash such a system if it is Linux-based ... <b>fry the harddisk</b>. No blue screens, no "segmentation fault" dialogs, no kernel panics ... (no, the picture does not need to be rotated.)
<br />
<p>On the right, you can see how the departure information should have looked like. And for the Germans among you - have a guess which major train station it happened on ;-)<p/>
<p>BTW, the ticket vending machines from the "DB" are using Windows. And, I did get my train, which is not that common, even (especially?) in Germany ...<p/>Sebhttp://www.blogger.com/profile/06553111406739261461noreply@blogger.com0tag:blogger.com,1999:blog-144805460541353359.post-10105602532037465702008-02-22T14:24:00.001+01:002008-02-22T14:24:20.818+01:00Java, PDFRenderer, and the Importance of "Order"<p>There is a great Java package for displaying PDF files inside your Java application: <a href="https://pdf-renderer.dev.java.net/">PDFRenderer, </a>developed as part of the java.net approach (javadesktop/swinglabs). Unfortunately, the <b>order</b> in which you do certain things is <b>very</b> important.<br/>
So, you need to do the following (in the Code):</p>
<ol>
<li>Create the JFrame, and create and add the PagePanel from PDFRenderer</li>
<li>Show the JFrame (<code>setVisible(true)</code>)</li>
<li>Show the PDF page you want to show (<code>PagePanel.showPage(...)</code>)</li>
</ol>
<p>This seems trivial, is done this way in the samples, yet ... change the order, and the only thing you get is "no page seleceted".</p>
<ul>
<li>setVisible before adding PagePanel: "no page selected"</li>
<li>setVisible after showPage: "no page selected"</li>
<li>adding PagePanel to a visible JFrame: "no page selected"</li>
<li>showPage in an invisble JFrame: "no page selected"</li>
<li>and so on ;-)</li>
</ul>
<p>Great software, isn't it?<br>
By the way, it can only show pdf version 1.4 (from Acrobat/Reader 5.0), and if there is a problem, you get an exception trace to System.err, yet no way to catch the exception ... the display is running asynchronously in a thread of its own.</p>
Have fun!Sebhttp://www.blogger.com/profile/06553111406739261461noreply@blogger.com3tag:blogger.com,1999:blog-144805460541353359.post-19590680513648771292008-02-22T14:11:00.000+01:002008-02-22T14:12:21.839+01:00Getting Birthday Greetings twice a Year with Skype<p>Wondering how to get birthday greetings from most of your friends more than once a year? Just change your birthday in your Skype profile regularly ...</p>
<p>A friend of mine just did it, unintentionally, though. I got a note from Skype that he was going to have his birthday in a few days, entered it into my calender, and send him greetings on the day. Then, by coincidence, I checked his Skype profile again ... and noticed that the birthday was 10 months later, now. (To tell the truth, I noticed a mismatch between his age and the difference between his birth year, and 2008. Already wanted to post it to my favorite <a href="http://thedailywtf.com/">What-the-Fork page</a>.)</p>
<p>I apologised to him, and he told me that quite some people had greeted him, so he noticed the mistake in his skype profile, and changed it. Yet there is no reason why it shouldn't work, regularly, most (Skype) friends will forget it anyway in a few months, and some will even add both (or even more ;-)) of your birth dates into their calenders ...</p>
Have fun.Sebhttp://www.blogger.com/profile/06553111406739261461noreply@blogger.com0tag:blogger.com,1999:blog-144805460541353359.post-66493298874220384602008-02-18T14:18:00.005+01:002008-03-13T08:21:49.111+01:00Migrating Windows XP from Pentium4 to Athlon64X2<p>You have a running Windows XP system on an "old" Intel-based processor, Pentium 4, e.g., and you get a new computer with an AMD-based processor, an Athlon64X2 4800+, in my case. Switching the hard disks from one machine to the other is easy, of course, yet the system doesn't boot ... due to</p>
<ul><li>different hardware access layers (HAL)</li>
<li>different hard disk (SATA) controllers</li>
<li>different CPUs</li>
<li>possibly more reasons.</li></ul>
<p>But, there are solutions for everything ... even though MS says it's not possible (at least, they say it is impossible to switch CPU types when using sysprep, see <a href="http://support.microsoft.com/kb/828287/">here</a>).</p>
<h3>Step 1: Backup</h3>
<p>Save all important data. You never know what is going to happen.</p>
<h3>Step 2: Remove Drive Letter Assignments</h3>
<p>If you don't want to move the harddisk, but copy it instead onto another one, you need to remove all drive letter assigments. Otherwise, if your C: system is copied onto a G: drive, you will end up with a G: drive on the new system ... which does not really work.
See <a href="http://www.dominok.net/en/it/en.it.clonexp.html">"Forking a XP-installation"</a>: Remove all entries from the registry-key <code>"HKEY_LOCAL_MACHINE\SYSTEM\MountedDevices"</code></p>
<p>If you use the copying approach, some more steps are necessary, especially making the hard disk bootable by makeing a rescue boot, and executing fixmbr and fixboot sucessfully. Also, the copying itself needs to be done on a third(!) system.</p>
<h3>Step 4: Disable intelppm.sys and/or processr.sys</h3>
<p>There are two system services that are left untouched by Windows XP when doing a repair as we are going to do below, both responsible for Intel processors -- microcode loading, etc. Thus, either</p>
<ul><li>disable them before shutting the old system down for the last time (services.msc, "Disable")</li>
<li>Boot your windows XP CD into rescue console mode, and execute "disable intelppm" and/or "disable processr" (use "listsvc" for listing the services). This can also be done between steps 5 and 6, if necessary.</li></ul>
<p>Thanks to <a href="http://blogs.msdn.com/virtual_pc_guy/archive/2005/10/24/484461.aspx">Ben Armstrong</a> from the Virtual PC Team for this information; also see <a href="http://support.microsoft.com/kb/888372/en-us">here.</a></p>
<h3>Step 5: Repair the system</h3>
<p>Use the XP CD to boot, select "Install", then, "Repair". Makes a clean installation of the system, yet <strong>keeps all software, user etc. settings, programs and data</strong>. This is the main reason for doing this in the beginning, instead of a clean install. <br>
Make sure you have a XP CD <b>with</b> Service Pack 2, to avoid both the trouble of reinstalling it, and any unexpected pre-SP2-behaviour ...</p>
<p>Information about this repair can be found, e.g., <a href="http://support.microsoft.com/?scid=kb%3Ben-us%3B315341&x=10&y=12">here.</a></p>
<p>If you skip this step and just boot the old system on the new machine, you get a blue screen of death (BSOD) -- usually <a href="http://support.microsoft.com/?scid=kb%3Ben-us%3B315341&x=10&y=12">"inaccessible boot device"</a>, also <a href="http://msdn2.microsoft.com/en-gb/library/ms795508.aspx">here</a> or <a href="http://support.microsoft.com/default.aspx?scid=kb;en-us;Q314082">here.</a></p>
<h3>Step 6: Boot the half-installed system</h3>
<a href="http://picasaweb.google.com/csbac74/Blog/photo?authkey=avVuzh__ZaI#5169477761868018690"><img src="http://lh4.google.com/csbac74/R72soqZstAI/AAAAAAAAABc/wCkB_typvco/s144/GreenScreenOfDeath-cut-400.jpg" align="right" alt="STOP: 0x0000007E (0xC0000005, 0xBAA28750, 0xBACC342C, 0xBACC3128)"/></a>
<p>Part of the repair process, as any other windows install process, is a reboot. If the reboot fails with a blue screen (of death, BSOD), or a green screen (yes, really, see figure), you need to do step 4 ("disable intelppm"):<br/> <code>STOP: 0x0000007E (0xC0000005, 0xBAA28750, 0xBACC342C, 0xBACC3128)</code></p>
<p>Apart from this, you need to finish the installation, including new hardware drivers (they'll have changed, anyway), and similar stuff. You should have a running system, now; otherwise, contact me with detailed questions ;-)</p>
<h3>Step 7: Patch the system</h3>
<p>Last thing to do: install the current MS patches. You overwrote all system files, so you are back to SP2 state ... that means about 50 patches, currently.</p>
<h3>Step n: Have fun.</h3>
As much fun as one can have with a windows system ....
<h3>Appendix A</h3>
<p>As I found out later (12th March 2008), it is possible to copy the "repair" registry into into a non-booting system via the repair console (booted from CD). This is usually the first step on the way to manually copying the least recent registry from a system restore point. On the other hand, it is possible to copy c:\windows\repair\system into c:\windows\config\system, thus replacing the <em>system</em> registry only, while keeping the rest of it, and forcing hardware re-detection on the next boot</p>
<p>Unfortunately, this did not really work out on the one time we tried it ... the system booted, yet the second the mouse cursor appeared it re-booted.</p>
<p>On the other hand -- if you have a system that windows is not willing to repair because it is simply not detected by the boot CD for the "repair-install", doing this surprisingly makes the CD rediscover the installation ... no idea why it wasn't found in the first place, yet it helped. Go back to Step 1, then. </p>
<h3>Appendix B</h3>
<p>After the finished the install on the new hardware, the installation still contains the information about all the old hardware ... from on-board network devices via ACPI to mainboard resources. There is trick to make the hardware configuration panel to <a href="http://support.microsoft.com/kb/315539">show "non-available" devices</a>, though, and delete the ones you surely never need again. The non-available ones have "lighter" icons.</p>
<ul><li>start a cmd shell</li><li><code>set devmgr_show_nonpresent_devices=1</code></li><li><code>devmgmt.msc</code></li></ul>
<p>Just don't delete anything you might need again, and rather keep the USB stuff ... also, do <b>not</b> delete any IDE channels, as the ones where no drive is attached, are shown as missing as well.</p>Sebhttp://www.blogger.com/profile/06553111406739261461noreply@blogger.com0tag:blogger.com,1999:blog-144805460541353359.post-192552605306640172008-02-14T10:16:00.008+01:002008-02-15T19:56:09.811+01:00Speeding up Firefox "Tab Effect"<p>There's the great plugin for Firefox called <a href="https://addons.mozilla.org/en-US/firefox/addon/4258">"Tab Effect"</a> which does 3D rotation on a cube when you change tabs. No important use, yet great animation. For Windows-Users who want Linux XGLX or MacOS feeling.
Unfortunately, the switching takes time ... but there is a speedup patch:</p>
<a href="https://addons.mozilla.org/en-US/firefox/reviews/display/4258">
<h3>"How to make it faster!</h3></a><address>by aquanautmonkey on December 17, 2007 (rated 7) </address>
<p>
Nice effect!
To make it faster, do the following:
<ol>
<li>Open the tab_effect-1.1-fx.xpi file in a zip archive editor (7zip, etc.)</li>
<li>Navigate to content/javascript.js</li>
<li>About 3/4 down the file there is this line:<br>
TabEffect.xpcomObj.translateToNextTab(back, 24);</li>
<li>Set the number which is originally 24, to be something less. I put 10 and it works much faster and looks better!</li>
<li>Install the edited add-on like you usually would.</li>
</ol>
<h3>Editing after installation</h3>
<p>
There is also a simple way to edit it after installation:
<ul><li>Go into extensions\{0784CD66-62FE-4cef-ABF4-F8ED9B654ACC}\content (if the GUID is different, search for ITabEffect.xpt in the extensions dir, and go into ..\content</li><li>Edit javascript.js, TabEffect.xpcomObj.translateToNextTab(back, 8); (8 instead of the default 24)</li><li>Restart firefox</li><li>enjoy!</li></ul>
If the graphics card is the slowing factor in your setup, this won't help you, of course ...</p>Sebhttp://www.blogger.com/profile/06553111406739261461noreply@blogger.com0tag:blogger.com,1999:blog-144805460541353359.post-5085812512684626982008-02-14T08:21:00.002+01:002008-02-14T08:27:26.387+01:00Market niches<ul><li>Spotted chocolate ("Kuhflecken"), with dark spots instead of white ones</li><li>An alarm clock that does a short "beep" or "ding" a few minutes before wakeup time, so that you are already "prepared" for the real signal, and don't need the snooze feature so often</li></ul>
Any more ideas?Sebhttp://www.blogger.com/profile/06553111406739261461noreply@blogger.com1tag:blogger.com,1999:blog-144805460541353359.post-64740533207112281202008-02-13T15:43:00.006+01:002008-02-13T17:04:42.109+01:00Loading an XML file into Java objects with CastorA common problem:
You have a certain XML file, of a semi-fixed format. No document type definition (DTD), no XML schema definition (XSD), just some "agreed-on" XML structure.
You want to load a bunch of those files into Java, and work with them.
Best would be to transfer them into Java classes or beans.
Castor allows this - see <a href="http://www.castor.org/">http://www.castor.org/</a>
Install Castor 1.2, you'll need the complete version with source code; otherwise, it seems to be missing some of the dependencies, e.g., velocity-1.5.jar.
The scripts to run are found in <CASTOR>/bin as .sh and/or .bat scripts, e.g., classpath.bat/.sh which will be used in the following.
<h3>Step 1: Generating a schema definition</h3>
Castor is able to generate an xsd file from an XML instance file. This schema might not be complete nor correct, yet it is a good starting point. Possible, you'll have to patch it, to remove nodes that have no well-known structure, or to add others that don't appear in the selected instance file.
<pre>
classpath.bat
org.exolab.castor.xml.schema.util.XMLInstance2Schema
input.xml [output.xsd]
</pre>
If no output file is given, the schema is written to standard out.
Alternatively, you can used the class from your own code:
<pre>
XMLInstance2Schema instance2Schema = new XMLInstance2Schema();
Schema schema = instance2Schema.
createSchema("input.xml");
System.out.println(schema);
// copied from XMLInstance2Schema#main
Writer dstWriter = new PrintWriter(
new FileOutputStream("output.xsd"), true);
SchemaWriter schemaWriter = new SchemaWriter(dstWriter);
schemaWriter.write(schema);
dstWriter.flush();
</pre>
Some Links:<ul><li><a href="http://www.castor.org/xml-faq.html#Is-there-a-way-to-automatically-create-an-XML-Schema-from-an-XML-instance?">Castor FAQ</a>
</li><li><a href="http://www.nabble.com/How-to-create-XML-Schema-based-on-XML-td13400428.html">Nabble Forum
</a></li><li><a href="http://castor.codehaus.org/javadoc/org/exolab/castor/xml/schema/util/XMLInstance2Schema.html">XMLInstance2Schema</a></li></ul>
<h3>Step 2: Patch the generated schema</h3>
Often, changes to the generated schema file are necessary.
The input.xml may, for example, contain a set of nodes that are not really well-agreed on, change regularly, or are very different between different instance files. In our case, it was some html-formatted text that was just barely made xml-compatible by making sure each <p> also contained </p> ... not even xhtml, I'd say.
So, we replaced a complex node structure
<pre>
{sequence}
{element name="p"}
{complexType}
{all}
{element name="i"}
{complexType mixed="true"}
{sequence}
[...]
</pre>
with simple
<pre>
{element name="p" type="xsd:anyType" /}
</pre>
Links:<ul><li><a href="http://www.xmlschemareference.com/schemaElement.html">XML Schema reference</a></li><li><a href="http://de.wikipedia.org/wiki/XML_Schema#Beliebiger_Inhalt">Wikipedia: anyType (German)</a></li></ul>
<h3>Step 3: Generate the Java classes</h3>
Next step, Castor generates Java classes from the schema definition. Again, this can either be done by the sourceGen.bat provided with castor, or programmatically via <code>org.exolab.castor.builder.SourceGeneratorMain.main(new String[] {param1, param2, ...})</code>.
<pre>sourceGen.bat -i output-patched.xsd
-package my.package.name -dest src -f -types j2</pre>
-f suppresses any non-fatal warnings, including the overwriting of existing files.
-types j2 uses java.util.List for collections, even List<Type> with Java 5.0 as below.
For each type Type of the schema, a my.package.name.Type java file is generated, and a my.package.name.descriptors.TypeDescriptor for Castor use.
Oh, I also put a castorbuilder.properties file into the current directory which contained
<pre>
# Defines the XML parser to be used by Castor.
# The parser must implement org.xml.sax.Parser.
org.exolab.castor.parser=org.xml.sax.helpers.XMLReaderAdapter
# Defines the (default) XML serializer factory to use by Castor, which must
# implement org.exolab.castor.xml.SerializerFactory; default is
# org.exolab.castor.xml.XercesXMLSerializerFactory
org.exolab.castor.xml.serializer.factory=org.exolab.castor.xml.XercesJDK5XMLSerializerFactory
# Defines the default XML parser to be used by Castor.
org.exolab.castor.parser=com.sun.org.apache.xerces.internal.parsers.SAXParser
org.exolab.castor.builder.javaVersion=5.0
</pre>
<a href="http://www.castor.org/sourcegen.html">Castor Source-Generation</a>
<h3>Step 4: Use the classes</h3>
Write some code that unmarshals the XML file(s), and prints the resulting objects. toString() is not overridden, so you have to query each attribute and subnode individually.
<pre>
TopType top = (TopType) Unmarshaller.unmarshal(
TopType.class, new FileReader("input.xml"));
// topType.getSubItem returns SubItem[]
for (SubItem item: topType.getSubItem()) {
System.out.printf("SubItem id: %s; value: %s\n",
item.getSomeId(), item.getSomeValue());
// p is just the anyType object from above; toString(), it
// prints the XML content as a fragment.
System.out.println(item.getP());
}
</pre>
Have fun with it!Sebhttp://www.blogger.com/profile/06553111406739261461noreply@blogger.com0tag:blogger.com,1999:blog-144805460541353359.post-44368969506610246842007-10-25T11:48:00.001+02:002008-02-12T18:05:29.597+01:00Unit Testing (1): OverviewFirst article of a series:
Use unit testing with open source Java components, in the environment of Swing UIs, J2EE server components, database access (esp. hibernate), web applications, etc.
Unit testing is an important part of Test Driven Development (TDD). Admittedly, I have mostliy ignored this topic up to now. Obviously, the overview I have over my own code was enough to detect, place and correct bugs; working with others' code, detecing errors was usually easy, leaving them to fix it ;-)
Also, I was always of the opinion that "my" projects were not applicable for Unit Testing ... complicated UIs, enterprise architectures, complex databases, J2EE deployment, etc. Luckily, others have worked on developing frameworks for most of these purposes.
<h2>Test-Driven Development</h2>First write the tests, then the structure of the class to implemented, then run the tests. They'll fail, as there is no implementation yet.
So, do the coding, test it regularly, until the tests don't fail any longer ... finshed, sort of.<t>
</t><h2>JUnit</h2>JUnit is the most-used Java testing framework. There are so many good tutorials out there, so I don't see the need to write another one. Read one or more of
<ul><li>http://www.junit.org/</li><li>http://junit.sourceforge.net/</li><li>http://www.ibm.com/developerworks/library/j-ant/</li><li>http://www.torsten-horn.de/techdocs/java-junit.htm</li></ul>In the following, I will use JUnit 4.4.
Version 4 changed a lot of the usage of Test Cases and such, using Java 5 annotations.
<ul><li>http://www.frankwestphal.de/JUnit4.0.html</li><li>http://www.mm.informatik.tu-darmstadt.de/courses/helpdesk/junit4.html</li><li>http://radio.javaranch.com/lasse/2006/07/27/1154024535662.html</li><li>http://www.instrumentalservices.com/content/view/45/52/</li></ul>I will also make use of the assertThat statement which was introduced with JUnit 4.4, because it makes much of the test code more readable, especially the error messages.
<ul><li>http://junit.sourceforge.net/doc/ReleaseNotes4.4.html</li></ul><h2>Sample</h2>We write a simple utility for concatenating the textual representation of list elements, with a user-defined concatenation string.
Having the list <code>("Hello", "world", "!")</code>, <code>CollectionUtils.collectionToString(list, ", ")</code> should produce <code>"Hello, World, !"</code>.
<h3>Unit Test for collectionToString</h3>
We start with the unit test.
<pre>public class CollectionUtilsTest {
@Test public void testCollectionToString() {
final List <String> list1 = Arrays.asList("Hello", "World", "!");
final String comma = ", ";
final String result1 = CollectionUtils.collectionToString(list1, comma);
// we can check the complete string
assertEquals("Hello, World, !", result1);
// or the items
for (String s: list1)
assertThat(result1, containsString(s));
// and, all items except that last, need to be followed by ", "
Iterator<string> it = list1.iterator();
while (it.hasNext()) {
String s = it.next();
if (it.hasNext())
assertThat(result1, containsString(s+comma));
}
}
}</string></pre>
<code>assertEquals()</code> is quite easy to understand, imported via <code>import static org.junit.Assert.assertEquals</code><span style="font-family:Georgia,serif;">, and compares its two parameters for equality. Usually, a first parameter should be added that contains the message to print, if the two values are not equal.
<h3>Code for collectionToString()</h3>
Of course, we also need the CollectionUtils class.
<pre>public class CollectionUtils {
// for the moment, we don't do anything
public static String collectionToString(List<?> list, String comma) {
return null;
}</pre>That's enough to run a unit test ... with eclipse, you just need to start either the test case class (CollectionUtilsTest above) with "Run as JUnit Test", or -- alternatively -- the whole project, which runs all unit tests in the selected package.
<h3>First test run</h3>
<pre>java.lang.AssertionError: expected:<Hello, World, !> but was:<null<
...
at sbr.jut.demo.CollectionUtilsTest.testCollectionToString(CollectionUtilsTest.java:29)
...</pre>
<h3>Coding collectionToString</h3>
<pre>public static String collectionToString(Collection<string> coll, String comma) {
StringBuilder sb = new StringBuilder();
String sComma = "";
for (String s: coll) {
sb.append(sComma);
sb.append(s);
sComma = comma;
}
return sb.toString();
}</string></pre>
And, now, the unit test runs through ... until we start some demonic testing ;-)
<h3>Special test cases</h3>
Of course, null pointers and stuff need to be taken care of, especially ...
<pre>assertEquals("collectionToString(null, null)", "",
CollectionUtils.collectionToString(null, null));
assertEquals("collectionToString(null, null)", "",
CollectionUtils.collectionToString(Collections.EMPTY_LIST, null));
final String result2 = CollectionUtils.collectionToString(list1, "");
assertEquals("HelloWorld!", result2);
final String result3 = CollectionUtils.collectionToString(list1, null);
assertEquals("HelloWorld!", result3);</pre>
Nice, we start with the first NullPointerException
<pre>java.lang.NullPointerException
at sbr.jut.demo.CollectionUtils.collectionToString(CollectionUtils.java:18)
at sbr.jut.demo.CollectionUtilsTest.testCollectionToString(CollectionUtilsTest.java:45)
...</pre>, start fixing our implementation, until we end with ... no NPE!
<pre>public static String collectionToString(Collection<string> coll, String comma) {
if (coll==null)
return "";
if (comma==null)
comma = "";
StringBuilder sb = new StringBuilder();
...
}</string></pre>
So, that is enough for the beginning ...</span>Sebhttp://www.blogger.com/profile/06553111406739261461noreply@blogger.com0tag:blogger.com,1999:blog-144805460541353359.post-26497192887470000642007-10-21T10:06:00.000+02:002007-10-21T10:53:24.188+02:00Java programming dynamicsA very good series of articles about Java reflection (how to access a class' members and methods by name), class loading, and bytecode manipulation can be found at the IBM pages (April '03 - June '04):
<ul><li><a href="http://www.ibm.com/developerworks/java/library/j-dyn0429/">Part 1: Classes and class loading</a></li><li><a href="http://www.ibm.com/developerworks/java/library/j-dyn0603/">Part 2: Introducing reflection</a></li><li><a href="http://www.ibm.com/developerworks/java/library/j-dyn0715.html">Part 3: Applied reflection</a></li><li><a href="http://www.ibm.com/developerworks/java/library/j-dyn0916.html">Part 4: Class transformation with Javassist</a></li><li><a href="http://www.ibm.com/developerworks/java/library/j-dyn0203.html">Part 5: Transforming classes on-the-fly</a></li><li><a href="http://www.ibm.com/developerworks/java/library/j-dyn0302.html">Part 6: Aspect-oriented changes with Javassist</a></li><li><a href="http://www.ibm.com/developerworks/java/library/j-dyn0414/">Part 7: Bytecode engineering with BCEL</a></li><li><a href="http://www.ibm.com/developerworks/java/library/j-dyn0610/">Part 8: Replacing reflection with code generation</a></li></ul>If you want to learn something about the one the reasons that make Java such a powerful languate, read it. These features are, e.g., used by JEE servers or persistence frameworks to automatically determine the methods and fields to be deployed, for accessing the Java 5 @Attributes (not in the articles, yet comparably easy), and to code or derive proxy classes for the deployed services.
Part 1:
<ul><li>.class file format</li></ul>Part 2:
<ul><li>Hierarchy of class loaders</li><li>fields and methods by reflection</li><li>security of reflection, and how to disable it (e.g., to access private members(1))</li><li>reflection performance</li></ul>Part 3:
<ul><li>Using reflection for processing command line arguments
</li></ul>Part 4:
<ul><li>Inject bytecode into existing methods with javaassist</li><li>introduce method timing into compiled code
</li><li>Java Aspect Oriented Programming (AOP)</li></ul>Part 5:
<ul><li>Intercepting class loading</li><li>modifying class bytecode on load</li><li>introduce method timing into code at load time</li></ul>Part 6:
<ul><li>Code conversion</li><li>class mutilation made easy</li></ul>Part 7:
<ul><li>The Byte Code Engineering Library (BCEL)
(also have a look at <a href="http://asm.objectweb.org/">ASM,</a> also, as this library tries to correct BCEL's deficits)</li><li>using "coding constructs" instead of "bytecode assembler"
</li><li>the verifier of BCEL</li><li>disassembling with BCEL and its graphical display
</li></ul>Part 8:
<ul><li>Reflection on performance</li><li>building a glue class
</li><li>improved performance of code generation vs. reflection
</li></ul><span style="font-size:85%;"><span style="font-style: italic;">Notes:
(1) I know you shouldn't do this, especially not with human men ...
</span></span>Sebhttp://www.blogger.com/profile/06553111406739261461noreply@blogger.com0tag:blogger.com,1999:blog-144805460541353359.post-22028098321708262412007-10-16T11:36:00.000+02:002007-10-25T11:47:05.847+02:00Auto-Repeat of Server Calls<b>Problem:</b>
When doing client/server-programming, the client calls a function on the server -- EJB, RMI, Web-Services, etc., in a language such as Java.
Sometimes, the connection to the server gets lost, as the server is restarted, redeployed, network was down and up again, etc.
Then, the client's call to the server fails; after reconnecting, it should be possible to repeat the call and get the wanted result. Possibly, the reconnection will take some time, if the network has a longer "outing".
How can we ensure that the call is done in any case, even if there are transient network/deployment problems?
<b>Solution 1:</b>
The client's Business Delegate (you have one, haven't you?) calls a "ping()" or another such method before calling the real business method on the server. If the connection is broken, catch the exception, try to reconnect, until such a ping goes through.
<em>Disadvantages:</em>
<ul><li>doubles the number of c/s calls</li>
<li>if the ping succeeds, but the real call fails due to problems <i>in this nano second</i>, you're out of luck</li></ul>
<b>Solution 2:</b>
Wrap the call to the server inside a runnable, and repeat the call until it succeeds.
Requires a language like Java, that supports runnable concepts.
Let's see ... some code, untested, out of thin air.
<pre>
protected IServer mServer;
public ResultObject <b>businessMethod</b>(final int intParam, final String stringParam)
throws BusinessException {
class <b>BusinessMethodRunnable</b> implements Runnable() {
private ResultObject result;
public void <b>run</b>() {
<i>// do the server call itself, and store the result.</i>
result = mServer.businessMethod(intParam, stringParam);
}
public ResultObject <b>getResultObject</b>() {
return resultObject;
}
}
BusinessMethodRunnable runnable = new BusinessMethodRunnable();
<i>// wraps the call, to ensure successful completion</i>
callMethod(runnable);
return runnable.getResultObject();
}
protected void <b>callMethod</b>(Runnable runnable)
throws BusinessException {
<i>// repeat, until the loop is left with return after a successful call</i>
while (true) {
try {
if (mServer==null)
<i>// should block until the connection has been established</i>
connectToServer();
<i>// do the real call here.</i>
runnable.run();
return;
}
<i>// a business exception needs to be passed to the calling code</i>
catch (BusinessException e) {
throw e;
}
<i>// a runtime exception also needs to be passed to the calling code ...</i>
catch (RuntimeExceptione ) {
throw e;
<i>// alternatively:
// throw new BusinessException("RuntimeException caught", e);</i>
}
catch (Exception e) {
logException(e);
<i>// connection down, no resources to be freed(?)</i>
mServer = null;
}
}
}
</pre>Sebhttp://www.blogger.com/profile/06553111406739261461noreply@blogger.com0tag:blogger.com,1999:blog-144805460541353359.post-58655782589650450162007-10-16T11:25:00.000+02:002007-10-16T11:36:44.498+02:00Restoring Word 95 files on Windows 95 after crashSome of us are still using Windows 95.
(Probably none of "us", as I doubt any of those systems is able to surf the net ;-)
Mostly on machines that need it ... as nothing newer runs.
And, of course, for these systems, there is only Word 95 and companions.
Also, these machines still have floppy drives.
Not to forget -- most of the users of these systems are a bit digitally ... challenged.
Now, there is a user who thought saving files on a floppy disk would save them ... in case of a system/harddisk crash.
Not as a backup, but for working on the file.
Well.
As saving on a floppy takes some time, it's usually not done that often.
And computers crash.
So, we have an hours old file on a floppy, a rebooted system, and an old version of office that may or may not have auto-recovery files. And if it has those, where are they stored, if not in the working directory? Which is a floppy.
3/4 of an hour telephoning later, the file was found in c:\windows as "Sicherungskopie von ...". Rename it to .doc, and open it ... there it is.
Wait ... first, we need to explain, still via telephone, how to make windows show the extension ... otherwise, you can't change its extension.
Well, I should just send the bill for nearly an hours work ... probably the same as a new old computer for the user ;-)Sebhttp://www.blogger.com/profile/06553111406739261461noreply@blogger.com0tag:blogger.com,1999:blog-144805460541353359.post-20406387202962792192007-10-09T09:58:00.003+02:002008-06-20T14:43:56.734+02:00Avr32 Studio and .d filesHas been some time since I wrote this, so it's high time for publishing it ...!<br>
There seems to be a problem with the Atmel AVR32 studio.
It is based on eclipse, to develop C/C++ software for the embedded AVR32 chips.<br>
The following error message is (often) given, when a project is recompiled:<br>
make -k all<br>
src/main.d:1: *** multiple target patterns. Stop.<br>
Build complete for project aixC-BoxFirmware<br>
This usually happens when the previous build was not successful, b/c one ore more files could not be compiled.<br>
The reason seems to be the following line in the automatically generated Debug/src/*.d files:<br>
src/main.d src/main.o: ../src/main.cpp ...<br>
It seems, make is not really able to cope with the multiple main.d main.o: statement ...?<br>
The .d files are responsible for checking all file dependencies, i.e., which files need to be recompiled if one header has been changed.<br>
After a clean, which deletes *.d, a full build works.<br>
avr32-linux-gcc is called with the parameters<br>
-MMD -MP -MF"src/main.d" -MT"src/main.d"<br>
which means:<br>
Generated src/main.d (-MF) with the target src/main.d (-MT), for all user include files, and compile the source (-MMD), and generate phony targets for depended files (-MP).<br>
So, theoretically, only<br>
src/main.d: ...<br>
should appear in the src/main.d file ...<br>
Workarounds:<br>
1. Delete all .d files before recompiling<br>
not nice ... looses all dependency information<br>
2. Fix the generated .d files<br>
The following, a bit obscure sed command can be run inside Project/Debug to fix the .d files.<br>
find . -name '*.d'|xargs sed -ie 's#\.d src/[^/]\+/[^ /\.]\+\.o:#.d:#g'<br>
// do I need .d or .o?<br>
The real problem seems to be s.th. else ... the makefile itself (src/subdir.mk) has a rule for building src/main.o from src/main.cpp, and the .d file contains another rule ... strange version of make ...?<br>
The real problem is the inclusion of C:/home/Projekte/Avr32/aix-AVR32-libs/libserial-0.5.2/src/<br>
which gives the other ":" that raises the error ...<br>
1. use a relative path<br>
2. use make 3.80 ...<br>
This error is usually encountered in other situations:<br>
1. a file name contains spaces (windows makes, mostly)<br>
2. a file name contains : (windows again ;-)<br>
http://sunsite.ualberta.ca/Documentation/Gnu/make-3.79/html_chapter/make_16.html<br>
http://sunsite.ualberta.ca/Documentation/Gnu/make-3.79/html_chapter/make_4.html#SEC40<br>
Have fun,<br>
Sebastian<br>
See also<br>
http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&p=315323<br>
You've run into one of our known issues:<br>
Bug #5452<br>
Referencing external folders in managed make projects when using GNU make 3.81 causes build failures. This is caused by GNU make no longer supporting Windows-style path names. GNU make 3.80 works as expected.<br>
The known issues are described in the release notes, which are available on atmel.com. They are also included in the AVR32 Studio Help.<br>
Note that the release notes were not available on the website until quite recently, and the links in the Welcome page appear to be buggy, so I'm not blaming you for not reading them. This will be addressed for the 1.0 release.<br>
Run the cygwin setup.exe and try to downgrade Make to 3.80, that should help.<br>Sebhttp://www.blogger.com/profile/06553111406739261461noreply@blogger.com0tag:blogger.com,1999:blog-144805460541353359.post-813453038984826022007-09-01T10:17:00.000+02:002007-09-17T16:22:34.155+02:00Exporting hi-resolution images from OpenOffice.org DrawI can't use OpenOffice.org at work, so I try to use it for private stuff, as far as possible. Sometimes, though, I start wondering why ...
In the my current version of OpenOffice Draw (2.0.4, updated to 2.2.1, still the same ), it is impossible to export an image in a different resolution than 96dpi. Unless one uses workarounds like eps+ghostscript, pdf, or a macro.
I loaded an foto from my camera, 2272x1704 (4 MP), added some numbers and lines, and exported it into jpg, png etc. ... and got 1016x762. With different jpeg compression qualities, of course, but no different sizes. <a href="http://readlist.com/lists/openoffice.org/users/5/29094.html">Joe</a> pointed me to <a href="http://qa.openoffice.org/issues/show_bug.cgi?id=4499">the OO QA tracker, issue 4499</a>; a short summary:
<ul><li>the problem is known since May 2002
</li><li>it was closed due to a misunderstanding of the problem in July 2002
</li><li>reopened shortly after (OO 1.0)
</li><li>since then, reasons for not fixing it have been given ...
main problem: all filters need to be extended with the same functionality, thus, an extension to all the export dialogs needs to be requested, designed and implemented
</li><li>last post, "No promises but I try to do something for 2.3 here"</li></ul>
(I just wonder why the export dialog is part of the filter, and not of the common export handling code.)
Thanks to bryancole and jbarwick, there is one workaround:
Take the following macro code, add it to OpenOffice, and run it ...
It exports the current page (with white borders) or the current selection into a given .jpg file, with manual setting of resolution and quality.
Maybe someone has a lot of time on his/her hands and wants to write a dialog that does the same?
<code>Sub ExportCurrentPageOrSelection
REM Filter dependent filter properties
Dim aFilterData (7) As New com.sun.star.beans.PropertyValue
Dim sFileUrl As String
' set the width and height you want
aFilterData(0).Name = "PixelWidth"
aFilterData(0).Value = 1704
aFilterData(1).Name = "PixelHeight"
aFilterData(1).Value = 2272
' no real idea what the logical width/height does ... and what units it is in?
' original was 140 and 98.89 ...
aFilterData(2).Name ="LogicalWidth"
aFilterData(2).Value = 1704
aFilterData(3).Name ="LogicalHeight"
aFilterData(3).Value = 2272
' jpeg quality
aFilterData(4).Name ="Quality"
aFilterData(4).Value = 85
aFilterData(5).Name = "ColorMode"
aFilterData(5).Value = 0
aFilterData(6).Name = "ExportMode"
aFilterData(6).Value = 1
' resolution, for use when loading in another image application
aFilterData(7).Name = "Resolution"
aFilterData(7).Value = 600
' the place to put it ... file:///C:/temp/image.jpg should work for Windooze
sFileUrl = "file:///home/meself/export-1.jpg"
REM A smart person would force this to be a Draw or Impress document
xDoc = ThisComponent
xView = xDoc.currentController
xSelection = xView.selection
If isEmpty( xSelection ) Then
xObj = xView.currentPage
Else
xObj = xSelection
End If
Export( xObj, sFileUrl, aFilterData() )
End Sub
Sub Export( xObject, sFileUrl As String, aFilterData )
Dim xExporter
xExporter = createUnoService( "com.sun.star.drawing.GraphicExportFilter" )
xExporter.SetSourceDocument( xObject )
Dim aArgs (2) As New com.sun.star.beans.PropertyValue
Dim aURL As New com.sun.star.util.URL
aURL.complete = sFileUrl
aArgs(0).Name = "MediaType"
aArgs(0).Value = "image/jpeg"
aArgs(1).Name = "URL"
aArgs(1).Value = aURL
aArgs(2).Name = "FilterData"
aArgs(2).Value = aFilterData
xExporter.filter( aArgs() )
End Sub</code>
Note:
OpenOffice.org 2.3.0 is out now (Sept 17th, 2007), yet this problem is unchanged.Sebhttp://www.blogger.com/profile/06553111406739261461noreply@blogger.com3tag:blogger.com,1999:blog-144805460541353359.post-15731373667804068752007-08-30T11:26:00.001+02:002007-08-30T17:20:36.302+02:00C++ String-UtilsEver had the problem of wanting to use (s)printf to format a string into an STL/StdC++ std::string instance?
The only thing STL says is, "use strstream", which I don't agree with ... (s)printf is easier to use once you get used to the %s stuff, and often cleaner to read.
Thus, I wrote my own method ... maybe I just used to much String.format() in Java ;-)
<h3>StringUtils.hh</h3>
<pre>
#ifndef STRINGUTILS_HH_
#define STRINGUTILS_HH_
#include <string>
std::string formatString(const char* format, ...);
#endif /*STRINGUTILS_HH_*/
</pre>
<h3>StringUtils.cc</h3>
<pre>
#include "StringUtils.hh"
#include "BufferUtils.hh"
#include <stdarg.h>
using std::string;
/**
No need to be afraid about memory leaks, segfaults
or buffer overflows (hopefully)
- the 2kB buffer is freed on return (destructor)
- the std::string is instantiated <it>before</it> the
buffer is freed, and returned on the stack
- vsnprintf checks the buffer length, and the last char
is ensured to be a '\0'
*/
std::string formatString(const char* format, ...) {
Buffer buffer(2048);
va_list vl;
va_start(vl, format);
vsnprintf(buffer, buffer.bufferSize(), format, vl);
buffer[buffer.bufferSize()-1] =0;
return string(buffer);
}
</pre>Sebhttp://www.blogger.com/profile/06553111406739261461noreply@blogger.com0tag:blogger.com,1999:blog-144805460541353359.post-10373492705730464702007-08-30T11:23:00.000+02:002007-08-30T17:15:23.369+02:00C++ Buffer-UtilsA common C++ problem: allocate some memory block, use it inside a function, and make sure the memory block is freed when exiting the function, even if an early return statement, an exception (or a segfault) or s.th. happens.
Best way: Create a class, allocate the memory block in the constructor and free it automatically in the destructor. Instantiate the class locally (i.e., on the stack), problem solved.
Some conversion operators to get the mem block as char*, void* etc needed ...
Additionally, a small method to nullify a pointer after free'ing the allocated memory with free(). Of course, when using C++, the clean way would be to use new char[] and delete[] ... yet I don't like these ones when I work with an unspecified memory block.
<h3>BufferUtils.hh</h3>
<pre>
#ifndef BUFFERUTILS_HH_
#define BUFFERUTILS_HH_
#include <cstdlib>
void freeAndNull(void* &pBuffer);
class Buffer {
private:
int miBufferSize;
void* mpBuffer;
public:
Buffer(int bufferSize)
: miBufferSize(bufferSize), mpBuffer(malloc(bufferSize)) {
// empty
};
~Buffer() {
freeAndNull(mpBuffer);
}
int bufferSize() {
return miBufferSize;
}
operator char*() {
return (char*)mpBuffer;
}
operator void*() {
return mpBuffer;
}
};
#endif /*BUFFERUTILS_HH_*/
</pre>
<h3>BufferUtils.cc</h3>
<pre>
#include "BufferUtils.hh"
void freeAndNull(void* &pBuffer) {
if (pBuffer)
free(pBuffer);
pBuffer = NULL;
}
</pre>Sebhttp://www.blogger.com/profile/06553111406739261461noreply@blogger.com0