Java Random Notes

Until I find time to get more organized, here are a number of miscellaneous notes assembled when I find answers to Java questions and don't want to have to go looking for them again.


The Java Virtual Machine

At its core, the Java virtual machine (JVM) consists of the following components:

  • Heap
  • Stack
  • PermGen and method area
  • Just-in-time (JIT) compiler
  • Code cache

The heap is where memory is allocated for every new operator you use during the application code development stage.

Local variables which remain within the scope of a method are stored on the stack. As a method or block in a method goes out of scope, those variables are removed. (Note too that once Java objects no longer have live references to them, they are garbage-collected.)

PermGen space stores class and method-level data as well as static variables that are defined by the application. A method area is in PermGen and stores all method, field and constant pool details of the application.

The JIT and the code cache go hand-in-hand. The JVM at its core interprets and converts the Java byte code into assembly code at run-time. Interpreting is a relatively slow process because the code is converted from byte code to machine code on the fly every time a portion of your application code is executed. This is where the JIT compiler swings into action:

The JIT compiler analyzes the application code at run-time to understand which methods can be categorized as "hot" methods. Hot means code fragments that are accessed more frequently. Conceptually, the JIT compiler has a counter for each method executed in order to understand the frequency of usage. When the counter's value reaches a defined threshold, the method becomes eligible to be compiled by the JIT compiler to assembly which is then stored in the code cache. From then on, whenever the JIT compiler comes across a call to such a pre-compiled and cached method, it will no longer try to reinterpret it, but will use the already compiled assembly code. This gives the application an obvious performance boost.


Links

Got Java?

Because I work on Linux, in the past years I've migrated to using OpenJDK. However, when I need Sun's Java (no, I don't mean Oracle's—I'm still a little in denial about that), I go to http://java.sun.com. There I can get it for any platform, including Apple Macintosh OS X.

Because I write software in Java, I download a JDK "privately" which is to say that I put it locally to my user, on a path like /home/russ/dev/jdk1.7.0_51. On Macintosh OS X, which I think give one little-to-no say in the matter, this apparently ends up being more like /Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home. (I don't use Macintosh, but one day I might again so this isn't completely irrelevant.)


Script finding and isolating Java version

Here.


Some defintions from Javaland
 
EAR Enterprise archive. An archive containing the enterprise-level Java bean modules.
JAR Java archive. Collection of .class files compiled from .java files plus resources (like properties files) and libraries (more .jar files).
WAR Web archive. Collection of JSPs (.jsp files), .html files, even graphics and other files necessary to the web application.
next definition x.

Utility methods...

A collection of utility methods isn't OOP (with a capital OOP). These methods should be static since their behaviour is not dependent on any specific instance of attributes.


Use of static...

A static variable in a class becomes a single instance for all instantiations of objects of that type. If changed by one, it's changed for all objects. static final will ensure its inability to be modified.

Declare immutable constants as static final. This guards against inadvertant modification and permits the compiler to perform optimizations in the use of those values.


Identifier case...

Use camel-back, lower-case initial in the names of methods and non-constant variables.


Width of characters...

A char cannot be safely converted to byte.


Flow-control...

Never use exceptions for flow-control.


Use of .class...
	String className = ASConfig.class.getName();

Given <class-type> .class. <method>
.class gets the Class object for the class-type and calls the indicated method. In the sample above, the class name is returned.

See http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#15.8.2


Accessors and mutators

..are formal names for getters and setters.


Conversions

int to String

	int      x = 99;
	String   X = Integer.toString( x );
	// or
	String   X = "" + x;

JUnit testing

See junit.html.


Integers in Java
Type Size Range
name bytes bits minimum maximum
byte 1 8 -128 +127
short 2 16 -32,768 +32,767
int 4 32 -2,147,483,648 +2,147,483,647
long 8 64 -9,223,372,036,854,775,808 +9,223,372,036,854,775,807

Instance variable instantiation

Consider the following class and subclass which illustrate a bizarre point of instance variable initialization. It might be a long time if ever someone actually suffers from this problem, but it makes a useful observation on initialization. The explanation here is a bit awkward and over-stated, but clear, I think.

	class Abc
	{
	  public Abc( Object o )
	  {
	    assignValue( o );
	  }

	  public void assignValue( Object o )
	  {
	    // do nothing...
	  }
	}

	public class Test extends Abc
	{
	  public Object x = null;

	  public Test( Object o )
	  {
	    super( o );
	  }

	  public void assignValue(Object o)
	  {
	    x = o;

	    System.out.println( "x in assignValue: " + x );
	  }

	  public static void main( String args[] ) throws CloneNotSupportedException
	  {
	    Test t = new Test( "Test" );

	    System.out.println( "t: " + t.x );
	  }
	}

Output:

	x in assignValue: Test
	t: null

The output happens because the initialization:

	public Object x = null;

executes after the constructor. So...

	x = 0;

gets overwritten by

	public Object x = null;

The secret is that the compiler in fact arranges to call the explicitly invoked superclass constructor before the (local) constructor will get executed.

The initializations done as part of the class instance variable declarations are part of and occur before the (local) construction process. In our example, they occur implicitly before the statements in the (subclass) constructor, with the exception of the superclass constructor invocation as noted.

Therefore, execution order is not straightforward as it is in C. Hence, here the null initialization runs after the local class' call of its superclass constructor. The compiler in essence absorbs the

	super( o );

statement and runs it before any other constructor statements as well as even before applying the initializations stated in the instance variable declarations.

See http://forums.sun.com/thread.jspa?forumID=31&threadID=5260093.


I/O

Here's a good site for sample code: http://www.exampledepot.com/egs/java.io/pkg.html

See also sample code in com.etretatlogiciels.samples.fileio.


The finally clause

Use this to close streams, file handles, database connections, etc. StreamUtils.close() is your short-hand friend for the first case.

	Properties      properties = new Properties();
	FileInputStream is         = null;

	try
	{
	  is = new FileInputStream( path );
	  properties.load( is );
	}
	catch( FileNotFoundException e )
	{
	  System.out.println( e.getMessage() );
	}
	catch( IOException e )
	{
	  System.out.println( e.getMessage() );
	}
	finally
	{
	  StreamUtils.close( is );
	}

PipeStream

Research this class for transforming an input stream into an output stream and vice-versa.


Reader versus Stream

In Java I/O, a file or other device may be opened on a stream and somewhere in the layer cake that wraps the device may be a reader. A reader augments a stream in that it deals with characters (UTF-8, etc.) rather than bytes.


Synchronization in Java

This is not an exhaustive treatment of concurrency solutions in Java. It is a simple treatment, from a C programmer's mentality, of the Java keyword, synchronized. Java uses this keyword in two ways.

Synchronized blocks

The synchronized keyword is used to synchronize a block of executable statements by referring to an object. This object becomes like a mutex in procedural programming languages: executing all other blocks with reference to object is serialized:

	Object object = new Object();

	synchronized( object )
	{
	  do something with object;
	}
How it works

On its face, object is not any kind of mutex, condition variable, reader-writer lock, barrier or other synchronization primitive that you would expect to declare in a procedural language to manage your protected data in parallel. But in fact, every Java object contains a lock within itself. This lock is formally referred to as a monitor. When the compiler sees synchronized in this situation, it generates code to use the object's monitor.


Synchronized methods

The synchronized keyword is also used to synchronize goings on in a method. This is also like controlling execution of the method based on a mutex, but the object is implied this rather than explicit.

	synchronized void makeSomeoneHappy()
	{
	  do something to make someone happy with several objects;
	}

All synchronized methods share the same mutex (this, as noted). The above is directly equivalent to:

	void makeSomeoneHappy()
	{
	  synchronized( this )
	  {
	    do something to make someone happy with several objects;
	  }
	}
Watch out!

A private member variable in a class isn't safe unless all methods touching it are explicitly synchronized. A public member variable would practically never be safe. In the following class, x is safe, but y is not even though their manipulating methods are synchronized.

	public class TwoCounters
	{
	  private int x = 0;
	  public int  y = 0;

	  public synchronized getX() { return this.x; }
	  public synchronized incX() { this.x++;      }
	  public synchronized zeroX(){ this.x = 0;    }

	  public synchronized getY() { return this.y; }
	  public synchronized incY() { this.y++;      }
	  public synchronized zeroY(){ this.y = 0;    }
	}

This is because code outside this class can freely access y whereas an attempt to access x would be rebuffed by the compiler:

	TwoCounters counter = new TwoCounters();

	counter.y = 99;        PASSES COMPILER, BUT A BAD IDEA!
	counter.x = 99;        COMPILATION ERROR!

The distinction between the two methods of synchronization just contrasted is that in the second case, no actual, explicit object is needed in writing the code to perform serialization. There is no need to create object. Instead, the implied object, this, is used.

(Yup, this is absolutely the first time in over a decade of writing HTML that I have used the <blink> tag: very annoying, isn't it?)

Deadlocking

Between correctly synchronized methods in diverse classes deadlocks can easily occur, in particular, the ABBA. The following is the scenario.

  1. Thread A enters a synchronized method for class Foo. It holds the monitor for Foo's this. Let's say that thread A blocks momentarily on some I/O operation.
  2. Thread B enters a synchronized method for class Bar. It holds the monitor for Bar's this. Thread B also knows about the same instance of Foo as thread A and attempts to enter one of Foo's synchronized methods. Foo's monitor is contested because thread A already has it.
  3. Thread A wakes up from its I/O operation and, having a reference to the instance of Bar that thread B already has locked, decides to attempt to enter one of Bar's synchronized methods.
  4. Thread A is blocked on a monitor held by thread B and thread B is blocked on a monitor held by thread A.

This sort of nightmare is best prevented by careful design. The temptation by bad engineers in a procedural language might be to test whether a lock is going to be contested before attempting to use it and, indeed, it is sometimes impossible to do otherwise. However, all efforts to design logic to avoid doing this should be made. Moreover, as noted next, it was not possible prior to Java 1.5 to perform a try-lock.


More traditional locking in Java

Starting (only) in Java 1.5, a new interface, Lock, is provided to mimic not only mutexes in use in other, especially procedural languages, but also try-locking mutexes, condition variables and reader-writer locks.

Without giving an implementation here (because that is how one chooses to implement a mutex versus a condition variable versus a reader-writer or other kind of lock), this example shows how it is used:

	Lock l = new ...();

	l.lock();

	try
	{
	  do something with resources controlled by lock l;
	}
	finally
	{
	  l.unlock();
	}

This usage is unsurprising and recognizable to any C programmer. The reason for this to exist (finally) in Java is that it gives greater flexibility (if also imposing the inelegant coding duty of maintaining the lock just as in C). Using synchronized does not give you the finer control to do something else in the case the object is contested: you are blocked on permanently on the object (explicit object or implicit this) until the thread that has it locked yields it. Hence the utility of this new interface.


Managed beans (and JSF)

In Java, a managed bean is a resource running in the Java virtual machine (JVM) used for getting and setting application configuration (pull); for collecting statistics (also a pull operation), e.g.: performance, resource usage, problems; and notifying events (push), e.g.: faults and state changes.

A good article with much better examples on this topic than those below can be found here.

A standard managed bean often implements a business interface containing setters and getters for the attributes and the operations (or methods). There are other sorts of managed beans.

The managed bean is also involved in inversion of control (dependency injection) and the POJO (plain-old Java object).

Managed beans and JavaServer Faces (JSF)

Before server-side Java development became the norm, developers managed all of their classes manually. Contemporarily, Java server "containers" (like Tomcat) have become responsible for running applications and POJOs have come back into popularity because they are so simple (as compared to Enterprise JavaBeans) and useful for performing dependency injection (formerly called "inversion of control" or IoC). The JSF managed bean facility is also an IoC framework that makes management of JavaBeans or POJOs easy for JSF developers.

Control of instantiation

The first item of business for IoC is being able to manage instantiation of Java objects. Originally, this was done in a page using JSP's <jsp:usebean> that instantiated a bean for a specified scope. This is now done using faces-config.xml and any Java class with a no-argument constructor may be registered. Imagine a POJO thus:

	public class TemperatureConverter
	{
	    private double  celsius    = 0.0;
	    private double  fahrenheit = 0.0;
	    private boolean initial    = true;

	    public double  getCelsius()                 { return celsius; }
	    public void    setCelsius( double celsius ) { this.celsius = celsius; }
	    public double  getFahrenheit()              { return fahrenheit; }
	    public boolean getInitial()                 { return initial; }

	    public String reset()
	    {
	  	    initial    = true;
	  	    fahrenheit = 0;
	  	    celsius    = 0;
	  	    return "reset";
	    }

	    public String celsiusToFahrenheit()
	    {
	  	    initial    = false;
	  	    fahrenheit = ( celsius * 9 / 5 ) + 32;
	  	    return "calculated";
	    }
	}

The dead give-away that this is a bean is:

In faces-config.xml, the bean, which is otherwise coded as above (no surprise) and included in the application as a simple Java object (POJO), is registered thus:

	<managed-bean>
	    <managed-bean-name>   temperatureConverter          </managed-bean-name>
	    <managed-bean-class>  mypackage.TemperatureConverter</managed-bean-class>
	    <managed-bean-scope>  session                       </managed-bean-scope>
	    <managed-property>
	        <property-name>   celsius    </property-name>
	        <value>           37.0       </value>
	    </managed-property>
	    <managed-property>
	        <property-name>   fahrenheit </property-name>
	        <value>           98.6       </value>
	    </managed-property>
	</managed-bean>

temperatureConverter is sort of arbitrarily named, but follows a common convention of dropping the first letter of the class to lower-case (since it is used in JSF as an indentifier).

In addition, the implicit "properties" of the bean, celsius and fahrenheit can be the target of initialization in the same faces-config.xml file as shown in the example above where the imaginary Celsius-to-Fahrenheit calculator will start up set at the temperature of a human body.

faces-config.xml is found in the typical web application at WEB-INF. For example, in Eclipse by default this is project-name/WebContent/WEB-INF/faces-config.xml. In the example above, the Java code is located at project-name/src/mypackage/TemperatureConverter.java.

Dependency handling

The ability to handle interdependence between Java objects is another requirement of IoC. JSF doesn't handle cyclical dependencies, but managed beans can refer to each other using expression language.

Life-cycle support

Another requirement of IoC is support of the life-cycle of, say, HTTP requests and other durations. Hence, JSF defines various levels of...

...granularity. No (none) granularity is when the bean has no scope, is created on the fly and whenever needed. The request is the bean having scope (and managed properties and values) only for the duration of an HTTP request. By session, the bean properties and values remain in effect (modified as many times or none) for an arbitrary length of time or operations as conceived by the developer, for example, a shopping cart that dies after a user has ordered or left the web site. Finally, the application-scoped bean exists while the application is up and running, for example a database connection.

Configuration support

The primary task of JSF is to present a web interface to a client that is predictably and automatically synchronized with one or a set of managed objects without extensive, spaghetti-like and difficult coding.


System properties

Much is configurable in Java and:

	String property = System.getProperty( property-name);

...is how a property is got. There are three ways they are set.

First, Sun sets them, like java.io.tmpdir, predefined, in its JRE. Other JREs do too and, from platform to platform, there is sometimes the tiniest bit of non-conformance.

Second, you can set them yourself using the command line:

	# java  -Dhow.i.feel=blue  MyClass

Last, you can set them programmatically:

	String libraries = System.getProperty( "java.library.path" );

	if( libraries != null && libraries.length() != 0 )
	  libraries += ":" + "/home/russ/dev/libs";
	else
	  libraries = "/home/russ/dev/libs";

	System.setProperty( "java.library.path", libraries );

File.createTempFile()

A temporary file is created in java.io.tmpdir:

	File f = File.createTempFile( "fun", ".poo" );

	System.out.println( "Just created file "
	                    + f.getName()
	                    + " in directory "
	                    + System.getProperty( "java.io.tmpdir" )
	                   );


The ternary operator

The ternary operator in Java is problematic, having trouble with mixed, ambiguous or unclear typing in places where humans do not.

In the example, a compile-time error is generated. In order to force understanding on the compiler, use parentheses as shown in the subsequent line. This forces evaluation of the expression before settling on what type is its result.

Type mismatch: cannot convert from String to boolean.
	Double x = 9.0;

	System.out.println( "This is a " + ( x == 9.9 ) ? "test" : "cat" + " of the Emergency Broadcast System" );

	/* fixed: */
	System.out.println( "This is a " + ( ( x == 9.9 ) ? "test" : "cat" ) + " of the Emergency Broadcast System" );

Viewing the contents of a JAR

Dump the particulars including class list for a JAR. If binary jar isn't on $PATH, find it in the JDK under the bin subdirectory. The options are mostly identical to tar:

	[email protected]:~/dev/downloads/myfaces-core-1.2.8/lib> jar tvf myfaces-impl-1.2.8.jar
	META-INF/
	META-INF/MANIFEST.MF
	META-INF/services/
	javax/
	javax/faces/
	org/
	org/apache/
	org/apache/myfaces/
	org/apache/myfaces/event/
	org/apache/myfaces/taglib/
	org/apache/myfaces/taglib/core/
	org/apache/myfaces/taglib/html/
	org/apache/myfaces/convert/
	org/apache/myfaces/portlet/
	.
	.
	.
	META-INF/NOTICE.txt
	META-INF/standard-faces-config.xml
	META-INF/myfaces_core.tld
	META-INF/myfaces_html.tld
	META-INF/LICENSE.txt
	META-INF/myfaces-metadata.xml
	javax/faces/Messages_pl.properties
	javax/faces/Messages_ru.properties
	javax/faces/Messages_ja.properties
	javax/faces/Messages_mt.properties
	javax/faces/Messages_it.properties
	javax/faces/Messages_ca.properties
	javax/faces/Messages.properties
	javax/faces/Messages_en.properties
	.
	.
	.
	org/apache/myfaces/taglib/core/ValidateDoubleRangeTag.class
	org/apache/myfaces/taglib/core/SetPropertyActionListenerTag.class
	org/apache/myfaces/taglib/core/LoadBundleTag.class
	org/apache/myfaces/taglib/core/ConvertNumberTag.class
	org/apache/myfaces/taglib/core/PhaseListenerTag$BindingPhaseListener.class
	org/apache/myfaces/taglib/core/ValidatorImplTag.class
	org/apache/myfaces/taglib/core/SubviewTag.class
	org/apache/myfaces/taglib/core/GenericListenerTag.class
	org/apache/myfaces/taglib/core/ConverterImplTag.class
	org/apache/myfaces/taglib/core/LoadBundleTag$BundleMap.class
	org/apache/myfaces/taglib/core/SelectItemTag.class
	org/apache/myfaces/taglib/core/ActionListenerTag.class
	org/apache/myfaces/taglib/core/GenericMinMaxValidatorTag.class
	org/apache/myfaces/taglib/core/DelegateConverter.class
	org/apache/myfaces/taglib/core/ConvertDateTimeTag.class
	org/apache/myfaces/taglib/core/SelectItemsTag.class
	org/apache/myfaces/taglib/core/VerbatimTag.class
	.
	.
	.
	org/apache/myfaces/webapp/StartupServletContextListener.class
	.
	.
	.
	org/apache/myfaces/application/jsp/ViewResponseWrapper$WrappedServletOutputStream.class
	org/apache/myfaces/application/MyfacesStateManager.class
	org/apache/myfaces/application/TreeStructureManager$TreeStructComponent.class
	org/apache/myfaces/application/ApplicationFactoryImpl.class
	org/apache/myfaces/application/DefaultViewHandlerSupport.class
	org/apache/myfaces/application/ActionListenerImpl.class
	META-INF/maven/
	META-INF/maven/org.apache.myfaces.core/
	META-INF/maven/org.apache.myfaces.core/myfaces-impl/
	META-INF/maven/org.apache.myfaces.core/myfaces-impl/pom.xml
	META-INF/maven/org.apache.myfaces.core/myfaces-impl/pom.properties

Runnable (stand-alone) JUnit testing

To run from the command line a JUnit test you've created, you need a main() method to call it. Create your JUnit test class as normal, here, FunTest, create another class with a public static void main( String[] args ) inside that calls it thus:

    import junit.textui.TestRunner;

    public class RunnableFunTest
    {
        public static void main( String[] args )
        {
            TestRunner.run( FunTest.class );
        }
    }

Obviously, when you run this from the command line, you'll also have to make allowances for the JUnit JAR (library) to be present.


Enabling Java assertions...

Java assertions have nothing to do with JUnit. In order to enable them, add -ea (or, -enableassertions) to the Java command line, to the launch configuration in Eclipse or as a default VM argument in the installed JRE (Preferences -> Java -> Installed JREs (select a JDK/JRE) Edit.


Encapsulation is...

...these three things, most importantly:

  1. Separation of concerns, a phrase borrowed from Edsger Djikstra, 1975.

    "Let me try to explain to you, what to my taste is characteristic for all intelligent thinking. It is, that one is willing to study in depth an aspect of one's subject matter in isolation for the sake of its own consistency, all the time knowing that one is occupying oneself only with one of the aspects. We know that a program must be correct and we can study it from that viewpoint only; we also know that it should be efficient and we can study its efficiency on another day, so to speak. In another mood we may ask ourselves whether, and if so: why, the program is desirable. But nothing is gained —on the contrary!— by tackling these various aspects simultaneously. It is what I sometimes have called "the separation of concerns", which, even if not perfectly possible, is yet the only available technique for effective ordering of one's thoughts, that I know of."

    An object's information (data) is separate from its interfaces.

  2. Information-hiding, a term borrowed from David Parnas, 1972.

    "We have tried to demonstrate by these examples that it is almost always incorrect to begin the decomposition of a system into modules on the basis of a flowchart. We propose instead that one begins with a list of difficult design decisions or design decisions which are likely to change. Each module is then designed to hide such a decision from the others."

    C.f. Java's private and, to a lesser extent, protected modifiers.

  3. Ripple effects, a term borrow from Wayne Stevens, 1974.

    "The fewer and simpler the connections between modules, the easier it is to understand each module without reference to other modules. Minimizing connections between modules also minimises the paths along which changes and errors can propagate into other parts of the system, thus eliminating disastrous, 'Ripple effects,' where changes in one part causes errors in another, necessitating additional changes elsewhere, giving rise to new errors, etc."

    I.e.: coupling and cohesion.

Problems with supposed encapsulation

Encapsulation is popularly implemented through usage of private attributes with accessors. Using this method to achieve encapsulation when the attribute is a java.util.Collection, java.util.Map, etc. is just plain wrong.

public class MyBean
{
    private Collection collection;

    public Collection getCollection() { return collection; }
    public void setCollection( Collection collection ) { this.collection = collection; }
}

...or even eschewing the setter by using a constructor:

public class MyBean
{
    private Collection collection;

    public MyBean( Collection collection ) { this.collection = collection; }

    public Collection getCollection() { return collection; }
}

...will not make the interior collection immutable since a handle to it on the outside will make it modifiable. The following could be tried:

public class MyBean
{
    private List collection = new ArrayList();

    public MyBean( Collection collection ) { this.collection.addAll( collection ); }

    public Collection getCollection() { return Collections.unmodifiableList( collection ); }
}

Tracking down memory leaks in Java

Here is an article: Monitoring and Detecting Memory Leaks in Your Java Application.

Note that thread-local store use and web applications running in a container like Tomcat can easily sport memory leaks that must be cogitated and analyzed.


Replacing Java 6 with Java 7

This is in the context of running Tomcat. See JAVA_HOME for Tomcat.


UnsupportedClassVersionError in Java

When you see a stack trace with...

    java.lang.UnsupportedClassVersionError: SomeClass : Unsupported major.minor version 51.0 (unable to load class SomeClass)
    .
    .
    .

...it probably means that you compiled your application with a Java compiler of a more recent version than the JVM you're trying to run it on.


How to override equals() and hashCode() properly

Equivalence must define a relation that's reflexive, symmetric, transitive and consistent. If null, what's being compared must return false. Apache Commons has some great helps for this.

import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;

public class Poop
{
    private String name;
    private int    age;

    public boolean equals( Object o )
    {
        if( o == null )
            return false;
        if( o == this )
            return true;
        if( !( o instanceof Poop ) )
            return false;

        Poop poop = ( Poop ) o;

        return new EqualsBuilder()
                    .append( name, poop.name )
                    .append( age, poop.age )
                    .isEquals();
    }

    public int hashCode()
    {
        return new HashCodeBuilder( 17, 31 )    // two randomly chosen prime numbers
                        .append( name )
                        .append( age )
                        .toHashCode();
    }
}

Visual VM bundled with JDK

Web site: http://visualvm.java.net/.

MBeans

Use to read and set properties with this plug-in directly in memory effectuating changes on the fly.

Launch thus from console:

$ jvisualvm

...and install Tools -> Plugins including:

If, when you click on the MBeans tab, you see:

Data not available because JMX connection to the JMX agent could not be established.

This link sort of applies: http://docs.oracle.com/javase/1.5.0/docs/guide/management/agent.html#remote, but you only need some of it (if you're not debugging remotely).

In Run/Debug configuration, for VM options: -Dcom.sun.management.jmxremote


Dependency injection (Inversion of control)

Better than Guice; Dagger for dependency injection: http://square.github.io/dagger/.


The history of identifier deprecation in Java

I was completely taken by surprise this morning.

These annotations have a rather sordid history including hopeless pleas now in our day exhorting correct usage which, officially and numerously (see stackoverflow.com* et al.) at least, is supposed to consist of employing both annotations simultaneously.

From Oracle (Sun) docs (underlining mine):

NOTE: The Java Language Specification requires compilers to issue warnings when classes, methods, or fields marked with the @Deprecated annotation are used. Compilers are not required by the Java Language Specification to issue warnings when classes, methods, or fields marked with the @deprecated Javadoc tag are accessed, although the Sun compilers currently do so. However, there is no guarantee that the Sun compiler will always issue such warnings.

Using the @Deprecated Annotation

J2SE 5.0 introduces a new language feature called annotations (also called metadata). One of the Java language's built-in annotations is the @Deprecated annotation. To use it, you simply precede the class, method, or member declaration with "@Deprecated."

This next document demonstrates that the Javadoc-looking annotation predates—to at least 1996. Note the statement,

This is the first time the compiler is in any way cognizant of document comment contents. (Once, it made sure that they were at the right place in the parse tree, but this is no longer true.) We did not lightly choose to make the compiler's behavior dependent on the contents of a comment.

(Yeah, no kidding? They must have been desperate. C already long sported #pragmas; I'd have reached the conclusion to implement annotations right then and there, Java 1.1, instead of awaiting Java 1.5.)

http://www.cis.upenn.edu/~bcpierce/courses/629/jdkdocs/guide/misc/deprecated.html

* http://stackoverflow.com/questions/9031832/how-to-declare-or-mark-a-java-method-as-deprecated


OS/system details in Java

http://java.dzone.com/articles/get-your-os-distribution


How I eliminated Oracle/Sun JDK

Not that I feel the need to do this. OpenJDK/JRE usually works fine and so does the Sun JDK/JRE. At work, they were in a "let'd get rid of Oracle" mood and while that's really only a database issue, it was proposed that the baby get tossed out too. No matter. Here's how I did it; I'm running Mint (Ubuntu) these days.

Please note that Oracle/Sun typically installs on the host at /opt/java, e.g.: /opt/java/jdk1.7.0_51. It is not seen via dpkg --list nor removed via apt-get purge/remove.

I'm dumbing this down a bit to reveal all the details that would otherwise have to be guessed at.

If it's really a JDK (and not merely a JRE) and you've done everything right, IntelliJ should start without the "missing tools.jar / please use a proper JDK message".

  1. Install openjdk 7, the one you want.
    ~ $ sudo bash
    ~ # apt-get update
    ~ # apt-get install openjdk-7-jdk
    
  2. Fix up links in /usr/lib/jvm:
    /usr/lib/jvm # ll
    total 56
    drwxr-xr-x   4 root root  4096 Jun 25 12:52 .
    drwxr-xr-x 203 root root 36864 Jun 25 12:52 ..
    lrwxrwxrwx   1 root root    18 Mar 13  2012 java-1.5.0-gcj -> java-1.5.0-gcj-4.6
    drwxr-xr-x   6 root root  4096 Feb  7 14:03 java-1.5.0-gcj-4.6
    lrwxrwxrwx   1 root root    20 Apr 25 12:31 java-1.7.0-openjdk-amd64 -> java-7-openjdk-amd64
    -rw-r--r--   1 root root  2439 Apr 25 12:31 .java-1.7.0-openjdk-amd64.jinfo
    drwxr-xr-x   5 root root  4096 Jun 25 10:56 java-7-openjdk-amd64
    lrwxrwxrwx   1 root root    12 Mar 13  2012 java-gcj -> java-gcj-4.6
    lrwxrwxrwx   1 root root    18 Apr 16  2012 java-gcj-4.6 -> java-1.5.0-gcj-4.6
    -rw-r--r--   1 root root   946 Apr 16  2012 .java-gcj-4.6.jinfo
    
  3. I added this link.
    lrwxrwxrwx   1 root root    26 Jun 25 13:06 java-7 -> ./java-1.7.0-openjdk-amd64
    
  4. Fix up /etc/alternatives.
    /etc/alternatives # ll java
    lrwxrwxrwx 1 root root 30 Feb  7 14:05 java -> /opt/java/jdk1.7.0_51/bin/java
    

    which I changed to:

    /etc/alternatives # ll java*
    lrwxrwxrwx 1 root root 30 Feb  7 14:05 java.old -> /opt/java/jdk1.7.0_51/bin/java
    lrwxrwxrwx 1 root root 28 Jun 25 13:08 java -> /usr/lib/jvm/java-7/bin/java
    

    I can remove java.old once everything is working.

  5. Fix up your .profile, something like:
    export JAVA7_HOME=/usr/lib/jvm/java-7-openjdk-amd647
    export  JAVA_HOME=${JAVA7_HOME}
    export   IDEA_JDK=${JAVA7_HOME}
    export    M2_HOME=/home/russ/dev/apache-maven-3.1.1
    export         M2=${M2_HOME}/bin
    export MAVEN_OPTS="-Xms2048m -Xmx2048m -XX:PermSize=256m -XX:MaxPermSize=512"
    
    PATH=/home/russ/bin:${JAVA_HOME}/bin:${PATH}
    PATH=${PATH}:${M2}
    

    so that your path appears thus:

    ~ $ echo $PATH
    /home/russ/bin:/usr/lib/jvm/java-7/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:\
        /sbin:/bin:/home/russ/dev/apache-maven-3.1.1/bin
    ~ $ which java
    /usr/lib/jvm/java-7/bin/java
    ~ $ java -version
    java version "1.7.0_55"
    OpenJDK Runtime Environment (IcedTea 2.4.7) (7u55-2.4.7-1ubuntu1~0.12.04.2)
    OpenJDK 64-Bit Server VM (build 24.51-b03, mixed mode)
    

The Java @Override snafu

The first things to remember are that Java 5 introduced...

  1. Annotations, including @Override.
  2. Interfaces, which had not existed before (everyone use abstract).

In Java 5, @Override was introduced for use in overriding a method from a superclass (including abstract classes). It was not offered for use on methods implementing a method from an interface.

In Java 7, @Override is tolerated for methods of a class that implement methods listed in an interface. However, it is not necessary. This is why you don't get errors for either method below:

public interface Foo
{
    public void fooit();
    public void barit();
}

public class Bar implements Foo
{
    @Override
    public void fooit() { }

    public void barit() { }
}

Nevertheless, when compiling with Java 6, you do get an error for the implementation of fooit().

I personally think it makes more sense not to use @Override when implementing an interface's contractual methods, but it's only a problem when you maintain code compiled sometimes by JDK 5/6 and sometimes by JDK 7/8.


Swiss Java knife

A useful, open-source tool to add to Java diagnostic toolkit. Swiss Java Knife offers a number of commands:

  • jps - Similar to the jps tool that comes with the JDK.
  • ttop - Similar to the linux top command.
  • hh - Similar to running the jmap tool that comes with the JDK with the -histo option.
  • gc - Reports information about garbage collection in real time.
  • mx - Allows you to do basic operations with MBeans from the command line.
  • mxdump - Dumps all MBeans of the target java process to JSON.

Links:


Java thread safety

How JEE applications execute

  1. Applications start with one master thread, the main thread, which hangs around keeping the application alive. This is usually part of the container in Java EE.
  2. On receiving user input or on receiving a request from client, the master thread may start new thread(s) to get the work done. Some entry method is called on your managed component - like doGet() or doPost() or a bean's business method.
  3. From this point onward you are not creating any further threads, so you are coding with a single thread in mind.
  4. As your code executes, you may create objects with new and work with them.
  5. You may share few of these objects with the container or hold static reference to the objects. These can become accessible to other threads.
  6. Your code can also access container-provided objects, singletons (and other objects held in static references), etc. which may be created by other threads and are visible to you.

How visibly to show code is safe

  1. Write minimal amounts of code in static methods—implement business logic as instance methods not static methods. Even if you write static methods, avoid static instance variables (just do some work, don't store anything).
  2. Don't expose: Keep as many objects unshared as possible. For example, don't write getters and setters for internal variables.
  3. Use lots of new and don't unnecessarily reuse. For example, don't reuse a SimpleDateFormat. Just create one each time you need to format or parse a date (or keep it as a private instance variable and mark it final. But don't make it static. Once you make it static it can be accessed by multiple threads).
  4. Similarly, create new ArrayLists and StringBuilders freely, don't reuse. (Code reuse is good, object reuse is bad)
  5. Create new instances every time for custom objects also. For example, create new BO and DAO objects. Use the objects the throw them (let them get garbage collected). Don't try to reuse.
  6. For extra safety, make task-oriented objects like BO/Bean and DAO stateless as far as possible (by avoiding instance variables).
  7. Make shared objects read-only (immutable) as far as possible: For example, if you have a list of countries supported by your application, that list is not going to change. So, mark the reference as final and use immutable lists/maps (See: http://stackoverflow.com/questions/7713274/java-immutable-collections).

The ultimate Java 8 list

Java 8 Features—The Ultimate Guide


Java collections

The Java collection consists of Sets, Lists and Queues:

Lists

Lists can contain duplicates, even LinkedList. If you want to eliminate duplicates (automatically), use a Set-type. What's different between types of lists is the speed of certain operations and this is how to pick which one to use in a given situation.

ArrayList - dynamically sizing array. Fast random-read access, get() takes constant time. Adding and removing require shifting of the array elements in memory, however. When the size of the array must be increased due to addition, a new array of size 150% is allocated and the old array must be copied. The default, unspecified size (Java 4 through 7) is 10. Constructing it with more saves time if you know there will be more.

ArrayList is hugely expensive for remove operations and for add operations when the size allocated is used up.

Vector works like ArrayList, but is synchronized and therefore thread-safe—and slightly slower. Most programmers eschew this in favor of ArrayList since they want to synchronize explicitly anyway.

LinkedList - doubly linked list. Best for constant-time insertions and sequential access of elements. Finding a position in the array takes time proportional to the length of the list. The size penalty for the overhead grows considerably over that for ArrayList at, on a graph, almost a 45° angle. (Note: since late Java 6, no distinction between 32-bit and 64-bit is distinguishable—64-bit used to have even more overhead.)

—better for add and remove than ArrayList, worse for get and set operations. Use LinkedList if there are going to be few random accesses (get(), contains()) or many add or remove operations. See http://www.programcreek.com/2013/03/arraylist-vs-linkedlist-vs-vector/.

HashMap is like an ArrayList of key-value pairs, but it is not implemented within the framework of Java collections (it's not a set, list or queue). It is a Map. Keys in a map cannot occur in duplicates.

Sets

In a set, no duplicates are allowed. When adding, duplicates are removed automatically. The three most commonly used sets implementations are HashSet (fast), LinkedHashSet (order-preserving) and TreeSet (maintained sorted).

HashSet - elements are unordered, held in a hash table. Add, remove and contain operations have constant-time complexity.

LinkedHashSet - is a sort of hash table with a linked list running through it, maintaining the order of insertion.

See http://www.programcreek.com/2013/03/hashset-vs-treeset-vs-linkedhashset/.

Queues

(Not today.)


Java maps

The Java map consists of HashMap, LinkedHashMap, TreeMap and Hashtable.

HashMap - makes no guarantee as to order, allows one null key and null values. Traversed using iteratory, entry set. (Inherits AbstractMap.)

LinkedHashMap - preserves the original insertion order, but is otherwise identical to HashMap.

TreeMap - uses natural or comparator-based ordering to maintain contents in-order. Null keys only allowed if comparator used and doesn't thrown an exception.

Hashtable - makes no guarantee as to order, disallows null keys and values, is synchronized and therefore expensive if you don't need that. Traversed using enumerator and iterator. (Inherits Dictionary.)


Java filepaths

You try to create a file. Where is it? Original, Windows code:

File child = new File(".././Java.txt");
  • getPath() —likely relative to current working subdirectory.
  • ..\.\Java.txt
  • getAbsolutePath() —fully qualified path, but in relationship to the current working subdirectory.
  • C:\Users\WINDOWS 8\workspace\Demo\..\.\Java.txt
  • getCanonicalPath() —full path from the filesystem's point of view.
  • C:\Users\WINDOWS 8\workspace\Java.txt

byte[] to String
byte[] aByte = new String( ".976" ).getBytes();
String propertyValue = new String( aByte );

...otherwise, aByte.toString() yields gobble-dee-gook.


Exceptions

... exist in checked and unchecked varieties. The original idea:

Unchecked exceptions represent defects in the application code, perhaps a null pointer, an invalid argument passed to a non-private method. These represent conditions that, generally speaking, reflect errors in logic and cannot be reasonably recovered from at runtime.

At least that was the theory in the 1990s.

Checked exceptions are invalid conditions in area outside immediate control of application code including invalid user input, database problems, network outages, absent files, etc.

They are subclasses of Exception.

Methods are oblged to establish a policy for all checked exceptions thrown by its implementation (either by passing the problem further up the stack or throwing again to be handled elsewhere).

If a client can reasonably be expected to recover from an exception, make it a checked one. If unreasonable, make it unchecked.


Java API exceptions

This is API theory: the right/best way to do things.

Returning null

This means the intent of the code is not explicit without looking at the JavaDocs, and so the worst option on our list.

Returning an Optional

This makes the intent explicit compared to returning null. Of course, this requires Java 8.

Return a Guava’s Optional

For those of us who are not fortunate enough to have Java 8.

Returning one’s own Optional

If you don't use Guava and prefer to embed your own copy of the class instead of relying on an external library.

Returning a Try

Cook up something like Scala's Try, which wraps either (hence its old name, "Either") the returned bean or an exception. In this case, however, the exception is not thrown but used like any other object, hence there will be no performance problem.

Conclusion: when designing an API, one should really keep using exceptions for exceptional situations only.

A better piece of advice (not mine, but a quote I read somewhere):

"When designing an API, I use the "get vs. find rule." The API's user needs to know how to handle the absence of a result. A get is expected to always return a result while a find is not. And so when coding getX() it returns the result or throws an exception—such as llegalStateException—if there is not one. Where as, when coding findX() it returns a result if available or a null, or an empty collection, if there is not one."


Checked/unchecked exceptions

1. Throwable and Error classes should not be caught

Throwable is the superclass of all errors and exceptions in Java. Error is the superclass of all errors which are not meant to be caught by applications. Thus, catching Throwable would essentially mean that Errors such as system exceptions (e.g., OutOfMemoryError, StackOverFlowError or InternalError) would also get caught. The recommended approach is that an application should not try to recover from errors such as these. Therefore, Throwable and Error classes should not be caught. Only Exception and its subclasses should be caught.

Data errors such as encoding issues etc which are not known at programming time should be caught using this technique. However, catching Throwable such as InternalError or OutofMemoryError would not be of any help and should never be thrown.

Avoid writing code consisting of catching Throwable as general practice.

2. Throwable.printStackTrace(…) should never be called

One should avoid invoking printStackTrace() method on Throwable/Exception classes and instead use a logging framework.

3. Generic exceptions Error, RuntimeException, Throwable and Exception should never be thrown

The primary reason to avoid throwing generic Exceptions, Throwable and Error is that doing so prevents classes from catching the intended exceptions. A caller cannot examine the exception to determine why it was thrown and consequently cannot attempt recovery.

Catching RuntimeException is considered a bad practice. Throwing generic Exceptions/Throwable leads the developer to catch the exception at a later stage which usually leads to worse practices.

Do not throw a generic exception like RuntimeException. Do, however, throw a custom-rolled exception that inherits from RuntimeException.

4. Exception handlers should preserve the original exception

5. System.out or System.err should not be used to log exceptions

The primary reason one should avoid using System.out or System.err to log exceptions is that one might simply loose the important error message.

Checked exceptions!

One man's opinion...

It is an utterly failed experiment because it is designed around the totally flawed assumption that the service/library throwing the exception should decide which ones should be checked and which ones should not. In reality, only the caller knows which ones should be caught (usually none), and which ones should not.

6. Generally, whenever a library-method is called that throws a checked exception, just do:

try
{
    libraryObject.method();
}
catch( Exception e )
{
    throw new MyAppRuntimeException( e );
}

...to prevent this checked-exception idiocy from propagating like a virus and infecting the whole application.


Reasons for resorting to a conditional...

...to think about and perhaps solve. Some are unavoidable—foisted upon one by someone else, some are code stench.

  1. Checking a value returned to me from code I own (null-pointer check stench)?
  2. Checking a value returned to me from code I do not own?
  3. Checking a parameter passed to me by code I own (control couple stench)?
  4. Checking a parameter passed to me by code I do not own?
  5. Checking my own state or attributes?
  6. Checking a value I set previously in this method?
  7. Checking the type of an exception thrown by code I own?
  8. Checking the type of an exception thrown by code I do not own?

How to close streams for sure

This code doesn't close streams although it's trying. It could throw an exception when one fails to close. If attempting to close fis fails, the code throws an exception and prints out a warning, but nothing is done to attempt to close fos.

FileInputStream  fis = null;
FileOutputStream fos = null;

try
{
	fis = new FileInputStream( "stuff-to-read.txt" );
	fos = new FileOutputStream( "stuff-put-out.txt" );
	...
}
finally
{
	try
	{
		if( fis != null )
			fis.close();
		if( fos != null )
			fos.close();
	}
	catch( IOException e )
	{
		System.out.println( "Failed to close streams" );
	}
}

This code will do the trick, but it's a bit unsightly. It takes up a lot of space and obfuscates a simple thing.

InputStream  fis = null;
OutputStream fos = null;

try
{
	fis = new FileInputStream( "stuff-to-read.txt" );
	fos = new FileOutputStream( "stuff-put-out.txt" );
	...
}
finally
{
	try
	{
		if( fis != null )
			fis.close();
	}
	catch( IOException e )
	{
		;
	}
	try
	{
		if( fos != null )
			fos.close();
	}
	catch( IOException e )
	{
		;
	}
}

JVM mind (share) map

Click to see full size.


Random in Java

Check out these claims when you get a chance.

import java.lang.reflect.Field;
import java.util.Random;

public class Entropy {
  public static void main(String[] args)
  throws Exception {

    // Extract the IntegerCache through reflection
    Class<?> clazz = Class.forName(
      "java.lang.Integer$IntegerCache");
    Field field = clazz.getDeclaredField("cache");
    field.setAccessible(true);
    Integer[] cache = (Integer[]) field.get(clazz);

    // Rewrite the Integer cache
    for (int i = 0; i < cache.length; i++) {
      cache[i] = new Integer( new Random().nextInt(cache.length));
    }

    // Prove randomness
    for (int i = 0; i < 10; i++) {
      System.out.println((Integer) i);
    }
  }
}

Reverse string
public class StringReverse
{
  private static final String[] FODDER =
                                { // palindromes except the first...
                                  "Off to the races...",
                                  "Madam I'm Adam",
                                  "A dog, a plan, a canal: pagoda",
                                  "A nut for a jar of tuna",
                                  "A Santa at NASA",
                                  "A slut nixes sex in Tulsa",
                                  "A car, a man, a maraca"
                                };

  private static String reverse( String string )
  {
    if( string.length() < 2 )
      return string;

    /* Algorithm: Grab everything after the first character and return
     * it followed by the (soon to be former) first character itself.
     */
    return reverse( string.substring( 1 ) ) + string.charAt( 0 );
  }

  public static void main( String[] args )
  {
    for( String string : FODDER )
    {
      String message = "String  " + string + " ";
      int TAB = 40, length = message.length();

      System.out.print( message );

      while( length++ < TAB )
        System.out.print( " " );

      System.out.println( " reversed is:  " + reverse( string ) );
    }
  }
}

Output:

String  Madam I'm Adam                   reversed is:  madA m'I madaM
String  Off to the races...              reversed is:  ...secar eht ot ffO
String  A dog, a plan, a canal: pagoda   reversed is:  adogap :lanac a ,nalp a ,god A
String  A nut for a jar of tuna          reversed is:  anut fo raj a rof tun A
String  A Santa at NASA                  reversed is:  ASAN ta atnaS A
String  A slut nixes sex in Tulsa        reversed is:  asluT ni xes sexin tuls A
String  A car, a man, a maraca           reversed is:  acaram a ,nam a ,rac A

Arrays.toString() minus the brackets

Arrays.toString( array ) surrounds the whole with "[ ... ]"—not what we want.

private String arrayToString( String[] array )
{
  StringBuilder sb    = new StringBuilder();
  boolean       first = true;

  for( String particle : array )
  {
    if( !first )
      sb.append( ' ' );

    sb.append( particle );
    first = false;
  }

  return sb.toString();
}

EarlyExitException is not EarlyExitException (symbol is not symbol)

Beware (duh!) that if you have a duplicate class, EarlyExitException, in your code and are building using a JAR that also has that symbol, uses and throws it, your code will not be catching it just because you happen also to have EarlyExitException. They are different and you get errors like

unreported exception EarlyExitException; must be caught or declared to be thrown

because EarlyExitException is not EarlyExitException.


Unsupported major.minor version 52.0

This happens when you've got code in your JAR, WAR or NAR compiled with a higher version of Java (in my case 8) for a higher version of Java (in my case, 8 though I wasn't specifying it by using this plug-in).

	<plugin>
		<groupId>org.apache.maven.plugins</groupId>
		<artifactId>maven-compiler-plugin</artifactId>
		<configuration>
			<source>1.7</source>
			<target>1.7</target>
		</configuration>
	</plugin>

The solution is to build everything with 1.7 (or whatever). Use Maven to clean out what's there before recompiling and packaging with this plug-on configuration in place.


Notes on Java serialization
public class SerializableClass implements Serializable
{
  private static final    long   serialVersionUID = 456778567857L;
  public                  String firstField       = "First Field";
  public transient static String secondField      = "Second Field";
  public transient final  String thirdField;      // unintialized
  public transient final  String fourthField      = "Fourth Field";
  private int                    privateField     = 99;

Notes

  1. serialVersionUID is explicitly defined to prevent InvalidClassException during deserialization. As the default serialVersionUID computation is highly sensitive to class details that may vary depending on compiler implementations and can produce different results in different environments, beware.
  2. firstField will be serialized, and the default value can be overridden in subsequent classes that are serializing SerializableClass.java.
  3. secondField, thirdField and fourthField, being either transient static or transient final, will never be serialized. The values these will have will be restored at deserialization from whatever their values are in SerializableClass at the time it happens.
  4. privateField is private. It will be serialized, but can be read only through reflection.

Notes on JVM garbage collection

These are the causes of the JVM garbage collection firing according to frequency in an average application.

Allocation Failure Application tried to make a new allocation and failed due to lack of available space in Young generation; hence Minor GC is required. On Linux, the JVM can trigger a GC if the kernel notifies there isn't much memory left via mem_notify.
GC Locker GC is started after all threads leave the JNI Critical region. For more information on JNI, refer to the Java Native Interface documentation website. GC is blocked when any thread is in the JNI Critical region and can start only when all of them outside of it.
G1 Evacuation Pause This is actual only for the G1 collector. It indicates that it is copying live objects from one set of regions (Young and sometimes Young + Tenured, which is called Mixed) to another set of regions.
G1 Humongous Allocation This is actual only for the G1 collector. Humongous is an allocation when its size is greater than 50% of one region size; the object then allocated in special space. Nevertheless, it also causes normal GC collection to get more (possibly continuous also) space for such objects.
CMS Initial Mark Initial mark phase of CMS, for more details, see Phases of CMS. It also triggers Young Space collection.
System.gc() There was a System.gc() call in the application code. You can start JVM with the -XX:+DisableExplicitGC flag to disable such behavior.
Adaptive Size Ergonomics Indicates you are using the adaptive heap size policy (ability to change Young and Tenured spaces size at runtime), enabled via the -XX:+UseAdaptiveSizePolicy flag. By default, it is enabled in the recent versions of JVM.
Allocation Profiler This is actual only for versions of Java before 8 and only when -Xaprof is set. It triggers just before JVM exits.
Heap Inspection GC was triggered by an inspection operation on the heap, most probably by the jmap tool with the -histo:live flag set.
Heap Dump GC was initiated before heap dump is made by some profiling instrument.
No GC Normally, you shouldn't see this reason. It was occurring in older Java versions, in case jstat command was started before any collection occurred. Other case is when jstat checks GC without any GC activity.
Last-ditch Collection When Metaspace (Java 8+) or PermGen (Java 7-) is full and you can't allocate a new object here, JVM first tries to clean it, triggering appropriate collector. If that's not possible, it then tries to expand it. If that doesn't work as well, it triggers Full GC with this cause name. Soft references are being cleaned during it as well.
Perm Generation Full Triggered as a result of an allocation failure in PermGen. Actual for Java versions prior to 8.
Metadata GC Threshold Triggered as a result of an allocation failure in Metaspace. Metaspace is a replacement for PermGen in Java 8+.
JvmtiEnv ForceGarbageCollection Something called the JVM tool interface function ForceGarbageCollection.