Posts tagged ‘Java’

August 20, 2013

Mutable variable capture in anonymous Java classes

by Jay Jonas
 
 

The Java compiler requires local variables of enclosing contexts referenced in anonymous classes (so-called captured variables) to be final. What if the anonymous class wants to alter the value of the variable, i.e. requires the variable to be mutable? This post shows different ways how to achieve that.

Mutability with an array

The most common way to solve this problem is to put the variable into an array of length one, make the array final and capture the array:

<br /><%%KEEPWHITESPACE%%>   JButton button = new JButton("Press me!");<br /><%%KEEPWHITESPACE%%>   final String[] message = new String[]{"Never been pressed"};<br /><%%KEEPWHITESPACE%%>   button.addActionListener(new ActionListener() {<br /><br /><%%KEEPWHITESPACE%%>      @Override<br /><%%KEEPWHITESPACE%%>      public void actionPerformed(ActionEvent e) {<br /><%%KEEPWHITESPACE%%>         message[0] = "Pressed";<br /><%%KEEPWHITESPACE%%>      }<br /><br /><%%KEEPWHITESPACE%%>   });<br />

The value is stored in the first slot of the array. The reference to the array is final but its element stays mutable.

While this approach works fine, it looks strange and will certainly raise questions for developers in your team which have never seen this construct before.

Mutability with a holder

The better way to make the message mutable is to put it into a holder class

<br /><%%KEEPWHITESPACE%%>    class Holder {<br /><%%KEEPWHITESPACE%%>        private T value;<br /><br /><%%KEEPWHITESPACE%%>        Holder(T value) {<br /><%%KEEPWHITESPACE%%>            setValue(value);<br /><%%KEEPWHITESPACE%%>        }<br /><br /><%%KEEPWHITESPACE%%>        T getValue() {<br /><%%KEEPWHITESPACE%%>            return value;<br /><%%KEEPWHITESPACE%%>        }<br /><br /><%%KEEPWHITESPACE%%>        void setValue(T value) {<br /><%%KEEPWHITESPACE%%>            this.value = value;<br /><%%KEEPWHITESPACE%%>        }<br /><%%KEEPWHITESPACE%%>    }<br />

and pass the holder into the inner class:

<br /><%%KEEPWHITESPACE%%>   JButton button = new JButton("Press me!");<br /><%%KEEPWHITESPACE%%>   final Holder mutableMessage = new Holder("Never been pressed");<br /><%%KEEPWHITESPACE%%>   button.addActionListener(new ActionListener() {<br /><br /><%%KEEPWHITESPACE%%>      @Override<br /><%%KEEPWHITESPACE%%>      public void actionPerformed(ActionEvent e) {<br /><%%KEEPWHITESPACE%%>         mutableMessage.setValue("Pressed");<br /><%%KEEPWHITESPACE%%>      }<br /><br /><%%KEEPWHITESPACE%%>   });<br />

This solution states more clearly why the message has been wrapped. If the holder is implemented as a generic utility class, this solution is not more verbose than the one with the array. In case you don’t want to implement the Holder class yourself, you can also reuse the MutableObject from Apache Commons or the Holder from Google Guava. One could argue that the solution with the array is faster (creating an array is usually faster than instantiating a class), but in most cases the performance loss will be negligible.

// from at eclipsesource.com/blogs

 
Advertisements
August 5, 2013

Running javah tool from Eclipse

by Jay Jonas

The javah produces C header files and C source files from a Java class that are needed to implement native methods. The javah -jni is used to generate a C header file containing the function prototype for the native method implementation.

The javah can be configured as an external tool like this: click Run |External Tools |External Tools Configurations. This will invoke External Tools Configurations wizard.

Select Program Type and create a new launch configuration.

For Location, click on Browse File System and browse to the path of javah tool (typically <java_home>\bin).

For Working Directory, click on Browse Workspace and select upto project output directory (directory where class files reside – typically ${workspace_loc:/your.jni.project/bin})

Various options of javah command may be added here which is then followed by ${java_type_name} workspace variable which returns the fully qualified Java type name of the primary type in the selected resource.

The argument list instructs the tool to keep the generated header file in a directory named jni under the project folder. If -d option is not specified, the header files will be stored in bin folder itself.

"${project_loc}${system_property:file.separator}jni" ${java_type_name}
External Tools Configuration

External Tools Configuration

// That’s all, folks!

January 26, 2011

ClassNotFoundException: org.mortbay.start.Main

by Jay Jonas

I was trying to set up Eclipse to run and deploy my projects to a Jetty 7 server. I have downloaded it and unpacked it, and I  installed the Jetty plugin from the available server adapters list, but when I try to configure a new Jetty server, the server type list only contains “Jetty 6”. If I use this and point it at my server runtime, when I try to start it I get the following error:

java.lang.NoClassDefFoundError: org/mortbay/start/Main
Caused by: java.lang.ClassNotFoundException: org.mortbay.start.Main
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClassInternal(Unknown Source)
Exception in thread "main"

The problem is that the package name changed with the migration from Codehaus to Eclipse. So, we need a new WTP Adaptor for Jetty 7.x/Jetty 8.x that can be downloaded from the update sites as follows:

To install the WTP Adaptor, complete the following steps.

  1. Open Eclipse.
  2. In the taskbar at the top of your screen, click Help -> Install New Software. The Available Software dialog box opens.
  3. In the Work with: field, type one of the URLs provided above.
  4. Press Return.
  5. In the Name/Version box below, select the box for Jetty WTP Adaptor Site.
  6. Click Next.
  7. The Install Details dialog box opens.
  8. Click Next again.
  9. The Review Licenses dialog box opens.
  10. Accept the terms and click Finish.
  11. The Installing Software dialog box opens, displaying progress for installing the WTP adaptor. When it completes, the Software Updates dialog box opens with a message that you need to restart Eclipse to complete the installation.
  12. Click Restart Now.

Next step will be create a Jetty WTP Server.  Stay tuned as I will show it in the next post.

Tags: , ,
January 20, 2011

Splash Screen of the Day: Eclipse 1.0

by Jay Jonas
Eclipse 1.0

Eclipse 1.0 Splash Screen - version 1.0

Released at November 7, 2001.  (c) Copyright IBM Corp. 2000, 2001. All Rights Reserved. It can be downloaded in Eclipse Foundation following this link here.

January 17, 2011

Eclipse: Import cannot be resolved

by Jay Jonas

Eclipse suddenly, and everyone is against you (or some) of its import are displaying the error message:

 import MyClassName cannot be resolved.

Do not panic yet. Before, you could try the following tips:

  • Clean Project command is your friend: go to Project > Clean menu.
  • If using Ant or Maven, use – clean option to clean your builds.
  • Refresh your project folder:  right click on your project folder  and click Refresh command.
  • Re-build your project.
  • Create a new Workspace and Import your project there.
  • ‘Switch’ Workspace – go to other Workspace the return back.
  • Double-check your JRE. Remove and re-add as follows:
  1. right click on your Project and click on  Properties from context menu;
  2. click on the Libraries tab;
  3. next, click on the JRE;
  4. click Remove, then OK;
  5. repeat 1-3 again, but this time add the JRE.
  • Finally, if your Target Plataform is divided into components in various folders, double check for duplicate plugins, ie plugins with same ID and version. If find one, remove it  mercilessly.

The tips can be followed in the order you prefer because not have a specific order and can work or not. Do not blame me if not. And make a backup before start.

January 13, 2011

Open a Eclipse View zoomed

by Jay Jonas
public class MyOpenViewZoomedCmdHandler extends AbstractHandler {

    @Override
    public Object execute(ExecutionEvent event) throws ExecutionException {

        IWorkbenchWindow window = HandlerUtil.getActiveWorkbenchWindowChecked(event);

        IWorkbenchPage page = window.getActivePage();

        try {

            // any view in your application
            IViewPart view = page.showView(MyView.VIEW_ID);

            if (!page.isPageZoomed()) {
                IWorkbenchPartReference ref = page.getReference(view);
                page.toggleZoom(ref);
            }
         } catch (PartInitException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return null;
    }
}
January 13, 2011

BIRT: The viewing session is not available or has expired

by Jay Jonas

If you are using…

WebViewer.display()

from a Eclipse RCP View calling to display a BIRT report and your report is open without any problem within the view, I know how much you are happy with BIRT.

However, if when you click on Print Report toolbar command, and  choose HTML print format, you see your report opens in a Internet Explorer window with a exception as follows, maybe you want to read the rest of this post.

This seems to be a Internet Explorer policy with iframe, cookies and cross-site.

read more »