Tuesday, December 17, 2013

Liquibase - implementing custom type.

There are some things to keep in mind while implementing custom type in liquibase. Let's see how to create one.

Existing database types

Well, this might be the biggest advantage of using/hacking the open source projects. You have a chance to see how are things done. This is useful to find your inspiration, the places that require modifications and the hooks to existing system.

Classes worth checking for our purposes are in the package:
liquibase.datatype.core
You can browse them directly on github.

Sample custom BlobType implementation

Let's assume we're about to modify BlobType. Our implementation could look like this:
package liquibase.datatype.core;

import liquibase.database.Database;
import liquibase.database.core.PostgresDatabase;
import liquibase.datatype.DataTypeInfo;
import liquibase.datatype.DatabaseDataType;
import liquibase.datatype.LiquibaseDataType;

@DataTypeInfo(name = "blob", aliases = { "longblob", "longvarbinary", "java.sql.Types.BLOB",
    "java.sql.Types.LONGBLOB", "java.sql.Types.LONGVARBINARY", "java.sql.Types.VARBINARY",
    "varbinary" }, minParameters = 0, maxParameters = 0, priority = LiquibaseDataType.PRIORITY_DATABASE)
public class BlobTypeTest extends BlobType {
  
  public DatabaseDataType toDatabaseDataType(Database database) {
    // handle the specifics here, you can go for the per DB specifics, let's assume Postgres
    if (database instanceof PostgresDatabase) {
       // your custom type here
    }
    // use defaults for all the others
    return super.toDatabaseDataType(database);
  }

}

Specifics to keep in mind

There are some specifics that should be considered:
  • DataType priority is important

    To make sure our type will be considered in favor to default implementation. We're going for:
    priority = LiquibaseDataType.PRIORITY_DATABASE
    
    where the default one (in the supertype) is:
    priority = LiquibaseDataType.PRIORITY_DEFAULT
    
    This just means that our implementation should be considered in favor to default one.

    See method:
    liquibase.datatype.DataTypeFactory.register()
    
    implementation for details.
  • DataType registration considers specific packages to be scanned only

    We have more options here, but our stuff should go to any of these:
    • any of those listed in jar/MANIFEST.MF property:
      Liquibase-Package
      
      Where the default set in the liquibase-core-3.0.8.jar is:
      Liquibase-Package: liquibase.change,liquibase.database,liquibase.parse
       r,liquibase.precondition,liquibase.datatype,liquibase.serializer,liqu
       ibase.sqlgenerator,liquibase.executor,liquibase.snapshot,liquibase.lo
       gging,liquibase.diff,liquibase.structure,liquibase.structurecompare,l
       iquibase.lockservice,liquibase.ext
      
    • comma separated custom package list provided via system property called:
      liquibase.scan.packages
      
    • if all of the above are empty, note the fallback package list is used. As implementation says:
      if (packagesToScan.size() == 0) {
      	addPackageToScan("liquibase.change");
      	addPackageToScan("liquibase.database");
      	addPackageToScan("liquibase.parser");
      	addPackageToScan("liquibase.precondition");
      	addPackageToScan("liquibase.datatype");
      	addPackageToScan("liquibase.serializer");
      	addPackageToScan("liquibase.sqlgenerator");
      	addPackageToScan("liquibase.executor");
      	addPackageToScan("liquibase.snapshot");
      	addPackageToScan("liquibase.logging");
      	addPackageToScan("liquibase.diff");
      	addPackageToScan("liquibase.structure");
      	addPackageToScan("liquibase.structurecompare");
      	addPackageToScan("liquibase.lockservice");
      	addPackageToScan("liquibase.ext");
      }
      

    See method:
    ServiceLocator.setResourceAccessor()
    
    implementation for details.

    Well, as you might have noticed, I'm lazy enough as I went for the already registered package:
    liquibase.datatype.core
    
    so it worked once my implementation is on the classpath.
That should be it.

Debugging ant task

It's allways good idea to debug once playing around with the custom changes in the 3.rd party code.
As I went for ant task, just addopted ANT_OPTS variable. In my case (as I'm on linux) following worked:
export ANT_OPTS="-Xdebug -agentlib:jdwp=transport=dt_socket,server=y,address=8000"
remote debugging was possible afterwards.

To check if custom type is registered, check in the debug session the constructor:
DataTypeFactory.DataTypeFactory()
local variable "classes" contents after line:
classes = ServiceLocator.getInstance().findClasses(LiquibaseDataType.class);
to see all the types found.

That should provide you the basics on liquibase types hacking.

Monday, December 16, 2013

Oracle JDK 1.7.0_u45 incompatibility with Glassfish 3.x (Corba)

Q: Did you give a try to Glassfish 3.1.x with latest stable JDK (1.7.0_u45)?
A: Well, you might be interested in possible trouble there.

After quite some debugging of weird error happening, namely:
Caused by: java.lang.ArrayIndexOutOfBoundsException: -1636631191
at java.util.HashMap.put(HashMap.java:498)
at java.util.HashSet.add(HashSet.java:217)
...
I ended up creating: https://java.net/jira/browse/GLASSFISH-20927 (Btw, it was quite weird, but I'm not allowed to add attachments in their jira :)
The problem seems to be in internals of the HashSet -> HashMap. Where Corba doesn't seem to set the expected reference to EMPTY_TABLE in case of empty Set. Let's see how they proceed with the analysis.

Tuesday, October 22, 2013

My Firefox browsing privacy settings

I decided to go for a bit more privacy for daily browsing. I don't think I need full security (I'm active in social networks anyway, so that would be the 1.st thing to cut), but let's say at least some. I've been influenced of the duckduckgo's donttrack.us and fixtracking.com pages.

I'm running Linux, so for the browser I have 2 mainstream options:
  • Chrome/Chromium
  • Firefox
The Chrome throws
Segmentation fault (core dumped)
at me (on both of my linux machines - Xubuntu/Fedora). Due to lack of motivation I didn't investigate any further (possibly some misbehaving extension). So my options narrow to Firefox only. But that is OK with me. As I'm used to it after some years of usage.

Firefox setup

I'm using duckduckgo.com as my default search engine in both
  • Location bar:
    • To set it, go to page:
      about:config 
      
      and set property:
      keyword.URL 
      
      to:
      https://duckduckgo.com/?q=
      
    and
  • Search bar:
    • To set it click down arrow in the Search bar and choose "Manage Search Engines ..." where move DuckDuckGo to the very top
So I can escape from search + profile association promoting me next day all the stuff I searched for a couple days ago.

Add-ons

Moreover I go for the following add-ons:

Unsecure part

Well there are some specifics in my setup. As mentioned earlier I'm using social networks for posting, and as I'm lazy enough and like posting with minimal effort, I use also ShareThis. However since installing all the previously mentioned, ShareThis stopped working. Following are the tweaks I had to do to enable it again:
  • DoNoTrackMe - I clicked on toolbar icon and then options wheel in the corner, where I disabled "ShareThis" blocking,
  • moreover as Sharethis page rendered on sharing has problems with HTTPs certificate, I had to deactivate it in the - HTTPS Everywhere - as well.
  • Once I'm ready to share site and click Sharethis button in location bar (nothing happens so) I have to go for "Disconnect me" toolbar button and choose "Advertising" category and uncheck "Sharethis". I need to click Sharethis button once again then.
That's it for my setup. I don't think I improved my privacy in a radical way, but let's say I went for options that don't hurt my common browsing experience that much. Some (like ads blocking) make it even more pleasant.

Eclipse toolbar housekeeping

It took me quite some time, since I really started to care about all the wasted space in my IDE of choice - Eclipse IDE. The problem is that toolbar contains elements that I never use. Reasons might differ. Some I don't need, for some I use keyboard shortcuts (that I consider faster to use) for the rest I don't have a clue what they're intended for.

Once I checked the options, motivated by the removal of "Quick access" element eating my toolbar space (since Eclipse Juno version) I've found the stackoverflow post providing even more help than I originally expected.

It correctly pointed me to yet unresolved Eclipse bug, however that was not what I was looking for. Still there were other answers giving me what I came for.

Removing "Quick access" element

As this answer pointed, adding:
#SearchField {
   visibility:hidden;
}
to the:
<ECLIPSE_HOME>/plugins/org.eclipse.platform_<VERSION>/css/e4_basestyle.css
and restarting Eclipse does the job.

Removing toolbar buttons

As the other answer pointed, going for: Window -> Customize Prespective ... I was able to get rid of the buttons (I don't need) in my toolbar.
Please note: this should be done on per perspective basis.

Conclusion

Since applying the mentioned, my toolbar behaves and takes one row of my vertical space only. In fact, it's like half empty :)

Sunday, October 20, 2013

How I left the output redirection to file.

If you feel with linux command line at home, there is often a situation you pipe command outputs. These enable us doing amazing things.

However there are times, when console is not the right place to examine the final output and your favourite editor could do much better job.
In the past I used to output to file and open afterwards, until,... I've noticed it's possible to pipe directly to editor.

Let's assume we're interested in reading tail output in our editor of choice.

Gedit

As my default editor used to be Gedit for quite some time, let's see it in action:
tail -f some.log | gedit
No surprise :), I guess. No extra arguments. Nice!

Morever gedit even provides me with the indicatior (displayed on the tab), that loading is in progress and automatically refreshes contents.

Gvim

I'm in process of transition to gvim usage. I've heard about it's power, never really had a chance to dive deep there. However after watching some vimcasts and reading couple reviews, I'm quite amazed. I'm still trying to memorize the keys for specific tasks (that should be just a question of time and frequency of usage of particular ones).

I made it already my primary editor (wherever I used to use Gedit before).

OK, let's see it in action:
tail -f some.log | gvim -R -
please note -R is not mandatory, but useful, as it indicates file beeing read only.

Kate

I'm not really a KDE guy (these days/years :), but this might be be still be useful for those using kate editor:
tail -f some.log | kate -i 

Bash integration

In the comments of the sites (commandlinefu), where I've found the solution for gvim was one more usecase that caught my attention. Having in the .bashrc following:
function gv() {
  $@ | gvim -R -
}
Enables me doing:
gv tail -f some.log
what makes things even more comfortable. Sure you could replace the function name, as well as the editor with the ones you prefer.

Well, that's it, enjoy (or forget it if you find it useless :) or if interested, share how you achieve it with your editor of choice.

XML processing in shell.

Q: Have you ever been struggling with xml processing in shell?
A: There's an elegant tool: Xmlstarlet (http://xmlstar.sourceforge.net/).

Why would you care?

Well, if you:
  • use the shell environment (bash in my case),
  • have a need for XML data extraction/transformation and
  • you know/are willing to learn XPath/Xslt
then you should. In fact it might be the perfect match.

Download/Installation

Follow the official docs. According to the link, if you're Linux (it's easy as things should be, I guess): "Bundled with your nearest Linux distribution"

Usage

Well, I'd recommend to check the:
man xmlstarlet
and
xmlstarlet --help
I'm going to focus on the one part of the functionality only, namely: data extraction, to see the official help, go for:
xmlstarlet sel
Output is quite impressive, giving you even some examples, for those lazy (like me), I copy/paste here:
XMLStarlet Toolkit: Select from XML document(s)
Usage: xmlstarlet sel <global-options> {<template>} [ <xml-file> ... ]
where
  <global-options> - global options for selecting
  <xml-file> - input XML document file name/uri (stdin is used if missing)
  <template> - template for querying XML document with following syntax:
 
<global-options> are:
  -Q or --quiet             - do not write anything to standard output.
  -C or --comp              - display generated XSLT
  -R or --root              - print root element <xsl-select>
  -T or --text              - output is text (default is XML)
  -I or --indent            - indent output
  -D or --xml-decl          - do not omit xml declaration line
  -B or --noblanks          - remove insignificant spaces from XML tree
  -E or --encode <encoding> - output in the given encoding (utf-8, unicode...)
  -N <name>=<value>         - predefine namespaces (name without 'xmlns:')
                              ex: xsql=urn:oracle-xsql
                              Multiple -N options are allowed.
  --net                     - allow fetch DTDs or entities over network
  --help                    - display help
 
Syntax for templates: -t|--template <options>
where <options>
  -c or --copy-of <xpath>   - print copy of XPATH expression
  -v or --value-of <xpath>  - print value of XPATH expression
  -o or --output <string>   - output string literal
  -n or --nl                - print new line
  -f or --inp-name          - print input file name (or URL)
  -m or --match <xpath>     - match XPATH expression
  --var <name> <value> --break or
  --var <name>=<value>      - declare a variable (referenced by $name)
  -i or --if <test-xpath>   - check condition <xsl:if test="test-xpath">
  --elif <test-xpath>       - check condition if previous conditions failed
  --else                    - check if previous conditions failed
  -e or --elem <name>       - print out element <xsl:element name="name">
  -a or --attr <name>       - add attribute <xsl:attribute name="name">
  -b or --break             - break nesting
  -s or --sort op xpath     - sort in order (used after -m) where
  op is X:Y:Z,
      X is A - for order="ascending"
      X is D - for order="descending"
      Y is N - for data-type="numeric"
      Y is T - for data-type="text"
      Z is U - for case-order="upper-first"
      Z is L - for case-order="lower-first"
 
There can be multiple --match, --copy-of, --value-of, etc options
in a single template. The effect of applying command line templates
can be illustrated with the following XSLT analogue
 
xml sel -t -c "xpath0" -m "xpath1" -m "xpath2" -v "xpath3" 
        -t -m "xpath4" -c "xpath5"
 
is equivalent to applying the following XSLT
 
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
  <xsl:call-template name="t1"/>
  <xsl:call-template name="t2"/>
</xsl:template>
<xsl:template name="t1">
  <xsl:copy-of select="xpath0"/>
  <xsl:for-each select="xpath1">
    <xsl:for-each select="xpath2">
      <xsl:value-of select="xpath3"/>
    </xsl:for-each>
  </xsl:for-each>
</xsl:template>
<xsl:template name="t2">
  <xsl:for-each select="xpath4">
    <xsl:copy-of select="xpath5"/>
  </xsl:for-each>
</xsl:template>
</xsl:stylesheet>
 
XMLStarlet is a command line toolkit to query/edit/check/transform
XML documents (for more information see http://xmlstar.sourceforge.net/)
 
Current implementation uses libxslt from GNOME codebase as XSLT processor
(see http://xmlsoft.org/ for more details)
Please note the switch:
-C or --comp              - display generated XSLT
This can really help if you're struggling on particular problem, to see what's really done in the background.

Let's jump directly to examples.

XmlStarlet in action

Imagine sample xml (copied from http://www.w3schools.com/xml/xml_attributes.asp) called sample.xml:
<messages>
  <note id="501">
    <to>Tove</to>
    <from>Jani</from>
    <heading>Reminder</heading>
    <body>Don't forget me this weekend!</body>
  </note>
  <note id="502">
    <to>Jani</to>
    <from>Tove</from>
    <heading>Re: Reminder</heading>
    <body>I will not</body>
  </note>
</messages>


Element value selection

Let's say, we want to extract all 'from' element values. Using:
xmlstarlet sel -t -m "messages" -m "note" -v "from" < sample.xml
we get:
JaniTove
So what have we done?
  • sel - select data or query XML document
  • -t - template definition
  • -m "messages" - match "messages" XPath expression
  • -m "note" - match "note" XPath expression
  • -v "from" - print value of "from" XPath expression
  • sample.xml - test input file used
Do you want to see the xslt used in the background? No problem, just go for:
xmlstarlet sel -C -t -m "messages" -m "note" -v "from" < sample.xml
to see:
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:exslt="http://exslt.org/common" version="1.0" extension-element-prefixes="exslt">
  <xsl:output omit-xml-declaration="yes" indent="no"/>
  <xsl:template match="/">
    <xsl:for-each select="messages">
      <xsl:for-each select="note">
        <xsl:call-template name="value-of-template">
          <xsl:with-param name="select" select="from"/>
        </xsl:call-template>
      </xsl:for-each>
    </xsl:for-each>
  </xsl:template>
  <xsl:template name="value-of-template">
    <xsl:param name="select"/>
    <xsl:value-of select="$select"/>
    <xsl:for-each select="exslt:node-set($select)[position()&gt;1]">
      <xsl:value-of select="'&#10;'"/>
      <xsl:value-of select="."/>
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>
easy, right?

Selecting xml element

Do you need whole element, not just value? Go for:
xmlstarlet sel -t -m "messages" -m "note" -c "from" < test.xml
to see:
<from>Jani</from><from>Tove</from>
Where only new flag introduced is:
  • -c "from" - print value of "from" XPath expression

Attribute values

Let's end the examples with id-attribute values. Let's assume, we're interested in the note's id attribute values:
xmlstarlet sel -t -m "messages" -m "note" -v "@id" < test.xml
should result in:
501502

Conclusion

XmlStarlet is much more powerful that shown in the examples above.
However my goal was not to show it all (if interested, go for official docs) but rather to show you the tool that can help with xml processing in the shell scripts.
It can save you from quite some unneeded complexity possibly introduced by sed/awk/grep solutions as it respects commented sections, ... and brings the full XPath power to your scripting.

Well, I need to admit, that the tool's development is somewhat stalled. Usually, that's not a good indicator. Still I consider it mature and extremely useful.

Tuesday, September 24, 2013

Energy saving with Raspberry Pi ssh server

I've noticed that after couple days of running my Raspberry Pi server (Raspberry Pi driven Dropbox alternative) I had a problem with connectivity to ssh. Not sure why, but it doesn't really bother me, as I've noticed it only once up to now. Once restarted ssh worked again.

Anyway as I don't need it to be running 24/7 but rather there are couple hours in night, when there is definitely no need to have it up.

Electronic timer switch

As I had a chance to buy electronic timer switch at "Flohmarkt" (in Riem seems to be one of the biggest ones), as it was a good deal I bought 3, where 2 seem to work (still it was worth it). After some googling I've found quite detailed manual (for I guess the British version).

Final setup

I ended up with following:
  • electronic timer switch has been programmed in the way it turns off at 01:00am and goes back on at some time in the morning (depending on weekday or weekend) and
  • cron job has been setup to switch the Raspberry Pi 5 minutes before hard unplug (in my setup are 5 mins enough):
    # m h dom mon dow command
    55 0 * * * /sbin/shutdown -h now
    
That's it. I neither need to worry about hard shutdown (and mess caused to my data) nor about manual startup my ssh server. It's been working fine for couple weeks already for me.

Wednesday, September 4, 2013

Handling file rollover with tail monitoring

The most of us probably already know the command:
tail -f <your_file_to_monitor>
it's useful for monitoring whatever has been appended to the file called <your_file_to_monitor>.

OK, nothing new here (probably). I could not live without it any more I guess, once I got used to it (as it offers me all the power of linux shell - like piping the output to other command, etc.).

The common use case for me is monitoring of the log files created by various java logging frameworks (log4j/sl4j/whatever is used).

Log file rollover problem

Maybe you've noticed that this works, but from time to time, no more messages are printed. Why that happens? You need to restart it to have it running again.

The common problem is the usage of file rollover (for example if file exceeds particular size to be backed up named by specified pattern and logging continues to the empty file named the same as the original one). This is a good practice to prevent log file unlimited growing and keeping some history across application restarts.

But the nice guys doing tail considered this option obviously. If you check the man page it has some switches that can be used for the case. Here are the relevant ones:
--retry
      keep trying to open a file even if it is inaccessible when  tail
      starts  or if it becomes inaccessible later; useful when follow-
      ing by name, i.e., with --follow=name

-f, --follow[={name|descriptor}]
      output appended data as the file grows; -f, --follow, and --fol-
      low=descriptor are equivalent

-F     same as --follow=name --retry
So to have things running even despite of log file rollover, you should go for:
tail -F <your_file_to_monitor>
That's it. Easy right?

Tuesday, September 3, 2013

EJB 3.1 - Local and Remote business interfaces must differ

Have you ever seen something like this?
Exception during lifecycle processing
java.lang.IllegalStateException: The interface XYZ cannot be both a local and a remote business interface
 at com.sun.enterprise.deployment.archivist.Archivist.readAnnotations(Archivist.java:518)
 at com.sun.enterprise.deployment.archivist.Archivist.readAnnotations(Archivist.java:446)
 at com.sun.enterprise.deployment.archivist.Archivist.readRestDeploymentDescriptors(Archivist.java:419)
 at com.sun.enterprise.deployment.archivist.Archivist.readDeploymentDescriptors(Archivist.java:396)
 at com.sun.enterprise.deployment.archivist.Archivist.open(Archivist.java:271)
 at com.sun.enterprise.deployment.archivist.Archivist.open(Archivist.java:280)
 at com.sun.enterprise.deployment.archivist.ApplicationArchivist.readModulesDescriptors(ApplicationArchivist.java:611)
 at com.sun.enterprise.deployment.archivist.ApplicationArchivist.openWith(ApplicationArchivist.java:229)
 at com.sun.enterprise.deployment.archivist.ApplicationFactory.openWith(ApplicationFactory.java:232)
 at org.glassfish.javaee.core.deployment.DolProvider.processDOL(DolProvider.java:188)
 at org.glassfish.javaee.core.deployment.DolProvider.load(DolProvider.java:222)
 at org.glassfish.javaee.core.deployment.DolProvider.load(DolProvider.java:96)
 at com.sun.enterprise.v3.server.ApplicationLifecycle.loadDeployer(ApplicationLifecycle.java:878)
 at com.sun.enterprise.v3.server.ApplicationLifecycle.setupContainerInfos(ApplicationLifecycle.java:818)
 at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:374)
 at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:219)
 at org.glassfish.deployment.admin.DeployCommand.execute(DeployCommand.java:491)
 at com.sun.enterprise.v3.admin.CommandRunnerImpl$2$1.run(CommandRunnerImpl.java:527)
 at com.sun.enterprise.v3.admin.CommandRunnerImpl$2$1.run(CommandRunnerImpl.java:523)
 at java.security.AccessController.doPrivileged(Native Method)
 at javax.security.auth.Subject.doAs(Subject.java:356)
 at com.sun.enterprise.v3.admin.CommandRunnerImpl$2.execute(CommandRunnerImpl.java:522)
 at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:546)
 at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:1423)
 at com.sun.enterprise.v3.admin.CommandRunnerImpl.access$1500(CommandRunnerImpl.java:108)
 at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1762)
 at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1674)
 at org.glassfish.admin.rest.resources.admin.CommandResource.executeCommand(CommandResource.java:396)
 at org.glassfish.admin.rest.resources.admin.CommandResource.execCommandSimpInMultOut(CommandResource.java:234)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
 at java.lang.reflect.Method.invoke(Method.java:606)
 at org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory$1.invoke(ResourceMethodInvocationHandlerFactory.java:81)
 at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:125)
 at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$ResponseOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:152)
 at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:91)
 at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:346)
 at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:341)
 at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:101)
 at org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:224)
 at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271)
 at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267)
 at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
 at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
 at org.glassfish.jersey.internal.Errors.process(Errors.java:267)
 at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:317)
 at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:198)
 at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:946)
 at org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpContainer.service(GrizzlyHttpContainer.java:331)
 at org.glassfish.admin.rest.adapter.JerseyContainerCommandService$3.service(JerseyContainerCommandService.java:165)
 at org.glassfish.admin.rest.adapter.RestAdapter.service(RestAdapter.java:181)
 at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:246)
 at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:191)
 at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:168)
 at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:189)
 at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
 at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:288)
 at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:206)
 at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:136)
 at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:114)
 at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
 at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:838)
 at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:113)
 at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:115)
 at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:55)
 at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:135)
 at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:564)
 at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:544)
 at java.lang.Thread.run(Thread.java:724)
Caused by: The interface XYZ cannot be both a local and a remote business interface
 at org.glassfish.ejb.deployment.annotation.handlers.AbstractEjbHandler.setBusinessAndHomeInterfaces(AbstractEjbHandler.java:471)
 at org.glassfish.ejb.deployment.annotation.handlers.StatelessHandler.setEjbDescriptorInfo(StatelessHandler.java:143)
 at org.glassfish.ejb.deployment.annotation.handlers.AbstractEjbHandler.processAnnotation(AbstractEjbHandler.java:270)
 at com.sun.enterprise.deployment.annotation.factory.SJSASFactory$LazyAnnotationHandler.processAnnotation(SJSASFactory.java:148)
 at org.glassfish.apf.impl.AnnotationProcessorImpl.process(AnnotationProcessorImpl.java:344)
 at org.glassfish.apf.impl.AnnotationProcessorImpl.process(AnnotationProcessorImpl.java:375)
 at org.glassfish.apf.impl.AnnotationProcessorImpl.processAnnotations(AnnotationProcessorImpl.java:289)
 at org.glassfish.apf.impl.AnnotationProcessorImpl.process(AnnotationProcessorImpl.java:195)
 at org.glassfish.apf.impl.AnnotationProcessorImpl.process(AnnotationProcessorImpl.java:134)
 at com.sun.enterprise.deployment.archivist.Archivist.processAnnotations(Archivist.java:626)
 at com.sun.enterprise.deployment.archivist.Archivist.readAnnotations(Archivist.java:462)
 ... 69 more
where XYZ would be the name of the interface referred as Local and Remote from some stateless session bean.

Well, once I did migration to Glassfish 4.0 I've noticed that. The message is quite clear, however the question is why that would be a problem. As having one interface serving as Local as well as Remote for stateless session EJB is quite common practice I think.

Root cause

The JBoss forum message pointed me to the right direction.

The thing is that EJB 3.1 specs (implemented in Glassfish 4.0) section 4.9.7 says:
The same business interface cannot be both a local and a remote business interface of the bean.
For those interested, see the full specs on: http://download.oracle.com/otndocs/jcp/ejb-3.1-fr-eval-oth-JSpec/

Solution

OK, but how to fix it? I recommend you to read Adam Bien's suggestion.

Basically, the idea might be the analogy to package protection present in java and easy solution can be creation of extra interface that would inherit existing one and be used as Local. Possibly having Local suffix.

Monday, September 2, 2013

Is Glassfish 4.0 with Hibernate JPA a dead end?

Glassfish 4.0 with Hibernate JPA stable? Nope, see: https://java.net/jira/browse/GLASSFISH-20716

You need to go for JPA 2.1. But there is no stable release of Hibernate supporting it yet (https://hibernate.atlassian.net/browse/HHH?selectedTab=com.atlassian.jira.plugin.system.project%3aversions-panel&subset=-1)!

Well, what can I say, I was disappointed as well. Unless you do some non-production code, feel free to give it a try with 4.3.0 BetaX. Otherwise, have some rest and cross your fingers for Hibernate guys or look elsewhere.

Thursday, August 22, 2013

Raspberry Pi driven Dropbox alternative

As mentioned earlier I bought Raspberry Pi. After some struggles with the board shipping I finally got it almost one month after my order. Components work as expected. I went for official Debian image installation.

Lately there has been quite some publicity about privacy and security on the the public services hosting data. So I decided to minimize the Dropbox usage for file sync and go for locally hosted solution. It doesn't mean I'm out of dropbox, but rather I use it only for things I need to share outside my LAN.

My synchronization requirements

  • two way sync
  • non-interactive sync
  • sync over ssh/local dirs (as pi works with ssh as a server out of the box)
  • support for star topology - PC1..n (laptops) <-> Server (Raspberry Pi)
  • keep additional dependencies to be installed on Raspberry low
  • enable sync within LAN only (as I have quite some restricted internet connection with respect to data transfer quotas)
  • operating on demand, rather than instantly (I want to use pi for other things as well and it's performance is not too impressive)

Alternative synchronization programs

I checked briefly only following:
  • rsync
  • Unison
    • quite well known,
    • but not actively developed any more, still patches seem to be applied from time to time.
  • ownCloud
    • looks actively developed
    • but compared to other 2 - eats more resources (on both sides, client and server)
To me, the unison looks like a winner. So I went for it.

Unison setup from scratch on Pi

I followed these steps:
  1. [on server] changed default raspberry password via:
    passwd
    
  2. [on clients and the server] set up password-less authentication for ssh connection (following the howtoforge tutorial)
  3. [on clients and the server] installed unison:
    • For Fedora:
      sudo yum install unison
      
    • For (X)ubuntu/Debian:
      sudo apt-get install unison
      
  4. [on clients] setup unison with ssh as a synch protocol (following the howtoforge tutorial) with the custom unison preferences file (see next section for reference).
That was basically it.

Custom setup

I created new unison preferences file:
~/.unison/unison.prf 
that has following contents:
# WATCH OUT: keep in sync across clients!

# dirs
root = /home/pb/unison
root = ssh://pi@192.168.2.109//media/My Book/pi/unison

# Work silently
batch = true

auto=true
times = true

# logging
log = true
logfile = /home/pb/.unison/unison.log

# Prevent deletion of all files if all files are locally deleted
confirmbigdeletes = true

# Check fast, don’t compare bit by bit
fastcheck = true # "the default on Unix systems", see docs

# ignore stuff
ignore = Name *~   ## ignores all files with ~ (gedit backup files)
Then I went for one more step. To synchronize via command line I issue following command on my client machines:
unison -ui text unison
To make my life easier, I created in:
~/.bashrc 
alias:
alias u-u="unison -ui text unison"
So that I can simply initiate the synchronization with:
u-u
That's it for my setup. Please note the paths as well as server IP should be adapted in case you'd be using it.

More info/inspiration

For more information, that I got inspired with, see:

Wednesday, August 14, 2013

tail: inotify resources exhausted

I've been facing issue with tail. Once executing:
tail -f <filename_to_tail>
I got error:
tail: die Inotify-Resourcen sind erschöpft
tail: Inotify kann nicht verwendet werden, es wird auf Pollen zurückgegriffen
For those of you having english locale, you'd see:
tail: inotify resources exhausted
tail: inotify cannot be used, reverting to polling
While looking around I've found following to be valuable in understanding the problem and solving it: So the error itself means that system is getting low on inotify watches, that enable programs to monitor file/dirs changes.

To see the currently set limit (including output on my machine), I executed:
cat /proc/sys/fs/inotify/max_user_watches
8192
Well, I had to decide about the limit. So I went for 1048576 (not sure why :) ). To set it I've found 2 solutions.

Temporary solution (not preserved across restarts)

As I'm used to sudo, I went for:
sudo echo 1048576 > /proc/sys/fs/inotify/max_user_watches
-bash: /proc/sys/fs/inotify/max_user_watches: Keine Berechtigung
OK, not working. Complaining about user rights on /proc/sys/fs/inotify/max_user_watches. Then based on: How do I use sudo to redirect output to a location I don't have permission to write to? I went for:
sudo sh -c 'echo 1048576 > /proc/sys/fs/inotify/max_user_watches'
which worked, as the command proofs:
cat /proc/sys/fs/inotify/max_user_watches
1048576
The problem is that the value is reset each time I rebooted.

Permanent solution (preserved across restarts)

Adding line:
fs.inotify.max_user_watches=1048576
to:
/etc/sysctl.conf
fixed the limit value permanently (even between restarts).

Deeper analysis

However if you're interested to investigate problem in deep, it would be good idea to find out who is using the resources. There seem to be an idea at unix.stackexchange: Who's consuming my inotify resources?.
for foo in /proc/*/fd/*; do readlink -f $foo; done | grep inotify | sort | uniq -c | sort -nr
However for me it didn't show any output I could analyse to dig deep.

On the other hand I convinced myself that Dropbox is guilty here. Even though I have no proof for that (just read on some of the sources where someone suspected the same service).

Friday, August 9, 2013

Setting up Vagrant on Fedora 17

Vagrant claims it can help in setup of virtual environments and make it easy to setup new guests.

However, to play around with that, I need to have Vagrant itself installed.

As I'm on Fedora 17, I went for this guide going through:
  • VirtualBox installation
  • Vagrant installation and sample usage

VirtualBox installation

[FAILED] Plan A (installing the RPMFusion package)


This was supposed to be be easy.
  • Searching for exact package name first
  • sudo yum list virtualbox
    
  • Installing afterwards
  • sudo yum install VirtualBox
    
After the 1.st expected problem (as documented by site I followed):
VBoxManage --version
WARNING: The vboxdrv kernel module is not loaded. Either there is no module
         available for the current kernel (3.9.10-100.fc17.x86_64) or it failed to
         load. Reboot the computer or load the kernel module by executing

           '/etc/sysconfig/modules/VirtualBox.modules' (as root)

         You will not be able to start VMs until this problem is fixed.
4.2.12_RPMFusionr84980
I was not able to resolve it as suggested, with (as I faced other errors):
sudo /etc/sysconfig/modules/VirtualBox.modules
[sudo] password for pb: 
ERROR: Module vboxdrv not found.
ERROR: Module vboxnetflt not found.
ERROR: Module vboxnetadp not found.
OK, well, time to look elsewhere. I found problem similar to my at virtualbox forum, with the reference, that I should go for the official rather than rpmfusion version of the VirtualBox.

As suggested, I did the removal and installation using:
sudo yum remove VirtualBox

[OK] Plan B (installing the official VirtualBox package)


For this one I've found guide here and it worked smoothly. I've decided not to copy paste information present elsewhere I'm reffering to, so feel free to follow the steps and get back here when done. Except that I didn't follow all the steps, but rather once comming to originally failed step:
$ sudo /etc/init.d/vboxdrv setup                                                                                        
[sudo] password for pb: 
Stopping VirtualBox kernel modules                         [  OK  ]
Uninstalling old VirtualBox DKMS kernel modules            [  OK  ]
Trying to register the VirtualBox kernel modules using DKMS[  OK  ]
Starting VirtualBox kernel modules                         [  OK  ]

$ VBoxManage --version
4.2.16r86992
I was done with that (didn't go for separate VirtualBox user setup).

Vagrant installation and sample usage


Let me reffer to original steps I followed, as the rest went smoothly for me.

Afterwards I could establish ssh connection to guest, simply via:
vagrant ssh
Enjoy.

Tuesday, August 6, 2013

JSPWiki text strikethrough howto

How can one do the strikethrough in JSPWiki text?
Imagine following text chunk you need to partially striketrough:

this text is deprecated one this one is not

Combining information from multiple sources:
You might end up with something like this:
%%(text-decoration: line-through;) this text is deprecated one%%  this one is not
and renderred it could look something like this:

this text is deprecated one this one is not

Removing all the tables in the MySQL database

Recently I came into the problem, that I needed to clean up the MySQL database contents (to get rid of all the tables). Normally I'd go for the database drop and creation, but there are situations, where it's not feasible. The common case is that the user that has granted access to particular DB only. Can't create/recreate new one.

So I ended up (heavily inspired by some comments found here) with:
mysql -u <username> --password=<password> <database_name> -BNe "show tables" | awk '{print "drop table " $1 ";"}' | mysql -u <username> --password=<password> <database_name>
If you'd like to prevent having password stored in your shell history (and you're using file: .my.cnf to handle user/pass/database), you should go for much shorter one:
mysql -BNe "show tables" | awk '{print "drop table " $1 ";"}' | mysql
The switches explanation follows:
  • -B --batch - tab delimited output, one line per record / no history
  • -N --skip-column-names - do not write column names in results
As one of the users noted:

There is a very good reason to use show tables and not mysqldump. If you have a large database show tables will offer a superior performance.

Friday, August 2, 2013

simplified posts template

Those of you who have been here before have probably noticed the new look of my blog.
I like it as it brings quite some simplicity, which I consider important for the writer as well as for the readers.

The reason for the change was the fact I got stuck with things I wanted show and dynamic templates on blogger just didn't behave.

Moreover posting code snipplets is quite frequent for me and doing it the way I used to (as suggested in the post: http://peter-butkovic.blogspot.com/2012/06/code-syntax-highlighting-in-blog-posts.html) was just too much complicated.

So welcome to my simplified blog design. Hope you'll enjoy it :)

Wednesday, July 17, 2013

cool centos sudo message

Today, I've seen the cool centos message when using sudo, that made my day :)

We trust you have received the usual lecture from the local System
Administrator. It usually boils down to these three things:

    #1) Respect the privacy of others.
    #2) Think before you type.
    #3) With great power comes great responsibility.

The second point is the one I use to struggle the most with :)

Well, as the general rule is that the audience always affects the way message is to be communicated, you might want to adapt it the way that would make your users cautious. If so, see the way to do that: http://serverfault.com/questions/302941/changing-the-sudo-warning

Monday, July 8, 2013

Raspberry Pi - my new home server for 70 EUR

I'm quite excited, I just ordered the Raspberry Pi.

But wait, you might ask: Excited to buy single core 700MHz CPU in 2013?
If someone would tell me couple years ago, I wouldn't believe, I guess :)
Nevertheless I see the use case for my small home server running Raspberry Pi.

I'll document what has been achieved, rather than summing up my dreams, so for today, I'll stick with the HW components I went for.

I decided to document my setup as things can vary in:
  • additional components you might need, as well as
  • country/shop you buy at.
The primary intent is to keep things summed up for me. But you might still find the information useful.

Components

The board itself is one thing, however having all the other components required is something different. So after some research I ended up with the following setup:
  • Raspberry Pi board itself
  • USB keyboard + mouse
  • as the previous 2 would occupy both of available USB ports, I need USB HUB
  • SD card
  • USB Wifi adapter - as I need to connect to my Wifi Router and no I don't want any new hole in the wall :)
  • monitor (well this one as well as keyboard and mouse) might won't be plugged permanently, if running as server (ssh should do the job), but still I need it
  • power supply
  • some box?
  • hope I didn't forget anything important :)
OK out of all these I have power supply, keyboard, monitor and mouse already, so let's go for the rest. And box? Lego should do the job for me (if my daughter borrows me some pieces :)

My order

I'm ordering in the Germany, but didn't really compare with other coutries. I've found all the shops for the components I need on the amazon.de with quite OK prices.

For the decision making I followed the rule of:
  • the lowest price as well as 
  • component compatibility and of course
  • shipping costs matter.
Following is my configuration of choice:
  1. Raspberry Pi Mod. B Rev 2.0 (512 MB RAM) 
  2. Transcend SDHC 32GB Class 10 
  3. Mini Highspeed 4-Port USB 2.0 Hub 
  4. TP-Link TL-WN725N Wireless N Nano USB-Adapter 
OK so my very new Raspberry Pi related costs up to now are: 70,23 EUR

Now I just need to be patient till all the components arrive and if all works as expected.
I'll keep you updated.

ShellEd - perfect shell scripts dev environment in Eclipse

Q: Are you in love with Eclipse and need to write shell scripts?
A: Go for the ShellEd (http://sourceforge.net/apps/trac/shelled/).

You'd gain:
  • syntax highlighting,
  • code folding,
  • outline view,
  • man pages displayed directly from editor,
  • possibility to run directly from Eclipse and
  • all the "common" Eclipse features.
To get the impression, see the screenshot (from official documentation):
 


For installation and setup, see the official user guide.

Wednesday, June 26, 2013

graphical UI for alternatives command on linux

Q: Do you need a UI for alternatives command?
A: Go for galternatives.

On linux is the alternatives command very powerful. Especially if you're in the world of java and need to live with multiple versions and possibly switch between them.

However I've found myself confused a bit by running the console commands.

While struggling with one of my issues I came across (http://forums.fedoraforum.org/showthread.php?t=241304) the UI for alternatives command called galternatives.

Installation


on Fedora was simple, as expected:
sudo yum install galternatives

Usage


Once you're familiar with alternatives concept and see the UI, there is not too much to explain any further I believe.

Making notify-send work on Fedora 17 + Xfce.

Q: Is not notify-send command working for you on Fedora 17 with Xfce?
A: You need to install required packages.

In my case:
sudo yum install xfce4-notifyd notification-daemon libnotify
did the job.

Where if you don't have xfce4-notifyd installed, command will execute without error, but no notification will be shown.

Now you can enjoy notifications like this one:
notify-send it\'s\ alive!
For inspirational sample messages, see: http://www.thegeekstuff.com/2010/12/ubuntu-notify-send/

Sunday, June 9, 2013

Less known handy eclipse IDE plugins.

Eclipse IDE is one of the most favorite IDEs available these days for Java.

People might prefer others (Netbeans, InteliJ Idea,...), but for me it's the IDE of choice for some years already. The point of this post is not to do any comparison with others however.

The core technology used in Eclipse is OSGI, that makes it easily extensible. There are plenty of plugins out there, some are well known, however there might be some you've never heard of, but might find them useful, once you see them in action.

I've decided, it's a time for the first mini series in my blog posts.

Let's start with the plugin I've found already quite some time ago... (thanks to my former colleague)

JAutoDoc (http://jautodoc.sourceforge.net/)

Commenting the source code in a right way is beneficial to whoever using/reading it.

I've seen/read various opinions on code comments. Some where going to extremes, but I basically agree with the one, that all of the API should have comments. In java world it means JavaDocs for the Classes/methods/fields/... should be present.

Of course, if the class design is nice object oriented and understandable, it's easier for others to understand it as well as for the programmer to write the JavaDocs for it.

But if you try to achieve 100% documented API there might be fields, or methods having names descriptive enough so that functionality/idea behind them is clear just by name. For the cases like these, it might be handy to have automated solution. Moreover if you're not happy with Eclipse auto generated javadocs but would still like to use generation for core comments manually providing only fields/method/... specifics, my recommendation is to give JAutoDoc a try.

Installation

As the first thing, we need to install it to eclipse. In my case, I went for update site:
http://jautodoc.sourceforge.net/update/

Test example


Once installation was complete, I restarted eclipse and created sample java project.

Let's assume, we have the class like this:
public class Person {
 private String firstName;
 private String middleName;
 private String surname;
}
Meaning of all the fields is more-less clear. Let's see what JAutoDoc can do for us and compare it with default eclipse generated comments.

Keyboard shortcuts

But at first as I'm a big fan of keyboard shortcuts let's list the relevant ones. The default ones for generating comments on particular element:
  • the Eclipse one: Alt+Shift+J
  • the JAutoDoc one: Alt+Ctrl+J
That is nice, because we can choose the one we like depending on the case.

And ... action

Eclipse generated JavaDocs:
/**
 * @author 
 *
 */
public class Person {
 /**
  * 
  */
 private String firstName;
 /**
  * 
  */
 private String middleName;
 /**
  * 
  */
 private String surname;
JAutoDoc generated JavaDocs:
// TODO: Auto-generated Javadoc
/**
 * The Class Person.
 */
public class Person {
 
 /** The first name. */
 private String firstName;
 
 /** The middle name. */
 private String middleName;
 
 /** The surname. */
 private String surname;
 
}
Well, I'd say, that it can speed up things, and for the case the comments look nice without a need for later editing.

To make our life even simpler, JAutoDocs enables us to generate comments on all the sellected elements, so if you don't want to go over each and every field and generate is separatelly just select all in editor and push the keyboard shortcut. 

Getters/setters case

Let's check what getters/setters case comments look like.

In Eclipse:
  • right clicking and going for Source -> Generate getters and setters 
  • afterwards, selecing all the fields and checking Generate method comments leaves us with the contents
/**
 * @author 
 *
 */
public class Person {
 /**
  * 
  */
 private String firstName;
 /**
  * 
  */
 private String middleName;
 /**
  * 
  */
 private String surname;

 /**
  * @return the firstName
  */
 public String getFirstName() {
  return firstName;
 }
 /**
  * @param firstName the firstName to set
  */
 public void setFirstName(String firstName) {
  this.firstName = firstName;
 }
 /**
  * @return the middleName
  */
 public String getMiddleName() {
  return middleName;
 }
 /**
  * @param middleName the middleName to set
  */
 public void setMiddleName(String middleName) {
  this.middleName = middleName;
 }
 /**
  * @return the surname
  */
 public String getSurname() {
  return surname;
 }
 /**
  * @param surname the surname to set
  */
 public void setSurname(String surname) {
  this.surname = surname;
 }
}
Now let's see what the comments would look like when generated JAutoDoc way:

// TODO: Auto-generated Javadoc
/**
 * The Class Person.
 */
public class Person {
 
 /** The first name. */
 private String firstName;
 
 /** The middle name. */
 private String middleName;
 
 /** The surname. */
 private String surname;

 /**
  * Gets the first name.
  *
  * @return the first name
  */
 public String getFirstName() {
  return firstName;
 }
 
 /**
  * Sets the first name.
  *
  * @param firstName the new first name
  */
 public void setFirstName(String firstName) {
  this.firstName = firstName;
 }
 
 /**
  * Gets the middle name.
  *
  * @return the middle name
  */
 public String getMiddleName() {
  return middleName;
 }
 
 /**
  * Sets the middle name.
  *
  * @param middleName the new middle name
  */
 public void setMiddleName(String middleName) {
  this.middleName = middleName;
 }
 
 /**
  * Gets the surname.
  *
  * @return the surname
  */
 public String getSurname() {
  return surname;
 }
 
 /**
  * Sets the surname.
  *
  * @param surname the new surname
  */
 public void setSurname(String surname) {
  this.surname = surname;
 }
}
OK, that is much nicer, I'd say.

Up to now, we just scratched the surface with examples. But as you can see, I'm the guy lazy enough to have stuff auto-generated. So you can't expect me to think of some more complicated example, I guess.

Anyway, if you're interested in more real world scenarios, possibly your project, there is no better thing as giving it a try and making up your mind.

To be honest I was really surprised once I've seen it in real world apps used.

More info

If interested, the full list of features can be found on the official web site: http://jautodoc.sourceforge.net/index.html

To have an idea, following are the plugin options available:

I'm looking forward for the next post in the series. Feel free to suggest the plugins you find useful in your daily work (otherwise I'll stick with my preferred list only).

Saturday, May 25, 2013

debugging fornax-oaw-m2-plugin maven plugin

Question: Do you need to debug maven plugin: fornax-oaw-m2-plugin ?
If so, go on reading.

You can find the basic info at their home page:
However remote debugging topic is not covered there.
The problem with maven plugins might be, that sometimes it's not enough to debug maven run itself (as described in my previous post).

However merging information from the previous links with common remote debugging options I came to solution that simply works for me:

<build>
  <plugins>
    <plugin>
      <groupId>org.fornax.toolsupport</groupId>
      <artifactId>fornax-oaw-m2-plugin</artifactId>
      <version>2.1.1</version>
      <type>pom</type>
      <configuration>
        <!-- [BEGIN] debugging related section -->
        <jvmSettings>
          <jvmArgs>
            <jvmArg>-Xdebug</jvmArg>
            <jvmArg>-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8100</jvmArg>
            <jvmArg>-Xnoagent</jvmArg>
            <jvmArg>-Djava.compiler=NONE</jvmArg>
          </jvmArgs>
        </jvmSettings>
        <!-- [END] debugging related section -->
      </configuration>
      <executions>
        <execution>
          <phase>generate-sources</phase>
          <goals>
            <goal>run-workflow</goal>
          </goals>
        </execution>
      </executions>
    </plugin>
  </plugins>
</build>
Please note that port to remotely connect to with debugger is 8100 in my sample. Feel free to adapt it based on your setup.

After using the configuration in your run, you should get to point where plugin run gets suspended and waits for remote debugger to connect (to find out how to remotelly debug, see some existing tutorial, like this one: http://java.dzone.com/articles/how-debug-remote-java-applicat).

That's it. Enjoy your debugging session.

This post is from pb's blog.

Friday, May 3, 2013

Keyboard shortcut (Ctrl+Space) caught in Xfce

Q: Did you ever face the problem of keyboard shortcut Ctrl+Space not working in Xfce?

This will be another one of my keyboard shortcut troubleshooting posts when living daily in Xfce (previous one can be found here).

My primary IDE is Eclipse, therefor Ctrl+Space is something I need like a salt. While coding I use it for code completion intensively.

However some months ago it stopped working for me. Stackoverflow ideas didn't help. So I gave up. As one of my favorite songs says: "Never know what you got till it's gone".

But couple days ago, I've observed, when pushing this combination accidentally twice in a row I got keyboard switch dialog.

While looking around, I've found IBus applet in my xfce panel (not sure how it got there :) ). When going for it's options, I've found out that my favorite keyboard shortcut was eaten by that one. Changing it to whatever else, solved the code completion in Eclipse for me.

Wednesday, March 27, 2013

Glassfish: showing jndi tree

To list the jndi tree entries in the glassfish use:

$GLASSFISH_HOME/glassfish/bin/asadmin list-jndi-entries

Wednesday, February 27, 2013

Xfce: changing standard global keyboard shortcuts

Q: Did you ever face the problem with Xfce not all of the globally defined keyboard shortcuts can be changed?

In my case Eclipse IDE shortcuts that I'm used to:
  • Perspective switch (Ctrl + F8)
  • Editor switch (Ctrl + F6)
  • ...
all of these were eaten by Xfce (as they're supposed to be used for some multi-workspace experience)
But hey! I don't use multiple workspaces! I'd rather like to use the full power of eclipse here.

Changing via UI 


But if you go over: Menu -> Settings -> Keyboad
There are not all the global shortcuts listed (at least those mentioned earlier are missing).

Looking for help


As I faced this problem already quite some time ago, I even participated in some discussions (like this on myeclipse related), and even submitted Xfce bug report.

Good old plain xml way 


But when I came back to this problem after some time, I've googled and found some references to file:
~/.config/xfce4/xfconf/xfce-perchannel-xml/xfce4-keyboard-shortcuts.xml

As I checked the contents, there seem to be even the shortcuts I'm facing the problem with.

I've seen there:
  <property name="xfwm4" type="empty">
    <property name="default" type="empty">
      <property name="&lt;Alt&gt;Insert" type="empty"/>
      <property name="Escape" type="empty"/>
      <property name="Left" type="empty"/>
      <property name="Right" type="empty"/>
      <property name="Up" type="empty"/>
      <property name="Down" type="empty"/>
      <property name="&lt;Alt&gt;Tab" type="empty"/>
      <property name="&lt;Alt&gt;&lt;Shift&gt;Tab" type="empty"/>
      <property name="&lt;Alt&gt;Delete" type="empty"/>
      <property name="&lt;Control&gt;&lt;Alt&gt;Down" type="empty"/>
      <property name="&lt;Control&gt;&lt;Alt&gt;Left" type="empty"/>
      <property name="&lt;Shift&gt;&lt;Alt&gt;Page_Down" type="empty"/>
      <property name="&lt;Alt&gt;F4" type="empty"/>
      <property name="&lt;Alt&gt;F6" type="empty"/>
      <property name="&lt;Alt&gt;F7" type="empty"/>
      <property name="&lt;Alt&gt;F8" type="empty"/>
      <property name="&lt;Alt&gt;F9" type="empty"/>
      <property name="&lt;Alt&gt;F10" type="empty"/>
      <property name="&lt;Alt&gt;F11" type="empty"/>
      <property name="&lt;Alt&gt;F12" type="empty"/>
      <property name="&lt;Control&gt;&lt;Shift&gt;&lt;Alt&gt;Left" type="empty"/>
      <property name="&lt;Alt&gt;&lt;Control&gt;End" type="empty"/>
      <property name="&lt;Alt&gt;&lt;Control&gt;Home" type="empty"/>
      <property name="&lt;Control&gt;&lt;Shift&gt;&lt;Alt&gt;Right" type="empty"/>
      <property name="&lt;Control&gt;&lt;Shift&gt;&lt;Alt&gt;Up" type="empty"/>
      <property name="&lt;Alt&gt;&lt;Control&gt;KP_1" type="empty"/>
      <property name="&lt;Alt&gt;&lt;Control&gt;KP_2" type="empty"/>
      <property name="&lt;Alt&gt;&lt;Control&gt;KP_3" type="empty"/>
      <property name="&lt;Alt&gt;&lt;Control&gt;KP_4" type="empty"/>
      <property name="&lt;Alt&gt;&lt;Control&gt;KP_5" type="empty"/>
      <property name="&lt;Alt&gt;&lt;Control&gt;KP_6" type="empty"/>
      <property name="&lt;Alt&gt;&lt;Control&gt;KP_7" type="empty"/>
      <property name="&lt;Alt&gt;&lt;Control&gt;KP_8" type="empty"/>
      <property name="&lt;Alt&gt;&lt;Control&gt;KP_9" type="empty"/>
      <property name="&lt;Alt&gt;space" type="empty"/>
      <property name="&lt;Shift&gt;&lt;Alt&gt;Page_Up" type="empty"/>
      <property name="&lt;Control&gt;&lt;Alt&gt;Right" type="empty"/>
      <property name="&lt;Control&gt;&lt;Alt&gt;d" type="empty"/>
      <property name="&lt;Control&gt;&lt;Alt&gt;Up" type="empty"/>
      <property name="&lt;Super&gt;Tab" type="empty"/>
      <property name="&lt;Control&gt;F1" type="empty"/>
      <property name="&lt;Control&gt;F2" type="empty"/>
      <property name="&lt;Control&gt;F3" type="empty"/>
      <property name="&lt;Control&gt;F4" type="empty"/>
      <property name="&lt;Control&gt;F5" type="empty"/>
      <property name="&lt;Control&gt;F6" type="empty"/>
      <property name="&lt;Control&gt;F7" type="empty"/>
      <property name="&lt;Control&gt;F8" type="empty"/>
      <property name="&lt;Control&gt;F9" type="empty"/>
      <property name="&lt;Control&gt;F10" type="empty"/>
      <property name="&lt;Control&gt;F11" type="empty"/>
      <property name="&lt;Control&gt;F12" type="empty"/>
    </property>
    <property name="custom" type="empty">
      <property name="&lt;Control&gt;F3" type="string" value="workspace_3_key"/>
      <property name="&lt;Control&gt;F4" type="string" value="workspace_4_key"/>
      <property name="&lt;Control&gt;F5" type="string" value="workspace_5_key"/>
      <property name="&lt;Control&gt;F6" type="string" value="workspace_6_key"/>
      <property name="&lt;Control&gt;F7" type="string" value="workspace_7_key"/>
      <property name="&lt;Control&gt;F8" type="string" value="workspace_8_key"/>
      <property name="&lt;Control&gt;F9" type="string" value="workspace_9_key"/>
      <property name="&lt;Alt&gt;Tab" type="string" value="cycle_windows_key"/>
      <property name="&lt;Control&gt;&lt;Alt&gt;Right" type="string" value="right_workspace_key"/>
      <property name="Left" type="string" value="left_key"/>
      <property name="&lt;Control&gt;&lt;Alt&gt;d" type="string" value="show_desktop_key"/>
      <property name="&lt;Control&gt;&lt;Shift&gt;&lt;Alt&gt;Left" type="string" value="move_window_left_key"/>
      <property name="&lt;Control&gt;&lt;Shift&gt;&lt;Alt&gt;Right" type="string" value="move_window_right_key"/>
      <property name="Up" type="string" value="up_key"/>
      <property name="&lt;Alt&gt;F4" type="string" value="close_window_key"/>
      <property name="&lt;Alt&gt;F6" type="string" value="stick_window_key"/>
      <property name="&lt;Control&gt;&lt;Alt&gt;Down" type="string" value="down_workspace_key"/>
      <property name="&lt;Alt&gt;F7" type="string" value="move_window_key"/>
      <property name="&lt;Alt&gt;F9" type="string" value="hide_window_key"/>
      <property name="&lt;Alt&gt;F11" type="string" value="fullscreen_key"/>
      <property name="&lt;Alt&gt;F8" type="string" value="resize_window_key"/>
      <property name="&lt;Super&gt;Tab" type="string" value="switch_window_key"/>
      <property name="Escape" type="string" value="cancel_key"/>
      <property name="&lt;Alt&gt;&lt;Control&gt;KP_1" type="string" value="move_window_workspace_1_key"/>
      <property name="&lt;Alt&gt;&lt;Control&gt;KP_2" type="string" value="move_window_workspace_2_key"/>
      <property name="&lt;Alt&gt;&lt;Control&gt;KP_3" type="string" value="move_window_workspace_3_key"/>
      <property name="&lt;Alt&gt;&lt;Control&gt;KP_4" type="string" value="move_window_workspace_4_key"/>
      <property name="&lt;Alt&gt;&lt;Control&gt;KP_5" type="string" value="move_window_workspace_5_key"/>
      <property name="&lt;Alt&gt;&lt;Control&gt;KP_6" type="string" value="move_window_workspace_6_key"/>
      <property name="Down" type="string" value="down_key"/>
      <property name="&lt;Control&gt;&lt;Shift&gt;&lt;Alt&gt;Up" type="string" value="move_window_up_key"/>
      <property name="&lt;Shift&gt;&lt;Alt&gt;Page_Down" type="string" value="lower_window_key"/>
      <property name="&lt;Alt&gt;F12" type="string" value="above_key"/>
      <property name="&lt;Alt&gt;&lt;Control&gt;KP_8" type="string" value="move_window_workspace_8_key"/>
      <property name="&lt;Alt&gt;&lt;Control&gt;KP_9" type="string" value="move_window_workspace_9_key"/>
      <property name="Right" type="string" value="right_key"/>
      <property name="&lt;Alt&gt;F10" type="string" value="maximize_window_key"/>
      <property name="&lt;Control&gt;&lt;Alt&gt;Up" type="string" value="up_workspace_key"/>
      <property name="&lt;Control&gt;F10" type="string" value="workspace_10_key"/>
      <property name="&lt;Alt&gt;&lt;Control&gt;KP_7" type="string" value="move_window_workspace_7_key"/>
      <property name="&lt;Alt&gt;&lt;Control&gt;End" type="string" value="move_window_next_workspace_key"/>
      <property name="&lt;Alt&gt;Delete" type="string" value="del_workspace_key"/>
      <property name="&lt;Control&gt;&lt;Alt&gt;Left" type="string" value="left_workspace_key"/>
      <property name="&lt;Control&gt;F12" type="string" value="workspace_12_key"/>
      <property name="&lt;Alt&gt;space" type="string" value="popup_menu_key"/>
      <property name="&lt;Alt&gt;&lt;Shift&gt;Tab" type="string" value="cycle_reverse_windows_key"/>
      <property name="&lt;Shift&gt;&lt;Alt&gt;Page_Up" type="string" value="raise_window_key"/>
      <property name="&lt;Alt&gt;Insert" type="string" value="add_workspace_key"/>
      <property name="&lt;Alt&gt;&lt;Control&gt;Home" type="string" value="move_window_prev_workspace_key"/>
      <property name="&lt;Control&gt;F2" type="string" value="workspace_2_key"/>
      <property name="&lt;Control&gt;F1" type="string" value="workspace_1_key"/>
      <property name="&lt;Control&gt;F11" type="string" value="workspace_11_key"/>
      <property name="override" type="bool" value="true"/>
    </property>
  </property>

That sounds promissing! Let's remove multi-workspace relevant and see if that helps.

After my update:
  <property name="xfwm4" type="empty">
    <property name="default" type="empty">
      <property name="&lt;Alt&gt;Insert" type="empty"/>
      <property name="Escape" type="empty"/>
      <property name="Left" type="empty"/>
      <property name="Right" type="empty"/>
      <property name="Up" type="empty"/>
      <property name="Down" type="empty"/>
      <property name="&lt;Alt&gt;Tab" type="empty"/>
      <property name="&lt;Alt&gt;&lt;Shift&gt;Tab" type="empty"/>
      <property name="&lt;Alt&gt;Delete" type="empty"/>
<!--
      <property name="&lt;Control&gt;&lt;Alt&gt;Down" type="empty"/>
      <property name="&lt;Control&gt;&lt;Alt&gt;Left" type="empty"/>
-->
      <property name="&lt;Shift&gt;&lt;Alt&gt;Page_Down" type="empty"/>
      <property name="&lt;Alt&gt;F4" type="empty"/>
      <property name="&lt;Alt&gt;F6" type="empty"/>
      <property name="&lt;Alt&gt;F7" type="empty"/>
      <property name="&lt;Alt&gt;F8" type="empty"/>
      <property name="&lt;Alt&gt;F9" type="empty"/>
      <property name="&lt;Alt&gt;F10" type="empty"/>
      <property name="&lt;Alt&gt;F11" type="empty"/>
      <property name="&lt;Alt&gt;F12" type="empty"/>
      <property name="&lt;Control&gt;&lt;Shift&gt;&lt;Alt&gt;Left" type="empty"/>
<!--
      <property name="&lt;Alt&gt;&lt;Control&gt;End" type="empty"/>
      <property name="&lt;Alt&gt;&lt;Control&gt;Home" type="empty"/>
      <property name="&lt;Control&gt;&lt;Shift&gt;&lt;Alt&gt;Right" type="empty"/>
      <property name="&lt;Control&gt;&lt;Shift&gt;&lt;Alt&gt;Up" type="empty"/>

      <property name="&lt;Alt&gt;&lt;Control&gt;KP_1" type="empty"/>
      <property name="&lt;Alt&gt;&lt;Control&gt;KP_2" type="empty"/>
      <property name="&lt;Alt&gt;&lt;Control&gt;KP_3" type="empty"/>
      <property name="&lt;Alt&gt;&lt;Control&gt;KP_4" type="empty"/>
      <property name="&lt;Alt&gt;&lt;Control&gt;KP_5" type="empty"/>
      <property name="&lt;Alt&gt;&lt;Control&gt;KP_6" type="empty"/>
      <property name="&lt;Alt&gt;&lt;Control&gt;KP_7" type="empty"/>
      <property name="&lt;Alt&gt;&lt;Control&gt;KP_8" type="empty"/>
      <property name="&lt;Alt&gt;&lt;Control&gt;KP_9" type="empty"/>
-->
      <property name="&lt;Alt&gt;space" type="empty"/>
      <property name="&lt;Shift&gt;&lt;Alt&gt;Page_Up" type="empty"/>
<!--
      <property name="&lt;Control&gt;&lt;Alt&gt;Right" type="empty"/>
-->
      <property name="&lt;Control&gt;&lt;Alt&gt;d" type="empty"/>
<!--
      <property name="&lt;Control&gt;&lt;Alt&gt;Up" type="empty"/>
-->
      <property name="&lt;Super&gt;Tab" type="empty"/>
<!--
      <property name="&lt;Control&gt;F1" type="empty"/>
      <property name="&lt;Control&gt;F2" type="empty"/>
      <property name="&lt;Control&gt;F3" type="empty"/>
      <property name="&lt;Control&gt;F4" type="empty"/>
      <property name="&lt;Control&gt;F5" type="empty"/>
      <property name="&lt;Control&gt;F6" type="empty"/>
      <property name="&lt;Control&gt;F7" type="empty"/>
      <property name="&lt;Control&gt;F8" type="empty"/>
      <property name="&lt;Control&gt;F9" type="empty"/>
      <property name="&lt;Control&gt;F10" type="empty"/>
      <property name="&lt;Control&gt;F11" type="empty"/>
      <property name="&lt;Control&gt;F12" type="empty"/>
-->
    </property>
    <property name="custom" type="empty">
<!--
      <property name="&lt;Control&gt;F3" type="string" value="workspace_3_key"/>
      <property name="&lt;Control&gt;F4" type="string" value="workspace_4_key"/>
      <property name="&lt;Control&gt;F5" type="string" value="workspace_5_key"/>
      <property name="&lt;Control&gt;F6" type="string" value="workspace_6_key"/>
      <property name="&lt;Control&gt;F7" type="string" value="workspace_7_key"/>
      <property name="&lt;Control&gt;F8" type="string" value="workspace_8_key"/>
      <property name="&lt;Control&gt;F9" type="string" value="workspace_9_key"/>
-->
      <property name="&lt;Alt&gt;Tab" type="string" value="cycle_windows_key"/>
<!--
      <property name="&lt;Control&gt;&lt;Alt&gt;Right" type="string" value="right_workspace_key"/>
-->
      <property name="Left" type="string" value="left_key"/>
      <property name="&lt;Control&gt;&lt;Alt&gt;d" type="string" value="show_desktop_key"/>
      <property name="&lt;Control&gt;&lt;Shift&gt;&lt;Alt&gt;Left" type="string" value="move_window_left_key"/>
      <property name="&lt;Control&gt;&lt;Shift&gt;&lt;Alt&gt;Right" type="string" value="move_window_right_key"/>
      <property name="Up" type="string" value="up_key"/>
      <property name="&lt;Alt&gt;F4" type="string" value="close_window_key"/>
      <property name="&lt;Alt&gt;F6" type="string" value="stick_window_key"/>
      <property name="&lt;Control&gt;&lt;Alt&gt;Down" type="string" value="down_workspace_key"/>
      <property name="&lt;Alt&gt;F7" type="string" value="move_window_key"/>
      <property name="&lt;Alt&gt;F9" type="string" value="hide_window_key"/>
      <property name="&lt;Alt&gt;F11" type="string" value="fullscreen_key"/>
      <property name="&lt;Alt&gt;F8" type="string" value="resize_window_key"/>
      <property name="&lt;Super&gt;Tab" type="string" value="switch_window_key"/>
      <property name="Escape" type="string" value="cancel_key"/>
<!--
      <property name="&lt;Alt&gt;&lt;Control&gt;KP_1" type="string" value="move_window_workspace_1_key"/>
      <property name="&lt;Alt&gt;&lt;Control&gt;KP_2" type="string" value="move_window_workspace_2_key"/>
      <property name="&lt;Alt&gt;&lt;Control&gt;KP_3" type="string" value="move_window_workspace_3_key"/>
      <property name="&lt;Alt&gt;&lt;Control&gt;KP_4" type="string" value="move_window_workspace_4_key"/>
      <property name="&lt;Alt&gt;&lt;Control&gt;KP_5" type="string" value="move_window_workspace_5_key"/>
      <property name="&lt;Alt&gt;&lt;Control&gt;KP_6" type="string" value="move_window_workspace_6_key"/>
-->
      <property name="Down" type="string" value="down_key"/>
      <property name="&lt;Control&gt;&lt;Shift&gt;&lt;Alt&gt;Up" type="string" value="move_window_up_key"/>
      <property name="&lt;Shift&gt;&lt;Alt&gt;Page_Down" type="string" value="lower_window_key"/>
      <property name="&lt;Alt&gt;F12" type="string" value="above_key"/>
<!--
      <property name="&lt;Alt&gt;&lt;Control&gt;KP_8" type="string" value="move_window_workspace_8_key"/>
      <property name="&lt;Alt&gt;&lt;Control&gt;KP_9" type="string" value="move_window_workspace_9_key"/>
-->
      <property name="Right" type="string" value="right_key"/>
      <property name="&lt;Alt&gt;F10" type="string" value="maximize_window_key"/>
<!--
      <property name="&lt;Control&gt;&lt;Alt&gt;Up" type="string" value="up_workspace_key"/>
      <property name="&lt;Control&gt;F10" type="string" value="workspace_10_key"/>
      <property name="&lt;Alt&gt;&lt;Control&gt;KP_7" type="string" value="move_window_workspace_7_key"/>
      <property name="&lt;Alt&gt;&lt;Control&gt;End" type="string" value="move_window_next_workspace_key"/>
      <property name="&lt;Alt&gt;Delete" type="string" value="del_workspace_key"/>
      <property name="&lt;Control&gt;&lt;Alt&gt;Left" type="string" value="left_workspace_key"/>
      <property name="&lt;Control&gt;F12" type="string" value="workspace_12_key"/>
-->
      <property name="&lt;Alt&gt;space" type="string" value="popup_menu_key"/>
      <property name="&lt;Alt&gt;&lt;Shift&gt;Tab" type="string" value="cycle_reverse_windows_key"/>
      <property name="&lt;Shift&gt;&lt;Alt&gt;Page_Up" type="string" value="raise_window_key"/>
<!--
      <property name="&lt;Alt&gt;Insert" type="string" value="add_workspace_key"/>
      <property name="&lt;Alt&gt;&lt;Control&gt;Home" type="string" value="move_window_prev_workspace_key"/>
      <property name="&lt;Control&gt;F2" type="string" value="workspace_2_key"/>
      <property name="&lt;Control&gt;F1" type="string" value="workspace_1_key"/>
      <property name="&lt;Control&gt;F11" type="string" value="workspace_11_key"/>
-->
      <property name="override" type="bool" value="true"/>
    </property>

to be honest, I'm not sure if I need to update them in both sections, but to make things fast, let's do so.

OK, I guess I need to log-out/and in and see if that helped.

And as you could guess it...... worked!  (otherwise I would not write a blog post, right? :-) )