tag:blogger.com,1999:blog-80421718761695528092024-02-19T06:10:04.937+01:00The Xemantic Blogmorisilhttp://www.blogger.com/profile/11834032341726823036noreply@blogger.comBlogger36125tag:blogger.com,1999:blog-8042171876169552809.post-70422351450282369312014-02-08T19:39:00.000+01:002014-02-08T19:39:51.236+01:00Ultimate hosting solution for static websites<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjebGBZaD4Ae35Ug54uCt-D8WltxCHU_5-P2mnWqRhK43qTkV5O5xADUMAFGFflAqeXgisF_AffCGi-5l-FYTQiiTxNg6atD6aj_MVqT3OXhU8UvJqvsumbDL7HW-tXWxDzLNI21a9skT6J/s1600/github-octocat.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjebGBZaD4Ae35Ug54uCt-D8WltxCHU_5-P2mnWqRhK43qTkV5O5xADUMAFGFflAqeXgisF_AffCGi-5l-FYTQiiTxNg6atD6aj_MVqT3OXhU8UvJqvsumbDL7HW-tXWxDzLNI21a9skT6J/s400/github-octocat.jpg" /></a></div><br />
<p> How often do you create simple web pages? No PHP, or anything, just pure HTML+CSS. How ofter do you update them? Do you use version control system for this purpose just like for other dev projects? How about hosting your project directly from the source code repository? Wouldn't that be perfect?<br />
</p><p> In the previous post I described <a href="/2013/12/ftp-synchronization-how-to-update-your.html">how to use <code>lftp</code> to effectively update website on FTP server</a> with the trick of reverse mirror mode. But if you are using <a href="http://git-scm.com/">GIT</a> for versioning your HTML (which I strongly recommend even if there are no other people working on the project), you are also quite likely using <a href="https://github.com/">GitHub</a> for keeping your source code. Do you know that you can <a href="http://pages.github.com/">host your website directly from GitHub infrastructure</a>? For free.<br />
</p><p> Of course it is possible to use custom domain name. In order to fully utilize GitHub's global <a href="http://en.wikipedia.org/wiki/Content_delivery_network">Content Delivery Network</a> it is advised to use <code>CNAME</code> record with for example <code>www</code> subdomain prefix to canonicalize domain name. Be sure to choose domain registrar which will allow you to configure <a href="http://en.wikipedia.org/wiki/HTTP_301">HTTP 301 redirection</a> for the main domain.<br />
</p>morisilhttp://www.blogger.com/profile/11834032341726823036noreply@blogger.com0tag:blogger.com,1999:blog-8042171876169552809.post-16190949053501296182013-12-22T16:39:00.000+01:002013-12-22T16:43:44.991+01:00FTP synchronization. How to update your sites via FTP?<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1znhQq5vBZ1MQu7qhbDp-3coIsPrJRnwcgpPEGK8PJm_cu65Yp6Nh3Ny0Y_GkIjaILCLOW6OZNdSKlqgJ76chZ7CfPfPq0-Gs96Gcb2dtG3wjANfLUM7FJSfG2UbYR_4ptMjwDACBZekI/s1600/ethernet.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1znhQq5vBZ1MQu7qhbDp-3coIsPrJRnwcgpPEGK8PJm_cu65Yp6Nh3Ny0Y_GkIjaILCLOW6OZNdSKlqgJ76chZ7CfPfPq0-Gs96Gcb2dtG3wjANfLUM7FJSfG2UbYR_4ptMjwDACBZekI/s400/ethernet.jpg" /></a></div><p><strong>Upload your site via FTP</strong>. This is usual offer bundled with web hosting solutions. Nowadays it is mostly <a href="http://en.wikipedia.org/wiki/SSH_File_Transfer_Protocol">SFTP</a>, for secure communication. <br />
</p><p>There are various sophisticated FTP synchronization solutions. But you can also use simple <a href="http://lftp.yar.ru/">LFTP</a> script to achieve the same. The <code>lftp</code> command is available in most of the Linux distributions.<br />
</p><p>Here is example script I put in some of the projects which are deployed as pure static HTML/CSS:<br />
</p><pre class="code">lftp -u <em>username</em> -e "set ssl:verify-certificate no; mirror --reverse --delete --only-newer -v <em>site_source_dir</em> /; exit" <em>ftp.somewebhosting.org</em>
</pre><p>It works like a charm thanks to this <q>reverse mirror</q> approach.<br />
</p><p>But there are better ways of pushing changes to your static sites. If your are interested, watch out the next post which should appear soon.<br />
</p>morisilhttp://www.blogger.com/profile/11834032341726823036noreply@blogger.com4tag:blogger.com,1999:blog-8042171876169552809.post-69730540380305942402011-04-26T21:16:00.000+02:002012-10-04T22:54:00.343+02:00Szczecin JUG meeting: Dependency Injection and Google Guice<p> Here are the <a href="http://groups.google.com/group/szczecin-jug/browse_thread/thread/eeb9837a895796f1">details</a> of this event (in Polish). </p><p> It is the first in a series of lectures/workshops covering practical aspects of <a href="http://en.wikipedia.org/wiki/Dependency_injection">Dependency Injection</a>, <a href="http://code.google.com/p/google-guice/">Google Guice</a>, <a href="http://code.google.com/p/google-gin/">GIN</a>, and building <a href="http://code.google.com/webtoolkit/">GWT</a> applications in the spirit of <a href="http://en.wikipedia.org/wiki/Model-view-presenter">Model-view-presenter</a> pattern. </p>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-8042171876169552809.post-57390367473586809232011-04-02T20:23:00.000+02:002011-04-02T20:23:45.379+02:00mvn release:update-versions<p>
<a href="http://maven.apache.org/plugins/maven-release-plugin/update-versions-mojo.html">mvn release:update-versions</a>
</p>
<p>
So simple feature, but a huge time saver for multi-module maven projects.
</p>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-8042171876169552809.post-79298532806939000102011-01-31T23:56:00.000+01:002011-01-31T23:56:45.632+01:00Tadedon - solid ground for any Java application<p>
Some time ago I started project called <a href="http://code.google.com/p/tadedon/">tadedon</a>. The name is coined by my little son <a href="http://memy.xemantic.com/search/label/alan">Alan</a> (Polish), and I assume it is short, unique, and easy to remember.
</p>
<p>
The whole projects consists of several <a href="http://maven.apache.org/">maven</a> modules, which are intended to be flexible tools for solving common problems. Each module is built on top of library like <a href="http://code.google.com/p/google-guice/">Guice</a>, <a href="http://code.google.com/webtoolkit/">GWT</a>, <a href="http://commons.apache.org/configuration/">commons-configuration</a>, etc. Tadedon modules shouldn't be considered as extensions to these libraries, but rather as a thin layer of code which allows to use these libraries in special contexts. Here is an example of <code>tadedon-guice-servlet-mock</code> module which supports unit testing of Guice <a href="http://code.google.com/p/google-guice/wiki/ServletModule">Servlet Modules</a> without the need of real servlet container.
</p>
<p>
I have already released version <code>1.0</code>. Now tadedon needs some attention - it should attract more users, and developers. Any contributions are welcome. Putting tadedon modules into maven central repository seems the most important goal right now.
</p>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-8042171876169552809.post-50374573619186677072010-10-21T00:00:00.000+02:002010-10-21T00:00:50.511+02:00Divergence<p>
Since the beginning of this blog I have been posting entries in both English and Polish. In order to distinguish these entries I applied specific labels to them. Now I feel it is the time for change.
</p>
<p>
I can recognize some writing patterns typical to myself. Either I am posting on computers/programming or on some other topics like little Alan, philosophy, arts, etc. I suppose that different audience could be interested in different contexts thus I am splitting this single blog into 3 new blogs.
</p>
<p>
This blog will remain concerned with IT stuff. Soon all non-it stuff will be moved to other places (together with comments).
</p>
<p>
I have started two new blogs for all the non-IT stuff:
</p>
<ul>
<li><a href="http://memy.xemantic.com/">replikator memetyczny</a></li>
<li><a href="http://memes.xemantic.com/">memetic repicator</a></li>
</ul>
<p>
Feel free to go there from time to time.
</p>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-8042171876169552809.post-43823355563500057852010-01-14T03:08:00.006+01:002010-10-27T16:57:38.544+02:00Unlocking Android - A Developers Guide<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.manning.com/ableson/ableson_cover150.jpg"><img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 150px; height: 188px;" src="http://www.manning.com/ableson/ableson_cover150.jpg" border="0" alt="" /></a>
<p>
Thanks to <a href="http://groups.google.com/group/szczecin-jug">Szczecin JUG</a> I had opportunity to read <a href="http://www.manning.com/ableson/">Unlocking Android - A Developer's Guide</a>. The title very accurately describes contents of this book. It is truly a developers guide, but also something more.
</p>
<p>
If you are reading this review, you probably already heard about Android? For sure this name does not only denote a bunch of mobile devices, nor it only refers to specific operating system. Android is one of the platforms provided by Google.
</p>
<p>
I found very interesting opinion somewhere on the web. The author concludes that Sun and Google both have three different Java editions. As Sun provides Enterprise Edition, Standard Edition and Micro Edition, Google offers Cloud Edition (Google App Engine for Java), Web Edition (Google Web Toolkit) and Mobile Edition (Android). Comparing Android to JavaMe is not completely fair. However such comparison shows how many possibilities Android platform provides in the field of development for mobile devices. From this perspective 'Unlocking Android' is not only a developers guide - it is a book about one of important Java editions. Software developed for mobile devices has it's very own specifics and Android platform offers special approach for addressing them. The book describes these topics to great extent also showing interesting comparison with other major mobile platforms.
</p>
<p>
Structure of the book is very convenient for the reader. However be prepared that it is more step-by-step guide then detailed reference of Android APIs. It starts with general concepts, and goes through detailed description of Eclipse based development environment, specifics of UI design, code examples of available APIs, and ends with core topics from the Hacking Android chapter. Each chapter contains a lot of diagrams and screenshots in addition to text and code fragments. The code examples are usually short, and possibly refer only to concept they are supposed to explain. However the sequence of involved machinery is described as deep as it matters - sometimes as deep as the level of Linux operating system internals below Dalvik virtual machine.
</p>
<p>
The whole Unlocking Android, it's structure and contents, is influenced by psychology of the end user of mobile device - the role of user's Intent as declaration of need. APIs which reference the real world have a real world illustrations - e.g. location API has picture of little globe describing latitude and longitude concepts. However I remember such picture from primary school, it seems very useful in this place. The consequence of such amount of information enclosed in one source (almost 400 pages) is that it could be hard to use it as a quick reference.
</p>
<p>
Unfortunately the Android Market and procedures of publishing the application are described very briefly. Android platform is evolving very quickly and I hope that book will be updated to include new features.
</p>
<p>
Who will benefit from reading Unlocking Android? I find it convenient and clear, but novice to software development could be confused. Authors assume that reader has experience in programming techniques, XML related topics, and Java in particular. Regardless of good IDE support the topic of development for mobile devices is quite complex. The requirements of good software design can interfere with the requirements of high performance and low memory footprint. It reminds me the time when I was coding in assembler :) . If you want to develop application on Android platform and have strong background in Java then the Unlocking Android will help you for sure.
</p>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-8042171876169552809.post-21070226432040080362009-11-30T12:36:00.009+01:002010-10-31T17:15:24.691+01:00XMind as eclipse plugin<h2>About XMind</h2>
<p>
Have you tried <a href="http://www.xmind.net/">XMind</a>? It is very nice, open source <a href="http://en.wikipedia.org/wiki/Mind_map">mind mapping</a> tool. If you have not tried mind mapping at all, maybe it is a good time to start as it helps a lot to visualize any conceptualization and then conceptualize some complex matters even better.
</p>
<iframe id='xmindshare_embedviewer' src='http://www.xmind.net/share/_embed/stephen/xmind-3-1-2/' frameborder='0' scrolling='no' width='100%'></iframe>
<p>
XMind is built on top of <a href="http://www.eclipse.org/home/categories/rcp.php">Eclipse RCP</a> and so far has been distributed also as eclipse plugin. However now this option is no longer supported. As I spend a lot of time in eclipse it is much more convenient to me, to have mind maps and code in the same tool.
<h2>Installation</h2>
<p>
I found the solution. Here is the script <code>install-as-eclipse-plugin.sh</code>:
</p>
<pre class="code">
#/bin/bash -e
if [ ! $2 ]; then
echo "Usage ./install-as-eclipse-plugin.sh xmind_path eclipse_path"
exit 1
fi
XMIND_PATH="$1"
ECLIPSE_PATH="$2"
if [ ! -d $XMIND_PATH/plugins ]; then
echo "Error - no /plugins directory in $XMIND_PATH - probably not XMind directory"
exit 2
fi
if [ ! -d $ECLIPSE_PATH/plugins ]; then
echo "Error - no /plugins directory in $ECLIPSE_PATH - probably not eclipse directory"
exit 3
fi
echo "Copying XMind plugins from $XMIND_PATH to eclipse at $ECLIPSE_PATH"
# remove old xmind plugins (if they exist)
rm -fr $ECLIPSE_PATH/dropins/xmind
mkdir -p $ECLIPSE_PATH/dropins/xmind/plugins
# exclude language variants, and os specific stuff
PLUGINS=`ls $XMIND_PATH/plugins | grep -v nl_ | grep -v linux | grep -v win32 | grep -v macos`
for PLUGIN in $PLUGINS; do
PLUGIN_NAME=`echo $PLUGIN | cut -d "_" -f 1`
FOUND=`find "${ECLIPSE_PATH}/plugins" -name "${PLUGIN_NAME}_*"`
if [ "$FOUND" == "" ]; then
echo "Copying: $PLUGIN"
cp -r $XMIND_PATH/plugins/$PLUGIN $ECLIPSE_PATH/dropins/xmind/plugins
else
echo "Plugin already installed: $PLUGIN_NAME"
fi
done
</pre>
<p>
This script will compare XMind plugins with plugins already available on eclipse installation and copy only these missing. It will also exclude all localization resources (I don't need them) and macosx stuff. Adjust these lines according to your needs.
</p>
<p>
All the plugins will be copied to <code>dropins/xmind</code> directory - it will ease the upgrade, if you want to remove xmind functionality from eclipse just remove this directory.
</p>
<p>
The only problem I have encountered so far is that on fresh eclipse installation, when new node is added to the map, there is exception from spell checker. Opening and closing xmind spell checking preferences in eclipse fixes this.
</p>
<p>
<strong>Update:</strong> I updated the script not to copy specific plugins, even if their version do not match. All the platform dependent stuff is excluded by default. The solution is tested with eclipse helios (3.6) and XMind 3.2.0.
</p>
<h2>How to use XMind in eclipse</h2>
<p>
Thanks to some comments I realized it could be not obvious how to use XMind inside eclipse. If you already have XMind file in one of your eclpse projects you can just click on it and it should open inside eclipse. Apparently you can also use <code>File > Open File...</code> from pull down menu to open any <code>.xmind</code> file. However you will not see all the <code>Markers</code> and <code>Overview</code> windows unless you open so called <code>Mind Mapping</code> perspective. You have only one default perspective in XMind, but several perspectives in default eclipse installation. Use <code>Windows > Open Perspective > Other... > Mind Mapping</code> from the pull down menu. You can also open separate windows specific to this perspective - just use <code>Window > Show View</code>. In order to create new XMind file, just open <code>File > New File > Other... > Mind Mapping > Mind Map Workbook</code>
</p>Unknownnoreply@blogger.com16tag:blogger.com,1999:blog-8042171876169552809.post-84975790880121755662009-11-19T00:46:00.006+01:002010-10-27T16:22:20.402+02:00wondershaper is a real wonder<p>
Have you ever experienced "slow internet" when there is another ongoing transfer on your wire which fully saturates the bandwidth. Even if one can accept high latency of HTTP transfers (sooner or later the page will appear in the browser), in case of interactive sessions like SSH it is completely unacceptable. <a href="http://lartc.org/wondershaper/">Wondershaper</a> is a great remedy with minimal side effects - especially if your are running your router on Linux machine.
</p>
<p>
Wondershaper is using CBQ instead of HTB and I am aware that there are better approaches to traffic shaping in Linux. But "traffic shaping" is usually associated with the context of splitting the bandwidth of single internet link among many hosts. This is too much in my case and wondershaper does exactly what I expect.
</p>
<p>
My ADSL line is 1024/256kb officially. But in logs I can see different values:
</p>
<pre class="code">
ATM dev 0: ADSL line is up (1312 kb/s down | 320 kb/s up)
</pre>
<p>
At first I tried to provide these values to wondershaper, however they were too high (high latency still and packet drops in addition). By using different values I finally established that official numbers give the best trade-off between latency and link speed.
<p>
<p>
In case of my link the average download rate is around 126KB/s. Now with wondershaper it is around 120KB/s - about 95% of the original speed - this the cost. However SSH sessions work like a charm when updates are being downloaded and the browser loads pages almost as fast as usually.
</p>
<p>
Now specific section of my <code>/etc/network/interfaces</code> (Debian specific) looks like:
</p>
<pre class="code">
auto ppp0
iface ppp0 inet ppp
pre-up /usr/local/sbin/firewall.sh start
pre-up while ! grep 'Line up' /proc/net/atm/speedtch:0 &>/dev/null; do sleep 1; done
post-up echo "1" >/proc/sys/net/ipv4/ip_forward
post-up wondershaper ppp0 1024 250
pre-down wondershaper clean ppp0
pre-down echo "0" >/proc/sys/net/ipv4/ip_forward
post-down /usr/local/sbin/firewall.sh stop
</pre>
<h2>Update</h2>
<p>
With the <code>1024 256</code> values I still had some latency where my uplink was fully saturated. The <code>1024 250</code> values seems to work OK.
</p>Unknownnoreply@blogger.com4tag:blogger.com,1999:blog-8042171876169552809.post-73403796620944262352009-11-07T01:13:00.007+01:002010-10-27T16:22:20.403+02:00smartd.conf: the ultimate settings<p>
By "ultimate settings" I mean options which suit my needs best ;) . I had problems finding comprehensive example of <code>smartd.conf</code> options. Here is what I finally came to:
</p>
<pre class="code">
/dev/sda \ # The device to monitor
-a \ # Implies all standard testing and reporting.
-n standby,10,q \ # Don't spin up disk if it is currently spun down
\ # unless it is 10th attempt in a row.
\ # Don't report unsuccessful attempts anyway.
-o on \ # Automatic offline tests (usually every 4 hours).
-S on \ # Attribute autosave (I don't really understand
\ # what it is for. If you can explain it to me
\ # please drop me a line.
-R 194 \ # Show real temperature in the logs.
-R 231 \ # The same as above.
-I 194 \ # Ignore temperature attribute changes
-W 3,50,50 \ # Notify if the temperature changes 3 degrees
\ # comparing to the last check or if
\ # the temperature exceeds 50 degrees.
-s (S/../.././02|L/../../1/22) \ # short test: every day between 2-3am
\ # long test every Monday between 10pm-2am
\ # (Long test takes a lot of time
\ # and it should be finished before
\ # daily short test starts.
\ # At 3am every day this disk will be
\ # utilized heavily as a backup storage)
-m root \ # To whom we should send mails.
-M exec /usr/share/smartmontools/smartd-runner # standard debian script
</pre>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-8042171876169552809.post-75260840996743776172009-11-06T14:26:00.004+01:002010-10-27T16:22:20.404+02:00smartmontools: debian lenny backport for armel architecture<p>
I had to backport <code>smartmontools</code>. You can download it from <a href="http://code.google.com/p/xemantic-builds/downloads/list">xemantic-builds</a>
</p>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-8042171876169552809.post-71723389095811466412009-11-05T20:09:00.008+01:002010-10-27T16:22:20.406+02:00dropbear: scp does not work, here is poor man's replacement<p>
The <a href="http://matt.ucc.asn.au/dropbear/dropbear.html">dropbear</a> project provides very interesting implementation of SSH server. It has advantage of very low memory footprint, which might be crucial in case of embedded devices. Personally I use dropbear on <a href="http://en.wikipedia.org/wiki/NSLU2">NSLU2</a> device (aka SLUG).
</p>
<p>
I was a little bit disappointed when I tried <code>scp</code> command against dropbear server (on debian host):
<p>
<pre class="code">
$ scp .ssh/id_rsa.pub root@slug:authorized_keys
bash: scp: command not found
lost connection
</pre>
<p>
Another try:
</p>
<pre class="code">
sftp root@slug
Connecting to slug...
bash: /usr/lib/sftp-server: No such file or directory
Connection closed
</pre>
<p>
Dropbear comes without <code>scp</code> and <code>sftp-server</code> commands. On debian you can find them in <code>openssh-server</code> package. Installing it would bring a lot of unwanted dependencies not even mentioning that I would have to make sure that OpenSSH server is not going to start and compete with my little <code>dropbear</code>. Here is simple scp-like solution.
</p>
<pre class="code">
cat .ssh/id_rsa.pub | ssh root@slug 'tee authorized_keys >/dev/null'
</pre>
<p>
I hope it will help someone.
</p>Unknownnoreply@blogger.com3tag:blogger.com,1999:blog-8042171876169552809.post-2935831373398249032009-06-27T02:11:00.004+02:002010-10-27T16:22:20.415+02:00Sparse image bundle for Time Machine backup<p>
The command is:
</p>
<pre class="code">
$ hdiutil create -size 150g -fs HFS+J -nospotlight -imagekey sparse-band-size=131072 -volname “hostname-backup” /tmp/HOSTNAME_MACADDRESSWITHOUTCOLONS.sparsebundle
</pre>
<dl>
<dt>-size</dt><dd>the maximal size of the bundle in gigabytes (created image will be initially smaller though - about 250MB)</dd>
<dt>-fs HFS+J</dt><dd>the filesystem - using HFS is the main reason for preparing image anyway. TimeMachine depends on some HFS magic.</dd>
<dt>-nospotlight</dt><dd>prevents Mac OS from indexing this image</dd>
<dt>-imagekey sparse-band-size=131072</dt><dd>some sources on the Internet claim this is the best choice in terms of performance</dd>
</dl>
<p>
When the image is ready, it should be moved to the network share where backup will be stored. Choosing the new location in TimeMachine preferences is the last step.
</p>Unknownnoreply@blogger.com3tag:blogger.com,1999:blog-8042171876169552809.post-56124359427166068402009-03-15T23:34:00.005+01:002009-03-16T00:12:00.380+01:00gwt-servlet-war project, no more annoying gwt-servlet in the classpath<p>
All the GWT libraries are available in the central maven repositories now. There are 4 different jars for single platform (<code>gwt-user</code>, <code>gwt-dev</code>, <code>gwt-dev</code> with platform classifier (thus there is even more jars the 4) and <code>gwt-servlet</code>.
</p>
<p>
If you are developing gwt application which will be packaged as war, these libraries should be included in <code>pom.xml</code> with something like this:
</p>
<pre class="code">
<dependencies>
<dependency>
<groupId>com.google.gwt</groupId>
<artifactId>gwt-user</artifactId>
<version>${gwtVersion}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.gwt</groupId>
<artifactId>gwt-dev</artifactId>
<version>${gwtVersion}</version>
<classifier>${platform}-libs</classifier>
<type>zip</type>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.gwt</groupId>
<artifactId>gwt-dev</artifactId>
<version>${gwtVersion}</version>
<classifier>${platform}</classifier>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.gwt</groupId>
<artifactId>gwt-servlet</artifactId>
<version>${gwtVersion}</version>
</dependency>
</dependencies>
</pre>
<p>
GWT jars marked with <code>provided</code> will be available during development, but not packaged into war. This approach have only one drawback, core gwt classes are present in both - <code>gwt-user</code>, and <code>gwt-servlet</code> jar in the same time. In case of developing project in eclipse with m2eclipse plugin it leads to very annoying behavior (not finding sources, showing two candidate types with the same name, etc.).
</p>
<p>
I have created new <a href="http://code.google.com/p/gwt-servlet-war/">gwt-servlet-war</a> project to overcome this problem. The idea is very simple. Instead of the last <code>gwt-servlet</code> dependency from above example, one should put:
</p>
<pre class="code">
<dependency>
<groupId>pl.ncdc.gwt</groupId>
<artifactId>gwt-servlet-war</artifactId>
<version>${gwtVersion}</version>
<type>war</type>
</dependency>
</pre>
<p>
After this change, war packaging will be supported by so called "war overlays" where wars specified as dependencies are merged into war being built.
</p>
<p>
And guess what gwt-servlet-war contains? Only gwt-servlet library in <code>WEB-INF/lib</code>. Thus project is in fact single <code>pom.xml</code>. Anyway It have to be packaged according to gwt versioning scheme.
</p>
<p>
If anyone have any idea how to set up maven repository on top of code.google.com's subversion, please contribute it to the project. Maybe I should promote this jar to be put in central maven repo, or rather suggest people responsible for putting gwt artifacts there to provide something of this kind along the line?
</p>Unknownnoreply@blogger.com1tag:blogger.com,1999:blog-8042171876169552809.post-47607926421949159332009-02-03T00:01:00.004+01:002010-10-27T16:22:20.416+02:00Maven google code upload plugin<p>
The project is located <a href="http://code.google.com/p/gcupload-maven-plugin/">here</a>.
</p>
<p>
Example setup (works well with my projects) looks like:
</p>
<pre class="code">
<plugin>
<groupId>org.riedelcastro</groupId>
<artifactId>maven-gcupload-plugin</artifactId>
<version>1.0</version>
<configuration>
<uploads>
<upload>
<extensions>jar</extensions>
<labels>Featured,Type-Archive,OpSys-All</labels>
</upload>
<upload>
<extensions>jar</extensions>
<postfix>sources</postfix>
<labels>Featured,Type-Source,OpSys-All</labels>
</upload>
<upload>
<extensions>jar</extensions>
<postfix>javadoc</postfix>
<labels>Featured,Type-Docs,OpSys-All</labels>
</upload>
</uploads>
</configuration>
</plugin>
</pre>
<p>
The <code>gcupload:gcupload</code> maven target is added to our <a href="https://hudson.dev.java.net/">Hudson</a>. We have <a href="http://code.google.com/p/differentia-javaica/">differentia-javaica</a> release build which takes care of everything - deploying jars to our <a href="">Nexus</a> as well as putting them to <a href="http://code.google.com/">Google Code</a>.
</p>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-8042171876169552809.post-71196093866912324372009-02-02T23:39:00.003+01:002010-10-27T16:22:20.418+02:00Differentia Javaica<p>
I started a new project called <a href="http://code.google.com/p/differentia-javaica/">differentia-javaica</a>. Here is the quote from the original description:
</p>
<blockquote>
<p>
The aim of this project is to compare two java source codes and check if they are equal. It is not a simple diff. It uses ANTLR to construct two Abstract Source Trees for java types and eventually compare these trees. As a consequence white spaces and comments will not affect comparison. Reordering of elements in source code will be treated as difference though.
</p>
<p>
This kind of comparison is especially helpful when writing unit tests for java source code generators. When we have expected source code it is possible to check if it equals to generated source code.
</p>
</blockquote>
<p>
We are writing some Java source code generators right now at <a href="http://www.ncdc.pl/">NCDC</a> and this tools is quite helpful in unit testing. Thus we want to share it with community.
</p>Unknownnoreply@blogger.com2tag:blogger.com,1999:blog-8042171876169552809.post-68404277612822549732008-12-23T23:20:00.010+01:002010-10-27T16:18:49.066+02:00Even more X-mas cards<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_nw-zNqHeRyc/SVHzjRP93EI/AAAAAAAAAD0/V_rkUsL24cU/s1600-h/3797.jpg"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 317px;" src="http://2.bp.blogspot.com/_nw-zNqHeRyc/SVHzjRP93EI/AAAAAAAAAD0/V_rkUsL24cU/s400/3797.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5283271625133644866" /></a>
<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_nw-zNqHeRyc/SVHzjp2RYuI/AAAAAAAAAD8/Oj_KStNL174/s1600-h/3798.jpg"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 263px;" src="http://3.bp.blogspot.com/_nw-zNqHeRyc/SVHzjp2RYuI/AAAAAAAAAD8/Oj_KStNL174/s400/3798.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5283271631736759010" /></a>
<p>
Source: <a href="http://eatliver.com/">eatliver.com</a>
</p>
<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_nw-zNqHeRyc/SVFkWJtT3II/AAAAAAAAADs/jJNwZkc70QM/s1600-h/DSC_0090.JPG"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 266px;" src="http://3.bp.blogspot.com/_nw-zNqHeRyc/SVFkWJtT3II/AAAAAAAAADs/jJNwZkc70QM/s400/DSC_0090.JPG" border="0" alt="" id="BLOGGER_PHOTO_ID_5283114169608166530" /></a>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-8042171876169552809.post-41418769552573005982008-12-23T22:59:00.010+01:002010-10-27T16:23:01.823+02:00X-mas cards<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_nw-zNqHeRyc/SVFf0ZgKDUI/AAAAAAAAADM/2LXIHoB3nds/s1600-h/zydzi1.JPG"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 305px; height: 400px;" src="http://3.bp.blogspot.com/_nw-zNqHeRyc/SVFf0ZgKDUI/AAAAAAAAADM/2LXIHoB3nds/s400/zydzi1.JPG" border="0" alt="" id="BLOGGER_PHOTO_ID_5283109191685901634" /></a>
<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_nw-zNqHeRyc/SVFgGmhtttI/AAAAAAAAADU/dTLPaQIFNHg/s1600-h/zydzi2.JPG"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 266px;" src="http://3.bp.blogspot.com/_nw-zNqHeRyc/SVFgGmhtttI/AAAAAAAAADU/dTLPaQIFNHg/s400/zydzi2.JPG" border="0" alt="" id="BLOGGER_PHOTO_ID_5283109504419739346" /></a>
<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_nw-zNqHeRyc/SVFgRrWR_6I/AAAAAAAAADc/uBKg7vtROe4/s1600-h/zydzi1a2.JPG"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 288px; height: 400px;" src="http://3.bp.blogspot.com/_nw-zNqHeRyc/SVFgRrWR_6I/AAAAAAAAADc/uBKg7vtROe4/s400/zydzi1a2.JPG" border="0" alt="" id="BLOGGER_PHOTO_ID_5283109694692523938" /></a>
<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_nw-zNqHeRyc/SVFj3zRxMjI/AAAAAAAAADk/cSHAIuv370g/s1600-h/DSC_0089.JPG"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 266px;" src="http://4.bp.blogspot.com/_nw-zNqHeRyc/SVFj3zRxMjI/AAAAAAAAADk/cSHAIuv370g/s400/DSC_0089.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5283113648190992946" /></a>Unknownnoreply@blogger.com2tag:blogger.com,1999:blog-8042171876169552809.post-19044184411546165532008-12-16T23:21:00.006+01:002010-10-27T16:22:20.419+02:00XML find and replace - xmlsed how to<p>
Sed is a great tool when it comes to string replacement. With simple command like:
</p>
<pre class="code">
$ sed -i -e 's/log4j\.rootLogger=debug/log4j\.rootLogger=warn/' log4j.properties
</pre>
<p>
, it will change appropriate value in <code>log4j.properties</code> file. It is especially useful in automatic scripts which customize configuration.
</p>
<p>
The problem I have encountered lately was connected with using sed for string replacement in xml files. I tried different regular expressions, and multi-line matching, and it was a real pain. I needed a kind of "xmlsed" in fact. Then I realized that even I don't know sed script syntax good enough, I know language which is tailored at manipulation of XML, which is XSLT. :)
</p>
<p>
For example when we have xml log4j configuration like this:
</p>
<pre class="code">
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="console" class="org.apache.log4j.ConsoleAppender">
<param name="Target" value="System.out"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-5p %c{1} - %m%n"/>
</layout>
</appender>
<root>
<priority value ="debug" />
<appender-ref ref="console" />
</root>
</log4j:configuration>
</pre>
We have to prepare appropriate filtering xslt file:
<pre class="code">
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="root/priority/@value">
<xsl:attribute name="value">warn</xsl:attribute>
</xsl:template>
<xsl:template match="@*|*">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="comment()">
<xsl:copy />
</xsl:template>
</xsl:stylesheet>
</pre>
<p>
, and then call:
</p>
<pre class="code">
$ xsltproc -o log4j.xml filter.xsl log4j.xml
</pre>
<p>
The XSLT file could look a bit verbose, but in fact only first template match is specific. The rest will just copy xml from input to output. Using this technique we can also strip some attributes or semantically replace more structured XML fragments. And all of this without removing XML comments.
</p>
<p>
The only drawback is that <code>DOCTYPE</code> will not be preserved.
</p>
<p>
If you want to match specific attribute value:
</p>
<pre class="code">
<xsl:template match="Connector/@port[.='8080']">
<xsl:attribute name="port">8180</xsl:attribute>
</xsl:template>
</pre>Unknownnoreply@blogger.com1tag:blogger.com,1999:blog-8042171876169552809.post-14543113030464758222008-11-29T12:16:00.012+01:002010-10-27T16:22:20.420+02:00Nexus on debian<p>
<a href="http://nexus.sonatype.org/">Nexus</a> is very cool Maven Repository Manager, and <a href="http://www.debian.org">debian</a> is as cool server OS platform. I tried to match them. There was some pain, however finally I succeeded :).
</p>
<p>
<a href="http://nexus.sonatype.org/">Nexus</a> is bundled as war now, thus the description is about installing it on <a href="http://tomcat.apache.org/">tomcat</a>.
</p>
<p>
In case of using debian etch (current stable), you may consider installing jdk 1.6 from <a href="http://www.backports.org/">backports</a>. With jdk 1.6 you have to specify new <code>JAVA_HOME=/usr/lib/jvm/java-6-sun</code> in <code>/etc/default/tomcat5.5</code>.
</p>
<p>
Debian's <a href="http://tomcat.apache.org/">tomcat</a> has security manager turned on by default. Of course it could be easily disabled in <code>/etc/default/tomcat5.5</code>, however I feel safer when it is turned on :). Establishing security policy is not easy. My solution to the problem is based on work described in Mark Petrovic's <a href="http://www.onjava.com/pub/a/onjava/2007/01/03/discovering-java-security-requirements.html">article</a>. I tweaked it a bit not to generate redundant rules. In case of nexus the resulting file looks as follows:
</p>
<pre class="code">
grant codeBase "file:${catalina.home}/bin/tomcat-juli.jar" {
permission java.io.FilePermission "${catalina.base}/webapps/nexus/WEB-INF/classes/logging.properties", "read";
};
grant codeBase "file:${catalina.base}/webapps/nexus/WEB-INF/lib/-" {
permission java.util.PropertyPermission "*", "read,write";
permission java.io.FilePermission "/", "read";
permission java.io.FilePermission "${catalina.base}/logs", "read";
permission java.io.FilePermission "${catalina.base}/webapps/nexus/localhost/nexus/WEB-INF/plexus.properties", "read";
permission java.io.FilePermission "${catalina.base}/webapps/nexus/localhost/nexus/WEB-INF/plexus.xml", "read";
permission java.io.FilePermission "${catalina.base}/webapps/nexus/WEB-INF/log4j.properties", "read";
permission java.io.FilePermission "${catalina.base}/temp", "read,write";
permission java.io.FilePermission "${catalina.base}/temp/-", "read,write,delete";
permission java.lang.RuntimePermission "defineClassInPackage.java.lang", "";
permission java.lang.RuntimePermission "createClassLoader", "";
permission java.lang.RuntimePermission "setContextClassLoader", "";
permission java.lang.RuntimePermission "accessDeclaredMembers", "";
permission java.lang.RuntimePermission "getenv.*", "";
permission java.lang.RuntimePermission "accessClassInPackage.sun.misc", "";
permission java.lang.RuntimePermission "accessClassInPackage.sun.reflect", "";
permission java.lang.RuntimePermission "reflectionFactoryAccess", "";
permission java.lang.RuntimePermission "getClassLoader", "";
permission java.lang.RuntimePermission "modifyThread", "";
permission java.io.FilePermission "${catalina.home}/sonatype-work", "read,write";
permission java.io.FilePermission "${catalina.home}/sonatype-work/-", "read,write,delete";
permission java.net.SocketPermission "*", "connect,resolve";
permission java.lang.reflect.ReflectPermission "suppressAccessChecks", "";
permission java.util.logging.LoggingPermission "control", "";
};
grant codeBase "file:${catalina.base}/webapps/nexus/WEB-INF/classes/-" {
permission java.util.PropertyPermission "*", "read,write";
permission java.io.FilePermission "${catalina.base}/webapps/nexus/localhost/nexus/WEB-INF/plexus.properties", "read";
permission java.io.FilePermission "${catalina.base}/webapps/nexus/localhost/nexus/WEB-INF/plexus.xml", "read";
permission java.io.FilePermission "${catalina.base}/webapps/nexus/WEB-INF/log4j.properties", "read";
permission java.io.FilePermission "${catalina.home}/sonatype-work", "read,write";
permission java.io.FilePermission "${catalina.home}/sonatype-work/-", "read,write,delete";
permission java.lang.RuntimePermission "getenv.*", "";
permission java.lang.RuntimePermission "defineClassInPackage.java.lang", "";
permission java.lang.RuntimePermission "createClassLoader", "";
permission java.lang.RuntimePermission "setContextClassLoader", "";
permission java.lang.RuntimePermission "accessDeclaredMembers", "";
permission java.lang.RuntimePermission "modifyThread", "";
permission java.util.logging.LoggingPermission "control", "";
};
</pre>
<p>
Copy these rules into <code>60nexus.policy</code> file and place it in <code>/etc/default/tomcat5.5</code>. Restart of JVM is required to make these rules effective.
</p>
<p>
The line:
</p>
</p>
<pre class="code">
permission java.io.FilePermission "/", "read";
</pre>
<p>
is redundant with other rules. The need of reading the whole filesystem seems to be a security flaw. I hope it will be eliminated in future nexus releases. I will fill the bug for this.
</p>
<p>
These security rules should work ok not only on debian, but also on any other system where tomcat is deployed. There are two system properties in use: <code>catalina.home</code> and <code>catalina.base</code>. This seems to be debian specific. In case of other systems <code>catalina.home</code> should be enough.
</p>
<p>
Nexus would create <code>sonatype-work</code> directory in <code>user.home</code> which is <code>/usr/share/tomcat5.5</code> in case of debian. However with security manager we have to create it by ourselves.
</p>
<pre class="code">
host# mkdir /var/opt/sonatype-work
host# chown tomcat55:adm /var/opt/sonatype-work
host# ln -s /var/opt/sonatype-work /usr/share/tomcat5.5
</pre>
<p>
The <code>/var/opt/sonatype-work</code> will become storage which should be backed up carefully when nexus is used not only as proxy, but also as local maven repository.
</p>
<p>
Now we can download the latest nexus from <a href="http://nexus.sonatype.org/using/download.html">http://nexus.sonatype.org/using/download.html</a>
</p>
<p>
Create <code>logging.properties</code> file with the following contents:
</p>
<pre class="code">
org.apache.juli.FileHandler.level = WARNING
java.util.logging.ConsoleHandler.level = WARNING
</pre>
<p>
and put it into <code>WEB-INF/classes</code> inside the war.
</p>
<p>
Without this modification nexus would log every single HTTP request on console which would be redirected to <code>catalina.out</code> log file. To much verbose default logging seems to be another nexus bug.
</p>
<p>
Strip the version number from war file, stop tomcat with:
</p>
<pre class="code">
host# /etc/init.d/tomcat5.5 stop
</pre>
<p>
Put nexus.war in <cod>/var/lib/tomcat5.5/webapps</code>.
</p>
<pre class="code">
host# /etc/init.d/tomcat5.5 start
</pre>
<p>
Nexus should be visible at <code>http://debianhost:8180/nexus/</code>
</p>
<p>
Upgradges should be as easy as putting new nexus war in webapps.
</p>Unknownnoreply@blogger.com1tag:blogger.com,1999:blog-8042171876169552809.post-82502353927448697552008-09-13T14:55:00.005+02:002010-10-27T16:22:20.421+02:00GWT Module DTD<p>
GWT modules are defined in special XML format. Developer of a new module has to maintain such file as well as module's java source code. Documentation of the GWT project <a href="http://code.google.com/webtoolkit/documentation/com.google.gwt.doc.DeveloperGuide.Fundamentals.html#ModuleXml">explains each option</a> which can be put in module descriptor, however one thing is missing there - reference to XML Schema or DTD.
</p>
<p>
Appropriate DTD has been <a href="http://code.google.com/p/google-web-toolkit/issues/detail?id=1484">submitted some time ago</a>, and you can find it <a href="http://code.google.com/p/google-web-toolkit/source/browse/trunk/distro-source/core/src/gwt-module.dtd">here</a>. In order to use it in your own modules just add this DOCTYPE to your module xml file :
</p>
<pre class="code">
<!DOCTYPE module SYSTEM "http://google-web-toolkit.googlecode.com/svn/releases/1.5/distro-source/core/src/gwt-module.dtd">
</pre>
<p>Unknownnoreply@blogger.com3tag:blogger.com,1999:blog-8042171876169552809.post-11816285216133361042008-07-13T22:39:00.014+02:002010-10-27T16:22:20.422+02:00Finding duplicates in array of integer numbers<p>
Some time ago I spotted <a href="http://mojstartup.pl/index.php/2008/06/19/praca-dla-programisty/">job offer (polish)</a> posted by a friend of mine. Marek initiated a start up company and now is looking for a new member of his team. The offer is very interesting because it contains a kind of "applicant sieve". :)
</p>
<p>
There is a task to do for a person who wants to apply - algorithm implemented in any language which solves the following problem:
</p>
<blockquote>
Having integer numbers array of size N which contains values from range 1 to N, find if there are any duplicated values.
</blockquote>
<p>
The problem is quite interesting because there are many possible solutions of different properties. Though I am not looking for a new job, I tried to solve the problem. Simple solutions are quite obvious, others which could be called "optimal" become much more complicated. When taking some restrictions into account like O(n) computational complexity, O(1) memory consumption and so on, the solution becomes strightforward. I wonder if it is possible to write an algorithm which will take all restrictions into account and will treat the input array as read-only structure. I tried to implement it, but I failed. :(
</p>
<p>
In order to achieve the goal I started with testing code. Having some different algorithms I decided to compare their "real life" effectiveness. As you probably know microbenchmarking is loosely connected with real life. :) Anyway writhing them is a good fun. I decided to put everything as open source project called <a href="http://code.google.com/p/finding-duplicates/">finding-duplicates</a>. I hope Marek won't be angry - the project is spoiling his offer. :) The task was posted some time ago, I hope he has employed someone already. I am quite surprised by the <a href="http://jlaskowski.blogspot.com/2008/07/netbeans-ide-65m1-dostpny-i.html">reactions</a> this offer has caused when mentioned on <a href="http://www.jaceklaskowski.pl/">Jacek Laskowski</a>'s blog. This is the reason I hope that some people could be interested in my project. I hope that all this buzz will sooner or later bring Marek more candidates. :)
</p>
<p>
If you have more "optimal" solution then one collected <a href="http://code.google.com/p/finding-duplicates/source/browse/trunk/finding-duplicates/src/main/java/com/xemantic/duplicates/Algorithms.java">here</a>, just send it to me, or better drop me a line and I will make you a member of this project. I wonder if I have collected all the possible categories of solutions. Special thantks to <a href="http://adamwozniak.blogspot.com/">Adam Woźniak</a> for his implementation. :)
</p>
<p>
With one additional assumption - array elements are less then N - it would be possible to use algorithm described <a href="http://domino.research.ibm.com/Comm/wwwr_ponder.nsf/solutions/January2004.html">here</a>, and <a href="http://aperiodic.net/phil/archives/Geekery/find-duplicate-elements.html">here</a>. Probably it could be somehow adapted to Marek's problem. For example by adding "virtual" last element to the array. It should has the value less then N (it could be even random number) if we find duplicate and its value is the same as the last element value, then one more pass through the array would be required. Any ideas?
</p>Unknownnoreply@blogger.com3tag:blogger.com,1999:blog-8042171876169552809.post-27684569797264300432008-06-26T23:20:00.004+02:002010-10-27T16:22:20.424+02:00Maven Integration for Eclipse and ClassNotFound exception<p>
I have been using <a href="http://m2eclipse.codehaus.org/">Maven Integration for Eclipse</a> plugin for some time and I am very fond of it. It is awesome. I imagine there is no a single solution to the problem of bridging two java project meta-descriptors - maven's represented by <code>pom.xml</code> and eclipse's represented by artifacts like <code>.classpath</code> and <code>.project</code>. The way it is implemented in this plugin is just awesome.
</p>
<p>
There was only one problem I have encountered while using m2eclipse plugin. After upgrade to <code>0.9.4</code> release, my eclipse-maven projects stopped working with <code>ClassNotFound</code> exception when being run from eclipse as whether Applications or JUnit tests. It was caused by a change introduced in default eclipse output folders for maven projects. It use to be <code>target-eclipse/classes</code> and is <code>target/classes</code> now - just like standard maven output directory. There is a <a href="http://docs.codehaus.org/display/M2ECLIPSE/Separate+Eclipse+and+Maven+output+folders">rationale</a> behind this change.
</p>
<p>
In order to fix the problem just select a project and choose <strong>Maven > Update Project Configuration</strong> from context menu. I've spent some time trying to understand what is going on - probably some kind of warning should be shown in case of projects with legacy paths. I hope this entry could help someone having similar problem.
</p>
<p>
m2eclipse plugin is on a <a href="http://www.eclipse.org/m2e/">good way</a> to become a project under eclipse umbrella, great.
</p>Unknownnoreply@blogger.com12tag:blogger.com,1999:blog-8042171876169552809.post-21067876453113160252008-06-18T11:00:00.001+02:002010-10-27T16:22:20.425+02:00Eclipse Ganymede - rejoicing in virility<h4>Origins of the meme</h4>
<p>
The phrase "rejoicing in virility" is translated etymology of term <em>ganymede</em>. <a href="http://en.wikipedia.org/wiki/Ganymede_(mythology)">Ganymedes</a> was the most handsome among mortals - a mythical hero of ancient Greek cluture.
</p>
<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://upload.wikimedia.org/wikipedia/commons/thumb/3/31/Bust_Ganymede_Louvre_Ma535.jpg/397px-Bust_Ganymede_Louvre_Ma535.jpg"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px;" src="http://upload.wikimedia.org/wikipedia/commons/thumb/3/31/Bust_Ganymede_Louvre_Ma535.jpg/397px-Bust_Ganymede_Louvre_Ma535.jpg" border="0" alt="" /></a>
<p>
Term <em>ganymede</em> is associated with some <a href="http://en.wikipedia.org/wiki/Meme">memes</a> - probably quite selfish ones. As long as they are referred in this post and as they are understood by readers of this post I assume the last statement being proved. :) In evolution of culture some old memes die, some other are born, some other gain a new life.
</p>
<p>
Memes of ancient Greek culture often influence birth of new memes and then persist somehow within new ideas. Soon after <a href="http://en.wikipedia.org/wiki/Galileo_Galilei">Galileo</a> discovered moons of Jupiter, one of them was named <a >Ganymede</a>.
</p>
<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://upload.wikimedia.org/wikipedia/en/2/2e/Ganymede_g1_true.jpg"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px;" src="http://upload.wikimedia.org/wikipedia/en/2/2e/Ganymede_g1_true.jpg" border="0" alt="" /></a>
<p>
A new meme associated with term <em>Ganymede</em> has been born recently. I suppose it's life will be relatively short (about year), although very intensive. For sure it will cause creation of new memes.
</p>
<p>
If I was asked some time ago what <em>eclipse</em> is, I would not have much problem with the answer - another Java IDE. Now eclipse is much more. We can call it a <em>platform</em> for hosting different development components. Every day connotations of the term <em>eclipse</em> grow like branches of a big tree.
</p>
<p>
As <em>eclipse</em> is astronomical term, the <em>ganymede</em> used for naming software follows this convention. If I was asked what this <a href="http://www.eclipse.org/projects/ganymede.php">Ganymede</a> is I would say: it is an attempt to steer some specific evolutionary process associated with software development. An attempt to stop this evolution for a while. An attempt to match different software projects in the shape they interoperate the best. There is a reason the platform is called <em>ecosystem</em>.
</p>
<p>
It is not the first time that <a href="http://www.eclipse.org/">Eclipse Foundation</a> freezes the evolution at some specific stage. It is called "simultaneous releases" and so far we had two previous releases of this kind also named after moons of Jupiter - Calisto and Europa.
</p>
<p>
This introduction was long and boring. :) What really interest me as [not-so-]pragmatic programmer, and probably interests you who is reading this post right now, is a comparison between Ganymede and Europa.
</p>
<h4>Downloading</h4>
<p>
Ganymede could be downloaded from a <a href="http://www.eclipse.org/downloads/packages/">new site</a>. What is nice here - special link for downloading Linux AMD64 version. Finding proper version for this platform was a pain in the past. I have downloaded Mac OS X version numbered as RC3.
</p>
<h4>Launching</h4>
<p>
I have checked that the Mac OS X version comes with <code>eclipse.ini</code> file adjusted for more realistic usage scenario
</p>
<pre class="code">
-Xms40m
-Xmx512m
-XX:MaxPermSize=256m
</pre>
<p>
Good, I won't have to tweak it by hand. It was probably fixed also in the latest Europa bundles, but for sure not in the initial ones.
</p>
<p>
During eclipse start I spotted new splash screen, quite interesting to see what else could be arranged with the same conceptual graphical elements and the same color scheme.
</p>
<p>
My workspace seems to be upgraded quite smoothly. From the first sight I cannot see anything new in eclipse appearance. Although generally being liberal I tend to be conservative on some topics. One of them is look and behavior of tools I am using and I got use to. It is not about software only. It could be about hammer or screwdriver, any extension of human body or human mind. :)
</p>
<h4>Installing plugins</h4>
<p>
Although version <strong>Eclipse IDE for Java EE Developers</strong> provides quite comprehensive development environment there are still some missing futures I use on day to day basis.
</p>
<p>
Installation of eclipse plugins has been completely redesigned. Now it is simpler and clearer and works without much ambiguity as it use to be. New option of <strong>Automatic Updates</strong> was added to general eclipse preferences, nice. However there seems to be some software update related bug in <code>RC3</code>, eclipse is trying to install the same upgrades forever. Fortunately when I came back to eclipse.org there was <code>RC4</code> release available which upgrades without any problem.
</p>
<p>
I see only one drawback comparing to previous <strong>Software Updates</strong> functionality. Selecting plugin to install will not show brief description. The description could be find in <strong>General Information</strong> after right clicking and choosing <strong>Properties</strong>.
</p>
<p>
Ganymede comes with dozens of new features comparing to Europa. Some of them I have been using already however specifying <strong>Update Site</strong> manually. Now these releases are synchronized available from predefined sources. I will just name things important to me:
</p>
<ul>
<li>Remot System Explorer (included by default in Java EE bundle)</li>
<li>SVN Team Provider</li>
<li>Usage Data Collector (included by default)</li>
</ul>
<p>
The last feature is quite interesting:
</p>
<blockquote>
<p>
The Usage Data Collector collects information
about how individuals are using the Eclipse platform. This
information is periodically uploaded to servers hosted by
The Eclipse Foundation (though this is configurable). The intent
is to use this data to help committers and organizations better
understand how developers are using Eclipse.
<p>
<p>
Target Users of the Data:
</p>
<ul>
<li>Users of Eclipse</li>
<li>Committers working on Eclipse projects</li>
<li>ISVs and organization creating Eclipse based software</li>
<li>Enterprise IT departments that make extensive use of Eclipse
Foundation</li>
<li>Academic researchers that want to study how developer work
Data to Be Collected</li>
</ul>
<p>
Captured data is associated with a user through a combination
of workstation and workspace ids that are automatically generated
by the collector. This identification is not tied to any personal
information about the user.
</p>
<p>
The usage data monitors:
</p>
<ul>
<li>Start up and shutdown times of a workspace
<li>What is being used and when (timestamp), including
<ol>
<li>Loaded bundles</li>
<li>Commands accessed via keyboard shortcuts</li>
<li>Actions invoked via menus or toolbars</li>
<li>Perspective changes</li>
<li>View usage</li>
<li>Editor usage </li>
</ol>
</li>
</ul>
<p>
Where possible, the usage data collector also capture the symbolic
name and version of the bundle contributing the command/action/perspective/view/editor.
</p>
</blockquote>
<p>
This functionality reminds me <a href="http://popcon.debian.org/">Debian Popularity Contents</a>. Did I say something about evolution. It is definitely a kind of convergence.
</p>
<p>
Subversive plugin is now part of the distribution. Unfortunately it still depends on connectors provided by <a href="www.poartion.org">Polarion</a>. I added:
</p>
<pre class="code">
http://www.polarion.org/projects/subversive/download/eclipse/2.0/update-site/
</pre>
<p>
to my Update Sites, nice feature here (or rather lack of annoyance :) ) - I am not longer forced to provide <code>Site Name</code> - just URL.
</p>
<p>
I installed <code>SVNKit 1.1.7</code>.
</p>
<p>
Now it is a time for <a href="http://m2eclipse.codehaus.org/">Maven Integration Plugin</a> plugin, I installed:
</p>
<ul>
<li>Maven Integration for Eclipse</li>
<li>Maven POM XML Editor</li>
<li>Maven: The Definitive Guide book</li>
</ul>
<p>
BTW there is a proposal to create <a href="http://www.eclipse.org/proposals/iam/">Eclipse Integration for Apache Maven (IAM)</a> under the umbrella of the Eclipse Foundation, great.
</p>
<p>
I installed additional plugins without any problem:
</p>
<ul>
<li><a href="http://eclipsewiki.sourceforge.net/">EclipseWiki</a> - the latest version is integrated with Eclipse Spellchecker</li>
<li><a href="http://www.java2html.de/">Java2HTML</a> - the plugin is quite old, but works with eclipse 3.4 without any problem</li>
<li><a href="http://directory.apache.org/studio/">Apache Directory Studio</a></li>
</ul>
<p>
And now a little bit about new features I can see from the first sight:
</p>
<h4>New features and other remarks</h4>
<p>
Unfortunately <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=208757">the most annoying bug</a> (at least for Mac OS X users) of the latest Europa updates remains in Ganymede (I suppose it is connected with SWT). :(
</p>
<p>
I can see italics text in case of attributes shown in XML editor, interesting.
</p>
<p>
While browsing available views and perspectives I spotted some interesting things I hadn't tried.
</p>
<ul>
<li>Palette - I suppose it is available to support diagram editin</li>
<li>Snippets - something new</li>
<li>Templates - looks like new interface to the old functionality</li>
<li>TCP/IP Monitor - it is from Debug Perspective, great I hope it will replace external sniffer for debugging networking code</li>
<li>JPA related views</li>
<li>Execution Plan in SQL Development perspective</li>
</ul>
<p>
That's all for now. I hope to write more when I will start using these new features. So far ganymede looks very promising and interesting.
</p>
<h4>Conclusion</h4>
<p>
Valueable memes never die. :) Eclipse Foundation is quite good in <a href="http://www.eclipse.org/ganymede/aroundtheworld.php">spreading own memes</a>. It is very interesting to see what kind of "social engineering" is used in order to attract mass attention for products of open source movement . Firefox is a perfect example with todays <a href="http://www.spreadfirefox.com/en-US/worldrecord/">Download Day 2008</a>.
</p>Unknownnoreply@blogger.com5tag:blogger.com,1999:blog-8042171876169552809.post-17562370710133065762008-06-17T22:49:00.007+02:002010-10-27T16:22:20.426+02:00Calling method of anonymous class<p>
I though that it is an axiom of Java language specification - one cannot call new method defined in anonymous class outside the scope of this class. I was wrong. :)
</p>
<pre class="code">
<span class="java4">public class </span><span class="java10">AnonymousClassMethod </span><span class="java8">{
  </span><span class="java4">public static </span><span class="java9">void </span><span class="java10">main</span><span class="java8">(</span><span class="java10">String</span><span class="java8">[] </span><span class="java10">args</span><span class="java8">) {
    (</span><span class="java4">new </span><span class="java10">Object</span><span class="java8">() {
      </span><span class="java9">void </span><span class="java10">foo</span><span class="java8">() {
        </span><span class="java10">System.out.println</span><span class="java8">(</span><span class="java5">"foo"</span><span class="java8">)</span><span class="java10">;
      </span><span class="java8">}
    })</span><span class="java10">.foo</span><span class="java8">()</span><span class="java10">;
  </span><span class="java8">}
}</span>
</pre>
<p>
This code just prints <code>foo</code>
</p>
<p>
But what is the purpose of such construct. Here is simple example which came to my mind:
</p>
<pre class="code">
<span class="java4">public class </span><span class="java10">Caller </span><span class="java8">{
  </span><span class="java4">public static </span><span class="java9">void </span><span class="java10">main</span><span class="java8">(</span><span class="java10">String</span><span class="java8">[] </span><span class="java10">args</span><span class="java8">) {
    </span><span class="java10">System.out.println</span><span class="java8">((</span><span class="java4">new </span><span class="java10">Subject</span><span class="java8">())</span><span class="java10">.getCallerClass</span><span class="java8">())</span><span class="java10">;
  </span><span class="java8">}
}</span>
</pre>
<pre class="code">
<span class="java4">public class </span><span class="java10">Subject </span><span class="java8">{
  </span><span class="java4">public </span><span class="java10">Class getCallerClass</span><span class="java8">() {
    </span><span class="java4">return </span><span class="java8">(</span><span class="java4">new </span><span class="java10">SecurityManager</span><span class="java8">() {
      </span><span class="java10">Class getCallerClass</span><span class="java8">() {
        </span><span class="java4">return </span><span class="java10">getClassContext</span><span class="java8">()[</span><span class="java7">1</span><span class="java8">]</span><span class="java10">;
      </span><span class="java8">}
    })</span><span class="java10">.getCallerClass</span><span class="java8">()</span><span class="java10">;
  </span><span class="java8">}
}</span>
</pre>
<p>
Crazybob has another <a href="http://crazybob.org/2006/02/you-can-call-method-defined-on.html">example</a>.
</p>Unknownnoreply@blogger.com0