Monday, 5 December 2011

Java VM


Monitoring and Management of the Java Virtual Machine
The JMX technology can also be used to monitor and manage the Java virtual machine (Java VM).
The Java VM has built-in instrumentation that enables you to monitor and manage it by using the JMX technology. These built-in management utilities are often referred to as out-of-the-box management tools for the Java VM. To monitor and manage different aspects of the Java VM, the Java VM includes a platform MBean server and special MXBeans for use by management applications that conform to the JMX specification.

Platform MXBeans and the Platform MBean Server

The platform MXBeans are a set of MXBeans that is provided with the Java SE platform for monitoring and managing the Java VM and other components of the Java Runtime Environment (JRE). Each platform MXBean encapsulates a part of Java VM functionality, such as the class-loading system, just-in-time (JIT) compilation system, garbage collector, and so on. These MXBeans can be displayed and interacted with by using a monitoring and management tool that complies with the JMX specification, to enable you to monitor and manage these different VM functionalities. One such monitoring and management tool is the Java SE platform's JConsole graphical user interface (GUI).
The Java SE platform provides a standard platform MBean server in which these platform MXBeans are registered. The platform MBean server can also register any other MBeans you wish to create.

JConsole

The Java SE platform includes the JConsole monitoring and management tool, which complies with the JMX specification. JConsole uses the extensive instrumentation of the Java VM (the platform MXBeans) to provide information about the performance and resource consumption of applications that are running on the Java platform.

Out-of-the-Box Management in Action

Because standard monitoring and management utilities that implement the JMX technology are built into the Java SE platform, you can see the out-of-the-box JMX technology in action without having to write a single line of JMX API code. You can do so by launching a Java application and then monitoring it by using JConsole.

Monitoring an Application by Using JConsole

This procedure shows how to monitor the Notepad Java application. This procedure assumes that you are running the Java SE 6 platform.
  1. Start the Notepad Java application, by using the following command in a terminal window:
    java -jar jdk_home/demo/jfc/Notepad/Notepad.jar
    Where jdk_home is the directory in which the Java Development Kit (JDK) is installed.
  2. Once Notepad has opened, in a different terminal window, start JConsole by using the following command:
    jconsole
    A New Connection dialog box is displayed.
  3. In the New Connection dialog box, select Notepad.jar from the Local Process list, and click the Connect button.JConsole opens and connects itself to the Notepad.jar process. When JConsole opens, you are presented with an overview of monitoring and management information related to Notepad. For example, you can view the amount of heap memory the application is consuming, the number of threads the application is currently running, and how much central procesing unit (CPU) capacity the application is consuming.
  4. Click the different JConsole tabs.Each tab presents more detailed information about the different areas of functionality of the Java VM in which Notepad is running. All the information presented is obtained from the various JMX technology MXBeans mentioned in this trail. All the platform MXBeans can be displayed in the MBeans tab. The MBeans tab is examined in the next section of this trail.
  5. To close JConsole, select Connection -> Exit.

What is JMX


The JMX technology provides developers with a flexible means to instrument Java technology-based applications (Java applications), create smart agents, implement distributed management middleware and managers, and smoothly integrate these solutions into existing management and monitoring systems.
  • The JMX technology enables Java applications to be managed without heavy investment.
    A JMX technology-based agent (JMX agent) can run on most Java technology-enabled devices. Consequently, Java applications can become manageable with little impact on their design. A Java application needs only to embed a managed object server and make some of its functionality available as one or several managed beans (MBeans) registered in the object server. That is all it takes to benefit from the management infrastructure.
  • The JMX technology provides a standard way to manage Java applications, systems, and networks.
    For example, the Java Platform, Enterprise Edition (Java EE) 5 Application Server conforms to the JMX architecture and consequently can be managed by using JMX technology.
  • The JMX technology can be used for out-of-the-box management of the Java VM.
    The Java Virtual Machine (Java VM) is highly instrumented using the JMX technology. You can start a JMX agent to access the built-in Java VM instrumentation, and thereby monitor and manage a Java VM remotely.
  • The JMX technology provides a scalable, dynamic management architecture.
    Every JMX agent service is an independent module that can be plugged into the management agent, depending on the requirements. This component-based approach means that JMX solutions can scale from small-footprint devices to large telecommunications switches and beyond. The JMX specification provides a set of core agent services. Additional services can be developed and dynamically loaded, unloaded, or updated in the management infrastructure.
  • The JMX technology leverages existing standard Java technologies.
    Whenever needed, the JMX specification references existing Java specifications, for example, the Java Naming and Directory Interface (J.N.D.I.) API.
  • The JMX technology-based applications (JMX applications) can be created from a NetBeans IDE module.
    You can obtain a module from the NetBeans Update Center (select Tools -> Update Center in the NetBeans interface) that enables you to create JMX applications by using the NetBeans IDE. This reduces the cost of development of JMX applications.
  • The JMX technology integrates with existing management solutions and emerging technologies.
    The JMX APIs are open interfaces that any management system vendor can implement. JMX solutions can use lookup and discovery services and protocols such as Jini network technology and the Service Location Protocol (SLP).

How to generate Enterprise Java Beans with EJBDoclet (XDoclet)


EJBDoclet is a tool that facilitates coding Enterprise Java Beans. You only have to code one file to generate automatically the needed interfaces and descriptor files. By using ant and theverifier it is very easy to produce correct beans.
EJBDoclet is an OpenSource project started by Rickard Oberg and located at http://sourceforge.net/projects/ejbdoclet.
EJBDoclet has been renamed XDoclet and a new project with this name has been started. XDoclet 1.0 was released in September 2001. Any questions about EJBDoclet and XDoclet must go to the new XDoclet mailing lists hosted at http://sourceforge.net/projects/xdoclet

Requirements

You need to download the ejbdoclet.jar file and put it somewhere in you classpath. I think that the use of Ant is highly recommended (and, for now, it is the only way to use EJBDoclet!).
The tools.jar file from the J2SDK is also needed to call Javadoc, so place it in the classpath, too.

Creating the Bean as a Template

EJBDoclet uses Javadoc tags and the Javadoc mechanism to generate the needed files out of a template. Here there is an example of a section for an Entity Bean class:
/**
 *   This is an account bean. It is an example of how to use the EJBDoclet tags.
 *
 *   @ejb:entity-cmp 1
 *   @ejb:ejb-name bank/Account
 *   @ejb:jndi-name ejb/bank/Account
 *   @ejb:finder Collection findAll() 2
 *   @ejb:finder Collection findByOwner(Customer owner)
 *   @ejb:finder Collection findLargeAccounts(int balance)
 *   @ejb:env-entry foo 1234 java.lang.Integer 3
 *   @ejb:ejb-ref bank/Customer 4
 *   @ejb:security-role-ref admin Administrator
 *   @ejb:permission Teller
 *   @ejb:transaction Required
 *   @ejb:use-soft-locking
 *
 *   JBoss specific 5
 *   @jboss:container-configuration Standard CMP EntityBean
 *
 *   JBoss/JAWS CMP specific 6
 *   @jboss:table-name account
 *   @jboss:create-table true
 *   @jboss:remove-table true
 *   @jboss:tuned-updates true
 *   @jboss:read-only false
 *   @jboss:finder-query findLargeAccounts $1 > 1000
 *   @jboss:finder-order findLargeAccounts balance
 */
public abstract class AccountBean
{
      
1
Here is where it is specified that this is an Entity Bean
2
Definitions of the finder methods
3
Easy definition of environment variables
4
Definition of references to other beans
5
With these tags you can define JBoss-specific parameters (see the EJBDoclet documentation for more details about the tags).
6
And here you can define JAWS-specific parameters (see the EJBDoclet documentation for more details about the tags).
You can see that it is very easy to create the bean template. The JBoss- and JAWS-specific parts should only be used if the JBoss standard values do not fit.
Now you need to define the method level tags like this:
/**
    * Create account.
    *
    * @ejb:permission Administrator 1
    */
   public AccountPK ejbCreate(AccountData data)
      throws CreateException
   {
      setId(data.getId());
      setData(data);

      return null;
   }

   /**
    * Id of this account.
    *
    * This is not remote since the primary key can be extracted by other means.
    *
    * @ejb:pk-field 2
    * @ejb:persistent-field
    *
    * @jboss:column-name pk
    */
   public abstract int getId();

   /**
    * Id of this account.
    *
    */
   public abstract void setId(int id);

   /**
    *  Owner of this account.
    *
    * @ejb:remote-method 3
    * @ejb:persistent-field 4
    * @ejb:permission Administrator
    * @ejb:transaction Supports
    */
   public abstract Customer getOwner();

   /**
    *  Owner of this account.
    *
    */
   public abstract void setOwner(Customer owner);
      
1
Permissions can be defined at the method level with this tag
2
With @ejb:pk-field a primary key field is defined
3
@ejb:remote-method defines a remote method
4
An @ejb:persistent-field defines an attribute that should be stored persistently.

Calling EJBDoclet

For now there is no way to use EJBDoclet without Ant.

Using EJBDoclet with Ant

To use Ant you must download it from the Apache Jakarta project. For EJBDoclet only the ant.jar file is needed.
I prefer a project directory structure like the one JBoss uses:
project
        +-build
        .  +-[...]
        +-dist
        .  +-[...]
        +-lib
        .  +-ant.jar
        .  +-ejbdoclet.jar
        .  +-[...]
        +-src
        .  +-resources
        .  .  +-test
        .  .  .  +-META-INF
        .  +-main
        .  .  +-test
        .  .  .  +-ejb
        .  .  .  .  +-AccountBean.java
        .  .  .  .  +-CustomerBean.java
      
Here it is my Ant script (build.xml) that first generates the bean interfaces and the descriptor files and then compiles the Java files and packages them into a JAR file:
<?xml version="1.0" encoding="ISO-8859-1"?>
<!--
 $Revision: 1.2 $ $Date: 2002/12/19 14:48:24 $ $Author: cvsuser $
-->
<project name="test" default="main" basedir="../..">

   <target name="init">
      <property name="Name" value="TEST"/>
      <property name="name" value="test"/>
      <property name="version" value="1.0"/>
      <property name="encoding" value="ISO-8859-1"/>
      <property name="typemapping" value="Hypersonic SQL"/>
      <property name="datasource" value="java:/DefaultDS"/>

      <property name="src.dir" value="${basedir}/src/main"/>
      <property name="src.resources" value="${basedir}/src/resources"/>
      <property name="etc.dir" value="${basedir}/src/etc"/>
      <property name="lib.dir" value="${basedir}/lib"/>
      <property name="build.dir" value="${basedir}/build"/>
      <property name="build.lib.dir" value="${basedir}/build/lib"/>
      <property name="build.deploy.dir" value="${basedir}/build/deploy"/>
      <property name="build.classes.dir" value="${basedir}/build/classes"/>
      <property name="build.client.dir" value="${basedir}/build/client"/>
      <property name="dist.dir" value="dist"/>
      <property name="classpath" value="${lib.dir}/jboss-j2ee.jar;${lib.dir}/jta-spec1_0_1.jar" />
      <property name="packages" value="test"/>
      <taskdef name="ejbdoclet" classname="ejbdoclet.EJBDocletTask"
               classpath="${basedir}/lib/ejbdoclet.jar" />
<!--      <property name="build.compiler" value="jikes"/>-->
   </target>

   <target name="prepare" depends="init">
      <mkdir dir="${build.dir}"/>
   </target>

  <!-- =================================================================== -->
  <!-- Creates the Bean Classes with EJBDoclet                             -->
  <!-- =================================================================== -->
   <target name="buildbeans" depends="prepare">

      <mkdir dir="${src.resources}/test"/>
      <mkdir dir="${src.resources}/test/META-INF"/>
      <!-- Call EJBDoclet -->
      <ejbdoclet sourcepath="${src.dir}"
                 destdir="${src.dir}"
                 packagenames="test"
                 classpath="${classpath};${basedir}/lib/ejbdoclet.jar"
                 ejbspec="1.1"
                 excludedtags="@version,@author">
        <dataobject/>
        <remoteinterface/>
        <homeinterface/>
        <entitypk/>
        <entitycmp/>
        <deploymentdescriptor xmlencoding="${encoding}"/>
        <jboss xmlencoding="${encoding}"
               typemapping="${typemapping}"
               datasource="${datasource}"/>
      </ejbdoclet>

      <!-- copy the generated descriptor files in the resources directory -->
      <copy file="${src.dir}/ejb-jar.xml" todir="${src.resources}/test/META-INF" />
      <copy file="${src.dir}/jboss.xml" todir="${src.resources}/test/META-INF" />
      <copy file="${src.dir}/jaws.xml" todir="${src.resources}/test/META-INF" />
      <delete>
         <fileset dir="${src.dir}" includes="*.xml"/>
      </delete>
   </target>

  <!-- =================================================================== -->
  <!-- Compiles the source code                                            -->
  <!-- =================================================================== -->
   <target name="compile" depends="prepare">
    <mkdir dir="${build.classes.dir}"/>
    <javac srcdir="${src.dir}"
           destdir="${build.classes.dir}"
           classpath="${classpath}"
           debug="off"
           deprecation="off"
           optimize="on"
           includes="**/*.java"
           excludes="**/*.jbx"
    />
   </target>

  <!-- =================================================================== -->
  <!-- Creates the jar archives                                            -->
  <!-- =================================================================== -->
  <target name="jar" depends="compile">
    <mkdir dir="${build.client.dir}"/>
    <mkdir dir="${build.lib.dir}"/>
    <mkdir dir="${build.deploy.dir}"/>

    <!-- Create Bean jar -->
    <copy todir="${build.classes.dir}">
       <fileset dir="${src.resources}/test" includes="**/*.xml"/>
    </copy>
    <jar jarfile="${build.deploy.dir}/test.jar"
         basedir="${build.classes.dir}"
         includes="test/**/*.class,
                   META-INF/**"
    />
    <delete>
       <fileset dir="${build.classes.dir}/META-INF" />
    </delete>

  </target>

  <!-- =================================================================== -->
  <!-- Verify Beans                                                        -->
  <!-- =================================================================== -->
  <target name="verify" depends="jar">
    <java classname="org.jboss.verifier.Main" fork="true" failonerror="true">
      <classpath path="${classpath}"/>
      <arg value="${build.deploy.dir}/test.jar"/>
    </java>
  </target>

  <!-- =================================================================== -->
  <!-- Creates the binary structure                                        -->
  <!-- =================================================================== -->
   <target name="main" depends="verify">
     <mkdir dir="${dist.dir}"/>
     <mkdir dir="${dist.dir}/bin"/>
     <mkdir dir="${dist.dir}/lib"/>
     <mkdir dir="${dist.dir}/deploy"/>
     <mkdir dir="${dist.dir}/client"/>
     <mkdir dir="${dist.dir}/conf"/>
     <mkdir dir="${dist.dir}/images"/>

     <copy todir="${dist.dir}/client">
        <fileset dir="${build.client.dir}"/>
     </copy>
     <copy todir="${dist.dir}/lib">
        <fileset dir="${build.lib.dir}"/>
     </copy>
     <copy todir="${dist.dir}/deploy">
        <fileset dir="${build.deploy.dir}"/>
     </copy>
     <copy todir="${dist.dir}/lib">
        <fileset dir="${src.resources}/test" includes="*.properties"/>
     </copy>
     <copy todir="${dist.dir}/conf">
        <fileset dir="${etc.dir}/conf"/>
     </copy>

     <copy file="${src.lib}/connector.jar" todir="${dist.dir}/client" />
     <copy file="${src.lib}/deploy.jar" todir="${dist.dir}/client" />
     <copy file="${src.lib}/jboss-j2ee.jar" todir="${dist.dir}/client" />
     <copy file="${src.lib}/jboss-client.jar" todir="${dist.dir}/client" />
     <copy file="${src.lib}/jbosssx-client.jar" todir="${dist.dir}/client" />
     <copy file="${src.lib}/jbossmq-client.jar" todir="${dist.dir}/client" />
     <copy file="${src.lib}/jndi.jar" todir="${dist.dir}/client" />
     <copy file="${src.lib}/jnp-client.jar" todir="${dist.dir}/client" />
     <copy file="${src.lib}/jta-spec1_0_1.jar" todir="${dist.dir}/client" />
     <copy file="${src.lib}/stop.jar" todir="${dist.dir}/client" />
     <copy file="${src.lib}/jaas.jar" todir="${dist.dir}/client" />
     <copy file="${src.lib}/auth.conf" todir="${dist.dir}/client" />
     <copy file="${src.lib}/jlfgr-1_0.jar" todir="${dist.dir}/client" />

     <copy file="${etc.dir}/conf/jndi.properties" todir="${dist.dir}/client" />

   </target>

  <!-- =================================================================== -->
  <!-- Cleans up generated stuff                                           -->
  <!-- =================================================================== -->
  <target name="clean" depends="init">
    <delete dir="${build.dir}"/>
    <delete dir="${dist.dir}"/>
  </target>

</project>
      
I have split the generation of the beans and the creation of the application in separate tasks. To generate the beans, call build buildbeans and to create the application, call build.
EJBDoclet throws some Exceptions the first time it is called, but they can be ignored.
The build.xml file generates first the PrimaryKey and DataObject classes, Home and Remote interfaces and the ejb-jar.xmljboss.xml and jaws.xml descriptors. The Java files are then compiled into the build/classes directory. After that, the files will be archived in test.jar in directory dist/deploy. Now the JAR file can be deployed in JBoss.
If you are either specifying ejbspec="2.0" or nothing (the default is 2.0), it is possible that JBoss will not find the DTDs defined in the deployment descriptors; in that case, just remove those lines or comment them out. For my own use, I have changed the EJBDoclet templates to avoid generating those lines.

Using Verifier in Ant


When deploying the Enterprise JavaBeans, JBoss attempts to verify each bean against the specification to make sure the Bean Developer has fulfilled her contract to implement all the required interfaces. The verifier goes through both session and entity beans making sure the method descriptors do not violate the specification, RMI/IIOP requirements are met, the relevant parts of the deployment descriptor are correct, and so forth.

It is also possible to use the verifier as part of your build process. Using Ant to build your project enables you to verify your Enterprise JavaBeans as you compile them. This removes the extra step of deploying just to verify your ejb-jar file is compliant and deploys correctly in the container. In case of spec violations, you can optionally stop the build process and rework your files to meet the specification requirements. This Howto explains the setup you need to verify your beans early rather than late.

Getting the required files

To use the verifier in Ant you will need two jars copied from the JBoss distribution to your build directory: verifier.jar and metadata.jar. You will find the verifier.jar file in the/dist/bin directory of your JBoss installation, and the metadata.jar in the /dist/external directory.
If you are using the CVS version of JBoss, you can build both of the above mentioned files by executing
src/build> build verifier
in the /src/build directory. This will generate the required packages to the correct directories.

Edit build.xml

A custom verifier task for Ant does not exist at the moment but you can execute the verifier from Ant by creating a new JVM for it using Ant's built in <java> task. For the most up to date information of using the <java> tag, see Ant online documentation.
Below is an example of using the <java> tag to execute the verifier:
<!-- verify the EJBs -->
        <java classname = "org.jboss.verifier.Main" fork="true">
            <classpath refid = "classpath"/>
            <arg value = "${dist.home}/admin.jar"/>
        </java>
      

Saturday, 3 December 2011

Integrating NetBeans/Forte for Java Community Edition


Integrating NetBeans/Forte for Java Community Edition with JBoss for source level debugging

Purpose

This howto is a first pass at illustrating the procedures required to use NetBeans to develop and debug EJBs running within JBoss. It will also discuss how to make the JBoss source available so that debugging can include JBoss code. It is not the purpose of this howto to describe how to develop and debug the JBoss code.
Because Sun's Forte for Java and NetBeans share much of their source code, this howto should be applicable to users in that environment as well.

Install the JBoss Server

For the purpose of this howto, I installed the JBossTomcat release version 2.4.4/3.2.3 into /opt/appserver on my linux box. If you translate the steps into Windows NT/2000 you can also debug JBoss apps using Netbeans there. Download it from http://www.jboss.org and select the binary link from the page. Don't worry about downloading a binary package, when all you want is the source code; the binary package also contains the source code used for building.

Create a NetBeans Project

Start NetBeans, I used NetBeans 3.3 while writing this howto. The first step is to create a new project or open an existing project. You create a new project from the Project -> Project Manager menu selection. This dialog will show a list of your projects like:

Mount the JBoss client jarfiles

This is a bit tedious, though it's not too bad. Once you have opened your project you should go to the explorer window and select the FileSystems tab. Either right click on the FileSystems entry in the explorer window, or choose File -> Mount Filesystem and pick mount jar. Use the browser or type in the path for the following jar files: jboss/lib/ext/jboss-j2ee.jar and jboss/lib/jboss-jdbc_ext.jar. If you are using JBossSX security then you'll also need to add additional jar files jboss/lib/jaas.jar, jboss/lib/jboss-jaas.jar and jboss/lib/ext/jbosssx.jar. If you are using JMS from your client you'll also need to add jboss/lib/ext/jbossmq-client.jar. Once you have added all these jar files a if you don't want them to show in the explorer you can right click on them one by one and from the properties panel select hidden=true.
At this point you need to add any other jar files specific to your app which need to be available to compile your project, e.g. log4j.jar if you are using the Apache logging framework.

Complete your project and build your jar/war files

Now you should be able to mount the directory containing your source code and compile it by right clicking on the root package and selecting compile all.
In order to build a jarfile from which to deploy your EJBs you'll need to add a new jar packager element to your project. Select File -> New and then from the Wizard select Jar Packager -> Jar Contents. This will take you into the Jar Packager wizard. It will allow you to specify the name of the jarfile, select and filter the contents of mounted filesystems for inclusion in the jarfile, and the output directory for the jarfile.
I have never seen POSIX filters before myself, there is good help available within NetBeans. The short version is that a filter to include .class files is \.class$. You could include .class and .xml files with a filter like (\.class$)|(\.xml$). See the online help for more details.
You will need to make sure that you include all required .class files as well as deployment descriptors in the META-INF directory. You right click on the Jar Contents and select "compile" to create the jar file.
After you have built the deployable jar file or war file you can deploy it into your JBoss server. If you want NetBeans to deploy the jar/war file for you then make the output location the jboss/deploy directory and you'll be on your way. Otherwise you'll need to manually copy it from where NetBeans writes it to the jboss/deploy directory.

Setup JBoss for debugging

Since these instructions are not for debugging JBoss so much as an application running in JBoss, at the moment the instructions will start JBoss from the command line and then attach the debugger. At some point in the future we can augment these instructions with instructions to launch JBoss from within NetBeans.
Make the following changes to your run.bat/run.sh file, or copy run.bat/run.sh to a new file debug.bat/debug.sh and paste the text in. This text is the Windows version, the UNIX version should use $env-var instead of %env-var%. Change the command line from:
java %JAXP% -classpath %JBOSS_CLASSPATH% org.jboss.Main ...
to: (as a single command line)
java -Xint -Xdebug -Xnoagent -classpath "%JBOSS_CLASSPATH%" -Xrunjdwp:transport=dt_socket,server=y,address=12999,suspend=n org.jboss.Main %1 %2 %3 %4 %5 %6 %7 %8 %9
The -Xint switch disables hotspot optimizations. This is not strictly necessary, but in my testing with the Win32 JDK 1.3 the JVM seemed more stable with this switch enabled.
You can of course substitute your favorite port for the 12999 in the example.
Once you startup JBoss then you can attach to it from NetBeans to do your debugging. Select the Debug -> Attach menu selection in NetBeans and then the debugger type should be default debugger JPDA. Select the SocketAttach in the connector dropdown and then enter the port number you selected when you edited the debug.bat/debug.sh file. The hostname should default to your local hostname when you select SocketAttach. After you complete filling in the debug "Attach to VM" dialog it should look something like:

Start the JBoss server

Start JBoss using the debug script which you previously created. Deploy the EJBs you'd like to debug. If you want to see your beans being instantiated by the deployer, place breakpoints on the bean constructors (if you specified them) You will not need to have a client running to exercise this functionality.

Sprinkle breakpoints throughout your EJB and or Client Code

Before you can debug, it is necessary to put breakpoints into your code. On the client side you can just open up your source files and toggle breakpoints as in any other Netbeans debugging effort. To put breakpoins into your ejb's is different. You will need to use the loaded classes menus to select the class and method you would like to break on. Once you have hit a break point within the class, and the source code is displayed, then you can add additional breakpoints. This seems to be an artifact of the class loading scheme used by JBoss, and a problem within NetBeans where it puts a breakpoint on the system classloader when you just open the source file and toggle a breakpoint.

Start the Client Test Application

To really debug your beans you will need to start up a client application. The easiest way to do this is either with a command line client, or else with a servlet/JSP client running inside any embedded or otherwise servlet container. One thing though, the timeouts are somewhat short so if you spend too much time in a method within the EJB you may find that transactions are rolled back.

Usefull NetBeans Shortcuts


It’s been several days that I am relying solely on NetBeans for my PHP and Java coding. So far, it’s beyond my wildest expectations – I am totally satisfied with that great IDE. Today, I have searched for shortcut that would allow me to duplicate a given line, and (fortunately!) came by a great post – Top 10 NetBeans IDE Keyboard Shortcuts. Not only I found the line-duplication thing, I discovered several other pearls which due to unavailability in my previous IDEs, I even didn’t consider to look for.
So, I decided to compile my own list of shortcuts that save me a lot of time during code-sessions.
Shift + Esc Toggle Work-space Maximize/Minimize
Like the original post author, I really like to have as much work-space available for code itself as possible. And when I occasionally need to see one of the supplementary panels (like Files, Project, Navigator etc), I rely mostly on short-cuts, w/o toggling back. So, if I need to view some docking panel I hit one of the following:
Ctrl+1 – Project Window
Ctrl+2 – Files Window
Ctrl+3 – Favorite Window
Ctrl+4 – Output Window
Ctrl+5 – Services window
Ctrl+6 – Tasks Window
and when I am done, Ctrl+0 to get me back to editor. Try for yourself, I am pretty sure, you’d be amazed how much time this saves you, while making coding area less cluttered.
Alt+Enter View fix suggestions
NetBeans makes your life a lot easier, its Java code analyzer does a really solid job. Most of errors are filtered even before compilation – should you see the light bulb on the left of your code, you can review fix suggestions by either clicking on it or (time-saver again!) by just hitting Alt+Enter. I personally enjoy this one, as I prefer to see why IDE is complaining w/o releasing my hands of the keyboard.
Ctrl+F12 Navigate to Member
If your class is too big, then Members View in Navigator (Ctrl+7 remember?) might not be the best option. Just hit Ctrl+F12 and you’d be able to navigate more easily, as it has filter that would eliminate non-matching members while you are typing.
Alt+Insert Generate code
That’s one of my favorites – code generators for getters/setters/constructors are just too sexy to ignore. This shortcut makes them even more usefull.
Ctrl+Shift+ArrowDown Duplicate Line
Duplicating lines never been easier :) If you want a new duplicate to be inserted before the current line, use ArrowUp instead of ArrowDown.
Ctrl+W Close Current Window
Firefox honors this short-cut, as well as Konqueror. So, I even configured my console to use this by default. In no time you’d be accustomed to hit this combination instead of Ctrl+F4.
Ctrl+PgUp and Ctrl+PgDn Navigate through Windows (previous/next)
Again, got used to it from Firefox. Makes it a swift to loop through open documents.
Ctrl+P Display method’s arguments
Within method’s braces hit this combination to see what parameters are there. Comes where handy when reviewing the code.
Ctrl+; Add semicolon to the end of the line w/o leaving current cursor position
If you are working on some code line and NetBeans underlines it red (due to [yet] non-existent semicolon at the end of the line) hitting Ctrl + ; (Ctrl + semicolon) is enough to close the statement, while you are still positioned at the very same place on line. First saw this on dzone.com blog, and really liked using it.
Ctrl+K and Ctrl+L Auto complete with previous/next matched word
I use this combination even more often than Ctrl+Space to auto complete. Listing all items with Ctrl+Spacemight be slow, but hitting Ctrl+K is instant. More than often the variable name you are typing is already typed somewhere in the current file, thus matching it with Ctrl+K or Ctrl+L is probably most obvious thing to do.
Ctrl+E Delete current line
Ctrl+Del and Ctrl+BackSpace Delete next/previous word
I generally use Ctrl+BackSpace, but on some occasions Ctrl+Del also proved userful.
That’s more than enough to get you going. In some time, I plan to write more extensive list  of esoteric shortcuts you rarely use, because you rarely know about them.
And what shortcuts save your time?

Netbeans + PHP Type Hinting


Sometimes, especially when dealing with variations of factory pattern, single method (namely factory()) can return objects of different types, so NetBeans is unable to guess the exact type of returned instance and as such cannot auto-complete. Indeed, you can setup return type using phpDoc syntax:
  1. /** 
  2.  * @return Some_Base_Abstract_Class_Name 
  3.  */  
  4. public function factory($adapter)  
but that doesn’t work if returned objects are specifications of more general abstract class (exactly the case with factory).
As it turned out, you can easily resolve this issue – just document your variable with @var, before calling factory() method:
  1. /** 
  2.  * @var Some_Specific_Class $foo 
  3.  */  
  4. $foo = Magic::factory('adapterName');  
  5. $foo-> // and NetBeans opens pop-up list with available attributes and methods  
The good news, you can use this method in any scope – it just works :) I love NetBeans!!
UPD: Well, actually NetBeans seems to be picky of scope – as reported by others (and confirmed by myself).
UPD1: Actually NetBeans handles this quite well, just use vdoc