JConsole is not showing any local processes

JConsole is a great tool to monitor Java applications using JMX. One common issue that can happen, is that when you start JConsole, you don’t see any process in the “Local Processes” list.

Normally, you should at least see the process for JConsole itself:

If you do not see any process in the list, not even JConsole’s, then you probably have a permission issue. Let’s see how can that happen.

When you are running a JVM, it generates a log file for each of your JVM processes. These log files contain performance related information, and are by default stored in a folder called hsperfdata_yourusername under your operating system’s temp folder.

JConsole is using these log files, to show you the list of local processes. So if the log files do not exist, you will see an empty list under “Local Processes”. The reason why there are no log files for your processes could be, that the JVM does not have enough permissions to create them.

The easiest solution to this is to just delete this log folder and let the JVM recreate it with the correct permissions.

To find it in it’s default location on Windows, you can just check the contents of your TMP environment variable:

> echo %TMP%
C:\Users\Username\AppData\Local\Temp

Look for a folder called hsperfdata_yourusername in this temp diretory and simply delete it.

Relaunch JConsole and your applications that need monitoring, and you should now see your local processes.

How to copy files to docker container from host and vica versa?

If you don’t want to install an editor in your docker container just to make a few small changes (e.g. change apache config etc.), you can just

docker cp <container>:/path/to/example.txt .

This command copies the file to your local machine (to your current directory). Then edit the file locally using your favorite editor, and copy it back to the container using the following command

docker cp example.txt <container>:/path/to/example.txt

to replace the old file.

Older docker versions

In older versions of Docker, the docker cp command only allowed copying files from a container to the host. From Docker 1.8 you can copy files from the host to a container.

ImprovedNamingStrategy does not work with Hibernate 5

Problem description

When you are trying to use the ImprovedNamingStrategy with Hibernate 5, it seems not to work. It does not resolve to underscore separated names, and because of that you get errors like this:

javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory
...
org.hibernate.tool.schema.spi.SchemaManagementException: Schema-validation: missing table [QuestionCategory]
@Entity
public class QuestionCategory extends IdentifiableEntity {

    private String name;

    // ...
}

It is looking for a table named “QuestionCategory”, but according to the ImprovedNamingStrategy it should be looking for “question_category”.

Why does it no longer work?

In Hibernate 4 you could use the following property to set the naming strategy that would map to names that only use lowercase letters and underscores as word separators:

jpaProperties.put("hibernate.ejb.naming_strategy", "org.hibernate.cfg.ImprovedNamingStrategy");

This naming strategy is pretty commonly used, because many developers like to use these kinds of names for the tables, columns etc. of their databases.

In Hibernate 5 however, the above mentioned hibernate.ejb.naming_strategy property is no longer available, because it has been split into two new properties to allow for deeper customization of the naming strategy.

What changed in Hibernate 5

Now, instead of one, there are two properties:

hibernate.implicit_naming_strategy
hibernate.physical_naming_strategy

Hibernate looks at name resolution as a 2 stage process:

  • When an entity does not explicitly name the database table that it maps to, we need to implicitly determine that table name. Or when a particular attribute does not explicitly name the database column that it maps to, we need to implicitly determine that column name. The first property is for defining this. 
  • Many organizations define rules around the naming of database objects (tables, columns, foreign-keys, etc). The idea of a PhysicalNamingStrategy is to help implement such naming rules without having to hard-code them into the mapping via explicit names. The second property is for this.

Solution

To resolve the issue and mimic the usage of ImprovedNamingStrategy, you can leave the implicit naming strategy as the default.

However, you need to create a custom physical naming strategy, because there is none that works the way we need it.

Here is how it’ll look like:

import org.hibernate.boot.model.naming.Identifier;
import org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl;
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;

import java.util.Locale;

public class PhysicalNamingStrategyImpl extends PhysicalNamingStrategyStandardImpl {


    @Override
    public Identifier toPhysicalTableName(Identifier name, JdbcEnvironment context) {
        return new Identifier(addUnderscores(name.getText()), name.isQuoted());
    }

    @Override
    public Identifier toPhysicalColumnName(Identifier name, JdbcEnvironment context) {
        return new Identifier(addUnderscores(name.getText()), name.isQuoted());
    }


    protected static String addUnderscores(String name) {
        final StringBuilder buf = new StringBuilder(name.replace('.', '_'));
        for (int i = 1; i < buf.length() - 1; i++) {
            if (Character.isLowerCase(buf.charAt(i - 1)) &&
                Character.isUpperCase(buf.charAt(i)) &&
                Character.isLowerCase(buf.charAt(i + 1))) {
                buf.insert(i++, '_');
            }
        }
        return buf.toString().toLowerCase(Locale.ROOT);
    }
}

You need to set this up by specifying the corresponding property:

jpaProperties.put("hibernate.physical_naming_strategy", "com.test.persistence.config.PhysicalNamingStrategyImpl");

Sources

  • https://docs.jboss.org/hibernate/orm/5.1/userguide/html_single/chapters/domain/naming.html
  • http://stackoverflow.com/questions/32437202/improvednamingstrategy-no-longer-working-in-hibernate-5

Why doesn’t Maven execute my unit tests?

If you have been using Maven for some time, you might have noticed that Maven will automatically find and execute your unit tests when they are present in your project, even without any additional configuration.

This is because it is using the Surefire Plugin with a default configuration (that can be overridden of course). However, for this to execute your tests, you need to place your test classes in the proper place and you need to name them appropriately.

Location of test classes

Your test classes need to be placed under the src/test/java folder, otherwise it won’t be picked up.

Naming of test classes

By default, the Surefire Plugin will automatically include all test classes that where the name matches one of the following patterns:

  • Test*.java
  • *Test.java
  • *TestCase.java

Example

We have the following test classes:

And the result is:

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running com.jtuts.MyTest
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.039 sec
Running com.jtuts.MyTestCase
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.002 sec
Running com.jtuts.TestMyCode
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0 sec
Running com.jtuts.TestsForMyCode
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0 sec

Results :

Tests run: 4, Failures: 0, Errors: 0, Skipped: 0

You can see that 3 of the above classes are skipped, because they do not match the naming convention.

Allow Linux in VirtualBox to connect to the localhost of the host machine

In this article I’ll show you how to set up a Linux running in VirtualBox to be able to access a service running on localhost on the host machine. I’ll use MySQL as an example, because that was the problem I faced with. The Linux OS of my choice is Ubuntu.

Testing the connection

First, let’s see how you can test if your virtual machine can access the service on the host. There is a great program called nmap for it. If it is not installed, you can install it with the following commands:

sudo apt-get update
sudo apt-get install nmap

Let’s suppose we have a web application that is trying to connect to the MySQL server on localhost:3306 by default. We would not like to change this configuration, but allow our virtual linux to connect to the MySQL server running on the host.

So, first let’s check if we can connect to MySQL:

nmap -p 3306 localhost

You could see something like this, indicating that it cannot connect:

Starting Nmap 7.01 ( https://nmap.org ) at 2016-09-18 19:12 CEST
Nmap scan report for localhost (127.0.0.1)
Host is up (0.000053s latency).
PORT     STATE  SERVICE
3306/tcp closed mysql

You should see an “open” STATE in the output instead of “closed”. Let’s try to resolve that.

Map localhost in the hosts file

We would like for our virtual linux to map localhost calls to the host machine. For this, we have to determine the default gateway of our machine.

netstat -rn
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
0.0.0.0         10.0.2.2        0.0.0.0         UG        0 0          0 enp0s3
10.0.2.0        0.0.0.0         255.255.255.0   U         0 0          0 enp0s3
169.254.0.0     0.0.0.0         255.255.0.0     U         0 0          0 enp0s3
root@relevart-VirtualBox:/media/sf_Projects/Java/#

Check the Gateway in the 0.0.0.0 line. That 10.0.2.2 IP address is what we need.

Open /etc/hosts and comment out the default line for localhost mapping and add a new one like this:

#127.0.0.1 localhost
10.0.2.2  localhost

After saving the file, and running nmap again, you should see that the STATE of the port is “open”.