Saturday, October 11, 2014

Spring 4 modular @Enable* annotation

I had a project that included several different deployments that uses similar architecture: all of them are Java EE Spring 4 based, deployed on Amazon Beanstalk environment, and share lots of cross-concern code, such as logging infrastructure, security mechanism, EC2-related custom code, etc.

The natural solution for such environment is to have a common infrastructure jar that will hold the common logic, and each project would be able set different configuration, if needed.

One instance is the cross-concern requirement to add a Log4J SocketAppender, in order to hook the projects into a central logging server that uses the Kibana+Logstash+Elasticsearch stack. Each project might use a different SocketAppender setting (different host, different port, different application name), but the wiring is the same. Let's examine the code that would do it.

First, an annotation should be defined, to enable the Logstash wiring:

The important bit here is the @Import(LogstashConfiguration.class) part. This allow spring to "understand" it needs to import the configuration bean LogstashConfiguration to its context. This will bootstrap the wiring.

An object that will hold the config data need to be created:

An interface to allow the projects to hook a configuration listener need to be defined:

Adding an concrete implementation of this interface in the target project will allow to configure the logstash binding. For instance, in order to set the hostname from the environment variable:

Now, we can define the actual binding logic:

This object is invoked due to the @Import code in the @EnableLogstash annotation. It has its own @ComponentScan annotation, to make Spring scan the relevant classes as well. It implements the ApplicationListener interface, in order to bind the SocketAppender during the context refresh event.

Now you can annotate the application with @EnableLogstash in order to activate the Logstash asynchronious appender, and use LogstashConfigurer implementation to pass configuration - whether you store it in property files, environment variables, system properties, or whatever.

Thursday, May 2, 2013

Jersey REST JAX-RS + Glassfish + EJB = Success!

A well known issue with Jersey prevents injecting EJB's into a RESTfull service. Several walkarounds were suggested (http://stackoverflow.com/questions/3027834/inject-a-ejb-into-jax-rs-restfull-service), but most of them are error-prone or just complicated.
If you are using Glassfish, by invoking InjectionManager.injectInstance(yourRestObject) you would inject your EJBs/Resources/@PersistenceContexts into yourRestObject, and solve the issue effortless. One way to accomplish it might be implementing an abstract constructor:

I guess some of you would raise an eyebrow about the sneakyThrow part. SneakyThrow is a nice (and dirty) trick I've learned from Lombok, which allow you to throw checked exceptions without declearing them. This is useful here because otherwise you would have to either: a) wrap your InjectionException with RuntimeException, which is not exactly the same as throwing InjectionException, or b) implement an empty YourRESTService() throws NamingException, InjectionException constructor for each RESTful service, which is ugly. Sneakily throwing the InjectionException (and the NamingException on odd cases) address both issues.

If you're using Maven, you'll need to have the following dependency added to your pom:


There is an important pitfall and limitation here: you cannot put your injector in a @PostConstract method, as the InjectionManager will invoke itself recursively. On the same note, since Jersey invokes @PostConstract methods as well, every method that is annotated with @PostConstract will be invoked twice upon construction (instead of once). In both invocations your injections will be in place (i.e not null), but you should still consider this fact into your design, especially if the @PostConstract's are expensive or have side effects.

P.S.
When thinking about it, if you really insist you can removing the container-common dependency from the compiler classpath, and invoke injectInstance() using reflection. But I can't find any good reason to do that.

Thursday, April 18, 2013

Installing ANTLR IDE plugin on Eclipse Juno

ANTLR IDE is probably the most comprehensive ANTLR Eclipse plugin. Among its features, you can count an option to see a railroad diagaram, an instant grammar evaluator and an ANTLR syntax highlighter. Problem is that it cannot be installed out-of-the-box for some Eclipse configurations, such as the Eclispe 4.2 for JavaEE: you may see "XXX requires 'org.eclipse.dltk.core [3.0.0,4.0.0)' but it could not be found" error message when trying to install it.

In order to install the ANTLR IDE, you first need to install the following plugins:

  • From the Indigo plugin repository (http://download.eclipse.org/releases/indigo/), under the "General Purpose Tools" group, install "Dynamic Languages Toolkit - Core Framework" (v3.x)
  • From the GEF (Graphical Editing Framework) plugin repository (http://download.eclipse.org/tools/gef/updates/releases/) install "Zest Visualization Toolkit" (v1.x)
Notice that you are installing the correct versions! Installing too advanced version will prevent you from installing some or all features of ANTLR IDE.

Once both are installed, you can install ANTLR IDE from the marketplace or from http://antlrv3ide.sourceforge.net/updates plugin repository.

Tuesday, January 29, 2013

Gmail allows CTRL-Enter

Gmail supports CTRL-Enter shortcut to send emails immediately. Hooray!

Wednesday, January 23, 2013

Security breach in an educational institute

I found a security breach in a well known Israeli high education institute. I sent an alert to the institute. I will publish the full details as soon as the breach will be patched or the affected service will be shutdown.
-- Update (24 Jan) - The institute has blocked the affected service, effectively blocking the vulnerability.

Saturday, August 25, 2012

Primefaces+Atmosphere+Push+Maven Setup

Recently enough Primefaces has announced their Atmosphere based push component. Unfortunately, the setup process isn't documented well yet, and requires few try-and-error iterations to get it working.

I assume you already have a working JSF+Primefaces+Maven environment, but when you try to use the newly Prime Push of the upcoming v3.4, you get one of those errors:

  • NoClassDefFoundError for org.atmosphere.cpr.AtmosphereServlet or org.primefaces.push.PushContextFactory
  • Error 500/404 from http://localhost:8080/YOUR_CONTEXT/primepush/YOUR_CHANNEL

First, you need to add two dependencies for your project:

  • Notice that the last one should match your environment. That is, if you are running in Tomcat environment, use atmosphere-compat-tomcat.
  • Notice that you need the latest beta version. The stable 0.9.7 version is not compatible with Primefaces Push.

Having that done, you'll need to add to your web.xml the following servlet:

  • Mind to have the channels values match the channels you are about to use.
  • Don't add leading/trainling backslashes.

And that's it.

For example:

  1. Put in the param-value "msg"
  2. Add the following snippet to one of your pages:
  3. Add the following to one of your beans:
When you'll invoke the push() method, the String would be pushed back to the client.

Friday, March 16, 2012

Lastpass.com security vulenrability

Recently, I'v discovered an XSS (Cross-site scripting) vulnerability in Lastpass.com add-on for browsers.
Lastpass.com is a password manager that keeps password in the cloud in a secured manner.

The vulnerability allow a malicious site owner to craft a special field, which in turn, if and when the user will decide to remove that field from that vault, an arbitrary JavaScript code would be executed. The code would be able to access the runtime environment of the plugin - thus to submit to external site sensitive information about Lastpass.com users.

Lastpass.com acknoladge the vulenrability, and issued a patch in a short amount of time. Lastpass.com add-ons are no longer affected by the issue, for this moment. They also publicly credited my about the disclosure at https://lastpass.com/support_security.php