Calling Objectify within DeferredTask

This article explains how to call Objectify within a DeferredTask on Google App Engine push queue.

This article appeared first on techtavern.wordpress.com

Objectify Wiki presents a clear explanation how to user ObjectifyFilter to get or inject a Objectify instance into your servlet. However there is no word using Objectify within push queues.

Solution 1: Create task with worker URLs that are mapped to your servlet

Let ObjectifyFilter inject the Objectify instance. It your responsibility to encode and handle parameters and to secure your URLs.

Solution 2: Create a DeferredTask

Let GAE handle parameters and security for you. Call ObjectifyService.begin() to manually start an Objectify session. Close this session manually when the task finishes. A try-with-resources block handles everything for you.

import com.googlecode.objectify.ObjectifyService;

public class MyTask implements DeferredTask {
   final String parameter;
   public MyTask(String parameter) {
      this.parameter = parameter;
   }

   @Override
   public void run() {
      try (Closeable closeable = ObjectifyService.begin()) {
          Objectify ofy = MyObjectifyService.ofy();          
          // start transactions, read or write data.
          // ...
      } catch (IOException | RuntimeException e) {
          // log or handle failure.
      }
   }
}

I recommend a class that statically registers your entities before calling any Objectify method.

public class MyObjectifyService {
   static {
      factory().register(MyEntity.class);
      // ...
   }
   public static Objectify ofy() {
      return ObjectifyService.ofy();
   }
}

References:

Google App Engine Java SDK advices

It would have been nice if I knew this beforehand about Google App Engine Java SDK

This article originally appeared on https://techtavern.wordpress.com

GAE infrastructure is a kind of Java 7 platform. You may compile your code using the current Java 8 SDK, as long as source code version is set to Java 7. You may deploy and run your application locally with Java 8, too.

However, when deploying to Google infrastructure, there are some pitfalls.

  1. The appcfg script pre-compiles your JSP files using the Java SDK on the PATH or set by JAVA_HOME system property. If this SDK is not Java 7, appcfg will create and upload incompatible class files.
  2. Java SDK 7 is not available anymore for download on Oracle website.

I have found Java SDK 7 (7u79) installer for download still available on http://www.oracle.com/technetwork/java/javase/downloads/jdk7-downloads-1880260.html

Probably, you do not want do pollute your development environment by installing a deprecated SDK. This article explains how to extract a portable SDK without running the installer. And if you do not want to mess your current PATH and JAVA_HOME system variables globally, you may set them within the appcfg.cmd file.

setlocal
set JAVA_HOME=C:\Users\Daniel\Programas\jdk7
set PATH=C:\Users\Daniel\Programas\jdk7\bin
java -Duser.language=EN -Xmx1100m -cp "%~dp0\..\lib\appengine-tools-api.jar" 
     com.google.appengine.tools.admin.AppCfg %*
endlocal

Netbeans RCP: Asking before exiting the application

This article explains how to present a confirmation dialog asking if the user really wants to close the application.

This article was originally published on techtavern.wordpress.com.

The following solution registers a callable via @OnStop annotation. The callable is an opportunity to cancel closing the application by returning false.

import java.util.concurrent.Callable;
import org.openide.DialogDisplayer;
import org.openide.NotifyDescriptor;
import org.openide.modules.OnStop;

@OnStop
public class ApplicationOnStop implements Callable<Boolean> {
@Override
   public Boolean call() throws Exception {
      NotifyDescriptor d = new NotifyDescriptor.Confirmation("Close application?", NotifyDescriptor.YES_NO_OPTION)
      return DialogDisplayer.getDefault().notify(d) == NotifyDescriptor.YES_OPTION; 
   } 
}

SLF4J on Netbeans RCP Applications

This article explains how to configure SLF4J logging framework for your Netbeans RCP modules.

This article was originally published on techtavern.wordpress.com

Netbeans RCP favors Java standards for a small memory footprint and to spare us from learning new APIs. For example, Netbeans uses java.util.logging instead of creating its own logging API. However, most developers prefer leaner logger APIs like SLF4J.

Context

It happens that Netbeans kept only the API and replaced most of the java.util.logging original implementation. The startup module replaces the log manager. A custom handler writes messages into the platform messages file using a custom pattern. Another handler repeats messages on the platform messages TopComponent.

A third handler identifies error and warning messages with exceptions and presents them as a error dialogs. The Dialog API deprecated error dialogs in order to “encourage” java.util.logging.

Even worse, the platform classloader prevents the slf4j bridges from replacing the java.util.logging framework on platform and third party modules. Module importing SLF4J themselves will behave inconsistently to other modules and to platform defaults.

Solution

Instead of trying to bypass the Platform logging features, we opted for SLF4J redirecting messages to java.util.logging, which is then handled by the Platform on its custom way.

We created a library wrapper module containing slf4j-api-x.y.z.jar and slf4j-sdk14-x.y.z.jar. No coding is required. Only the org.slf4j packages needs to be set ‘public’.

Netbeans RCP module wrapping SLF4J libraries

Netbeans RCP module wrapping SLF4J libraries

Netbeans RCP module exporting SLF4J public packages

Netbeans RCP module exporting SLF4J public packages

This combination preserves the platform logging features and conventions, while enabling our modules with the SLF4J better API.

Netbeans RCP Toys

The solution described above is provided by the Netbeans RCP Toys project at Github. Look for the Logger-Toys suite, that contains the Logger-SLF4J-Libs module.

References

Netbeans RCP: external layer.xml

A Netbeans RCP application might benefit from an additional layer.xml file stored outside of application bundles. A network directory or a http server may provide some layer.xml with centralized or corporated configuration or user profiles, maintained the network administrator.

This article was first published at techtavern.wordpress.com

There are two solutions to add an additional layer.xml file to your application. Both solutions are provided by Netbeans RCP Toys at github.

LayerProvider

Register a LayerProvider using the @ServiceProvider(service = LayerProvider.class) annotation. The platform calls all LayerProvider.registerLayers(Collection<? super URL>) to populate the collection with URLs to additional layer files. This URL may refer a local file or a remote over HTTP. As this method is called early, your application might not yet know the URL. For example, it does not work for command line argument as they have not been parsed then LayerProvider.registerLayers() is called. This approach is file as long as your URLs are declared as static constants.

@ServiceProvider(service = LayerProvider.class)
public class SystemPropertyUrlLayer extends Repository.LayerProvider {
    @Override
    protected void registerLayers(Collection<? super URL> context) {
       try {
          context.add(new URL(...));
        } catch (MalformedURLException ex) {
            throw new IllegalArgumentException("Invalid URL.", ex);
        }
    }
}

This solution is demonstrated by the Platform-Layer-Property example at Netbeans RCP Toys, which extracts the additional layer.xml URL from a system property.

Dynamic FileSystem

Register your own FileSystem instance using the @ServiceProvider(service = FileSystem.class) annotation. It will be instantiated early, but a FileSystem instance may change it content later when the additional layer.xml path is known. A custom and changeable FileSystem implementation is quite complex. Fortunately, the platform provides the DynamicLayer that may be extended to emulate the custom and changeable behavior.


/**
 * @see http://wiki.netbeans.org/DevFaqDynamicSystemFilesystem
 * @author Daniel Felix Ferber - X7WS
 */
@ServiceProvider(service = FileSystem.class)
public class PostLoadingFileSystem extends MultiFileSystem {

    private static PostLoadingFileSystem INSTANCE;

    public PostLoadingFileSystem() {
        // will be created on startup, exactly once
        INSTANCE = this;
        setPropagateMasks(true); // permit *_hidden masks to be used
    }

    public static PostLoadingFileSystem getInstance() {
        return INSTANCE;
    }

    public void setFileSystem(FileSystem fs) {
        FileSystem[] newDelegates = new FileSystem[] { fs };
        setDelegates(newDelegates);
    }

    public void setFileSystem(URL url) {
       try {
            setFileSystem(new XMLFileSystem(url));
        } catch (SAXException ex) {
            throw new IllegalArgumentException("URL references an invalid XML document.", ex);
        }
    }
}

This solution is demonstrated by the Platform-Layer-Argument example at Netbeans RCP Toys, which extracts the additional layer.xml URL from a command line argument.

SLF4J on Java Google App Engine

This article suggest a recipe to configure SLF4J on Google App Engine for Java.

This article was first published at techtavern.wordpress.com

Google App Engine for Java offers a restricted Java 6 API, which includes just the cumbersome Java Utils Logging. Fortunately, SLF4J works as well. The recipe is the standard one. Nearly no configuration is required.

Just add following SLF4J libraries into the applications WEB-INF/lib directory: slfj4-api-1.7.7.jar and slf4j-jdk14-1.7.7.jar (version number may vary). This will redirect all your SLF4J logging statements to the Java Utils Logging controlled by the App Engine.

Optionally you may also add jcl-over-slf4j-1.7.7.jar and log4j-over-slf4j-1.7.7.jar libraries, that will redirect both Apache Commons Logging and Log4J to SLF4J (and thus to App Engine’s Java Utils Logging).

View TopComponents with icons on Netbeans RCP

This article explains an approach to enable tabs with icons to ‘view’ TopComponents.

This article appeared first on techtavern.wordpress.com

The Problem

A typical Netbeans RCP application always displays TopComponents with ‘editor’ mode with their icon and their title, even if the tab runs out of space. Here is an example:

EditorTopComponentTab

Tabs of editor TopComponents

 

TopComponents with other modes are displayed as ‘views’. Their tabs are extremely simplistic: they never show their icon and their title is shortened or even omitted in case of less space. Here is an example:

ViewTopComponentTab

Tabs of view TopComponents (observe that the title of the focused tab is missing!)

 

 

Some thoughts about

Geertjan’s Blog explains in his blog how to completely hide tabs for ‘editor’ TopComponents, by setting the ‘EditorTabDisplayerUI’ UIManager property and overriding the inherited Look and Feel that renders the tab.

If there is an ‘editor’ tab displayer, wouldn’t there be a ‘view’ tab displayer? After some research, I found the analogous ‘ViewTabDisplayerUI’ UIManager property. But what would be the proper value? A self crafted class like Geertjan’s one? That would require too much work and it would not follow the current Look and Feel.

The Solution

As the editor tab displayer looks fine, I decided to reuse it as a view tab displayer provided by the current Look and Feel. That was quite simple, though audacious. To preserve the look and feel, copy the the EditorTabDisplayerUI property’s value to the ViewTabDisplayerUI UIManager property. This hack requires scheduling the code from an module installer to execute later in the UI thread, when the Look and Feel is already defined.

public class Installer extends ModuleInstall {
 @Override
 public void restored() {
   SwingUtilities.invokeLater(new Runnable() {
     @Override
     public void run() {
       final Object view = UIManager.get("ViewTabDisplayerUI");
       final Object editor = UIManager.get("EditorTabDisplayerUI");
       System.out.println("invokeLater: "+view);
       System.out.println("invokeLater: " +editor);
       UIManager.put("ViewTabDisplayerUI", editor);
     }
   });
 }
}

I admit that it is a dirty hack, but it worked.