Introducing TrueVFS Extension Insight

The last posting on this blog introduced you to the TrueVFS Archetype Access. This is a Maven archetype which generates a project with a bunch of sample applications for TrueVFS. This time we will slightly adapt the generated project so that we can monitor some nice statistics provided by the TrueVFS Extension Insight.

First, we need to add the extension to the class path. To do so, locate and uncomment the following lines in the file pom.xml:

<dependency>
    <groupId>net.java.truevfs</groupId>
    <artifactId>truevfs-ext-insight</artifactId>
    <version>${truevfs.version}</version>
    <scope>runtime</scope>
</dependency>

Next, we need to adjust the application life cycle so that we actually have a chance to see the plug-in in action before the short running sample applications would normally terminate. To do so, locate and uncomment the following lines in the class com.company.mavenproject1.java.Application:

@Override
protected void sync() throws FsSyncException {
    System.out.println("Waiting until interrupt...");
    try {
        Thread.sleep(Long.MAX_VALUE);
    } catch (InterruptedException ex) {
    }
    super.sync();
}

Now we are all set to see the TrueVFS Extension Insight in action. To do so, build the project and run the main class com.company.mavenproject1.java.file.Tree. When running, simply cancel the upcoming password dialog - we don’t need it for this exercise. This should produce some output like this:

cd C:\Users\christian\Documents\NetBeansProjects\mavenproject1; JAVA_HOME=C:\\Program Files\\Java\\jdk1.7.0_07 M2_HOME=C:\\Program Files\\Apache Software Foundation\\apache-maven-3.0.4 \C:\\Program Files\\Apache Software Foundation\\apache-maven-3.0.4\\bin\\mvn.bat\ -Dexec.args=-classpath %classpath com.company.mavenproject1.java.file.Tree -Dexec.executable=C:\\Program Files\\Java\\jdk1.7.0_07\\bin\\java.exe -Dexec.classpathScope=runtime process-classes org.codehaus.mojo:exec-maven-plugin:1.2:exec
Scanning for projects...

------------------------------------------------------------------------
Building mavenproject1 1.0-SNAPSHOT
------------------------------------------------------------------------

[[resources:resources]]
[debug] execute contextualize
Using 'UTF-8' encoding to copy filtered resources.
skip non existing resourceDirectory C:\Users\christian\Documents\NetBeansProjects\mavenproject1\src\main\resources

[[scala:add-source]]
Add Source directory: C:\Users\christian\Documents\NetBeansProjects\mavenproject1\src\main\scala
Add Test Source directory: C:\Users\christian\Documents\NetBeansProjects\mavenproject1\src\test\scala

[[scala:compile]]
C:\Users\christian\Documents\NetBeansProjects\mavenproject1\src\main\java:-1: info: compiling
C:\Users\christian\Documents\NetBeansProjects\mavenproject1\src\main\scala:-1: info: compiling
Compiling 15 source files to C:\Users\christian\Documents\NetBeansProjects\mavenproject1\target\classes at 1346872235144
prepare-compile in 0 s
compile in 3 s

[[compiler:compile]]
Compiling 12 source files to C:\Users\christian\Documents\NetBeansProjects\mavenproject1\target\classes

[[exec:exec]]
SLF4J: Failed to load class org.slf4j.impl.StaticLoggerBinder.
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
.
|-- nbactions.xml
|-- pom.xml
|-- src
|   `-- main
|       |-- java
|       |   `-- com
|       |       `-- company
|       |           `-- mavenproject1
|       |               `-- java
|       |                   |-- Application.java
|       |                   |-- diagnostics
|       |                   |   `-- DriverMap2Html.java
|       |                   |-- file
|       |                   |   |-- Cat.java
|       |                   |   |-- Copy.java
|       |                   |   |-- HelloWorld.java
|       |                   |   |-- Pickr.java
|       |                   |   `-- Tree.java
|       |                   `-- path
|       |                       |-- Cat1.java
|       |                       |-- Cat2.java
|       |                       |-- Copy.java
|       |                       |-- HelloWorld.java
|       |                       `-- Tree.java
|       `-- scala
|           `-- com
|               `-- company
|                   `-- mavenproject1
|                       `-- scala
|                           |-- Application.scala
|                           |-- file
|                           |   `-- Tree.scala
|                           `-- path
|                               `-- Tree.scala
|-- target
|   |-- classes
|   |   `-- com
|   |       `-- company
|   |           `-- mavenproject1
|   |               |-- java
|   |               |   |-- Application.class
|   |               |   |-- diagnostics
|   |               |   |   |-- DriverMap2Html$1.class
|   |               |   |   `-- DriverMap2Html.class
|   |               |   |-- file
|   |               |   |   |-- Cat.class
|   |               |   |   |-- Copy.class
|   |               |   |   |-- HelloWorld.class
|   |               |   |   |-- Pickr$1.class
|   |               |   |   |-- Pickr.class
|   |               |   |   `-- Tree.class
|   |               |   `-- path
|   |               |       |-- Cat1.class
|   |               |       |-- Cat2.class
|   |               |       |-- Copy.class
|   |               |       |-- HelloWorld.class
|   |               |       `-- Tree.class
|   |               `-- scala
|   |                   |-- Application.class
|   |                   |-- file
|   |                   |   |-- Tree$$anonfun$com$company$mavenproject1$scala$file$Tree$$graph$1.class
|   |                   |   |-- Tree$$anonfun$com$company$mavenproject1$scala$file$Tree$$graph$2.class
|   |                   |   |-- Tree$$anonfun$work$1.class
|   |                   |   |-- Tree$.class
|   |                   |   `-- Tree.class
|   |                   `-- path
|   |                       |-- Tree$$anon$1$$anonfun$1.class
|   |                       |-- Tree$$anon$1.class
|   |                       |-- Tree$$anonfun$com$company$mavenproject1$scala$path$Tree$$graph$1.class
|   |                       |-- Tree$$anonfun$com$company$mavenproject1$scala$path$Tree$$graph$2.class
|   |                       |-- Tree$$anonfun$work$1.class
|   |                       |-- Tree$.class
|   |                       `-- Tree.class
|   |-- classes.1644408872.timestamp
|   `-- generated-sources
|       `-- annotations
`-- test.zip
    |-- readme.txt
    |-- test.jar
    |   `-- readme.txt
    |-- test.tar
    |   `-- readme.txt
    |-- test.tar.bz2
    |   `-- readme.txt
    |-- test.tar.gz
    |   `-- readme.txt
    |-- test.tar.xz
    |   `-- readme.txt
    `-- the-password-is-test1234.tzp
Waiting until interrupt...

Do not (yet) interrupt or kill the application!

Note the archive file test.zip in the directory tree. This is obviously a ZIP file which contains some other archive files for testing purposes. Next, please fire up JVisualVM in order to interface with the TrueVFS Extension Insight via JMX. Once started, connect to the process for the main class we’re just running and select the MBeans tab. In this tab, expand the node net.java.truevfs.ext.insight and all its sub nodes and then select the node FsManager. The result should look similar to this:

On the right side there is a panel with attributes of the file system manager. Explaining them all is more than feasible for this post, but please try hovering the mouse over any of them to display a descriptive tool tip.

Next, please switch to the Operations tab in the panel on the right hand side and click on the sync() button twice. Each time you should get a dialog with the message “Method successfully invoked”. Now click on the Attributes tab again and spot the difference:

Some attributes have reduced their values as an implication of the sync() (for some explanation, please check this posting). But there’s more: Two nodes with numeric names have appeared under the nodes Application I/O, Buffer I/O and Kernel I/O - one for each time you have clicked sync()!

What happened is that each time sync() was run, a new statistics object for the respective I/O activity gets added - up to a maximum of ten objects. After ten sync()s, the objects get rotated in the same manner like logging files. So the object with the number zero always holds the current (mutable) statistics, while the object with the highest number holds the eldest (now immutable) statistics. Note that this rotation is applied whenever the file system manager is told to sync() its mounted file systems, regardless if this is done by the GUI or by the application code.

Finally, let’s have a look at the Kernel I/O statistics object with the number two:

As you can see, the TrueVFS Kernel has done some read operations in two different threads. This was done to mount the virtual file systems from the archive files.

That’s it for now. Please  experiment with the plug-in and have a look at the other statistics objects, too.

Enjoy!