Wednesday, August 17, 2016

Fix for "HibernateJpaDialect - JDBC Connection to reset not identical to originally prepared Connection" warning

After updating an application to Hibernate 5.1.1 from 5.1.0, I started seeing the following warning:

HibernateJpaDialect - JDBC Connection to reset not identical to originally prepared Connection

I did not find an "explicit" solution on the Internet, but looking through some of the code fixes in the ngrinder project, I figured out that I could fix my problem the same way by adding <prop key="hibernate.connection.release_mode">on_close</prop> to applicationContext.xml:

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="persistenceUnitName" value="pu"/>
<property name="packagesToScan">
<list>
<value>com.appia.model.beans</value>
</list>
</property>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="${orm.show_sql}"/>
<property name="databasePlatform" value="com.appia.pss.util.PostgresDialect"/>
</bean>
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.format_sql">${orm.format_sql}</prop>
<prop key="hibernate.connection.release_mode">on_close</prop>
</props>
</property>
</bean>

Thanks for this solution, JunHo!

Friday, August 12, 2016

JMeter in IntelliJ IDEA on Mac OS X

Quick Answer

Manually add the JMeter path at

Preferences » Other Settings » JMeter » JMeter home directory

Long Answer

I wanted to be able to launch JMeter scripts from within IntelliJ IDEA. This is the process I went through to make this happen:

Install JMeter

Having already installed Homebrew, JMeter can be easily installed with the command

brew install jmeter

Install JMeter Plugin in IntelliJ IDEA

Preferences » PlugIns » Search for JMeter » Select JMeter plugin » install » restart IntelliJ

Configure JMETER_HOME

This is where the troubleshooting needed to start. For the quick solution, see the first section. Otherwise, this is the process I went through:

Ideally, one would want things to "just work" after installing JMeter and the plugin. Unfortunately, when I created my first JMeter Run Configuration in IntelliJ, I got the message in the dialog box:

Run Configuration Error: JMeter not found

I eventually found a dialogue box under

Preferences » Other Settings » JMeter

with a helpful indicator that

JMETER_HOME is used by default

Sure enough, when I ran the env command in a Terminal, JMETER_HOME was not there.

To find out what my JMeter home directory was, I did the following in the Terminal

$ which jmeter
/usr/local/bin/jmeter
$ cat /usr/local/bin/jmeter
#!/bin/bash
exec "/usr/local/Cellar/jmeter/3.0/libexec/bin/jmeter" "$@"

So, based on some other information I gathered, the home directory was just above the "bin" directory.

My first attempt was to add the following line to my .bash_profile:

export JMETER_HOME=/usr/local/Cellar/jmeter/3.0/libexec

Sadly, I found this didn't work after rebooting and confirming that it showed up when the env command was executed in the Terminal.

I eventually ran across Setting global environment variables in IntelliJ IDEA and other test config goodies, from which I learned that environment variables are not automatically passed to GUI applications in Mac OS X. Nonetheless, Update 2 in the article looked promising.

I then added this line to .bash_profile:

launchctl setenv JMETER_HOME /usr/local/Cellar/jmeter/3.0/libexec

Again, to my frustration, I found that after rebooting and confirming that launchctl getenv JMETER_HOME displayed the correct value in the terminal, that this only worked in IntelliJ when I started IntelliJ, quit completely, and then started it again. I have no idea why the environment variable only seems to get read on the second startup.

So, for my final answer, I just had to go with the manual solution of adding the JMeter home path as an Override in the dialogue box found at:

Preferences » Other Settings » JMeter » JMeter home directory




Friday, August 05, 2016

Extract the icon from an APK file

Using the apk-parser library (https://github.com/caoqianli/apk-parser), I developed the following code that will extract the icon from an APK file. Note that there is no guarantee about what size the icon will be.
import net.dongliu.apk.parser.ApkParser;
import net.dongliu.apk.parser.bean.Icon;
import org.apache.log4j.Logger;
import java.io.*;
/** Services for managing APK (Adroid Application Package) objects. */
public class ApkService
{
/** The {@link Logger}. */
private static final Logger LOGGER = Logger.getLogger(ApkService.class);
/**
* Extract the icon from an APK file.
*
* @param apkParser the {@link ApkParser}
*
* @return the icon temp {@link File}
*/
public File saveIcon(ApkParser apkParser)
{
OutputStream out = null;
File file = null;
try
{
final Icon iconFile = apkParser.getIconFile();
String iconPath = iconFile.getPath();
String extension = iconPath.substring(iconPath.lastIndexOf('.'));
file = File.createTempFile("icon", extension);
out = new FileOutputStream(file);
out.write(iconFile.getData());
out.flush();
}
catch (Exception e)
{
throw new IllegalStateException("Problem extracting icon", e);
}
finally
{
if (out != null)
{
try
{
out.close();
}
catch (IOException e)
{
LOGGER.error(e);
}
}
}
return file;
}
}
view raw ApkService.java hosted with ❤ by GitHub
Enjoy!

Renaming a dependency JAR before buiding a WAR in Maven

I was recently tasked with updating New Relic on our servers. When this was initially set up, the server was set up with a JVM command line option:
-javaagent:/usr/share/tomcat7/webapps/ROOT/WEB-INF/lib/newrelic-3.9.0.jar
When working on updating the version, I wanted to change this so that
  1. We could update the New Relic Agent whenever a new update is available
  2. We would not need to change the JVM command line each time the Agent was updated
To accomplish this, I wanted the New Relic Agent JAR name to always be the same, regardless of the version. I found maven-dependency-plugin through a web search, but ran across a problem where my WAR file was being created before the JAR was downloaded and renamed (using maven-war-plugin). All the examples I ran across used <phase>package</phase>, and while that looked right, I figured that this was still happening in the wrong life cycle phase for what I wanted to do. I resorted to reading the documentation, and with some experimenting found that <phase>prepare-package</phase> did this at the right part of the life cycle.
Here is the plugins section of the working pom.xml:
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<phase>prepare-package</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<!--
New Relic is used for monitoring and troubleshooting in all environments.
It is configured on the server with the -javaagent JVM option.
This file needs to be named in a predictable manner when updates occur,
so we use this plugin to download the artifact and manually name it "newrelic.jar"
-->
<groupId>com.newrelic.agent.java</groupId>
<artifactId>newrelic-agent</artifactId>
<version>${com.newrelic.version}</version>
<type>jar</type>
<outputDirectory>${project.build.directory}/${project.build.finalName}/WEB-INF/lib</outputDirectory>
<destFileName>newrelic.jar</destFileName>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
view raw pom.xml hosted with ❤ by GitHub
You do not need to include this dependency in your dependencies section, unless you are actually using it in your code.
We changed the server's JVM command line option to:
-javaagent:/usr/share/tomcat7/webapps/ROOT/WEB-INF/lib/newrelic.jar
And everything worked just great ... once I got the YAML file figured out 😉.

Bonus Notes

  • If you have not worked with YAML before, you will find out quickly that indentation is important to keep the hierarchy of properties right
  • The newrelic.yml file included as an example in the newrelic-java.zip file appears to have an error in it. Specifically, the classloader_excludes property values need to be a commented list on the same line. I got parse errors using the example as-is (i.e., the list is indented with each item on a separate line, and has an extra comma at the end).
  • If you are reading this and setting up a new configuration based on this article, you will also need the newrelic.yml file to end up in the same folder. To that end, place the file in /src/main/webapp/WEB-INF/lib in your Maven-based folder structure.