How I Learned to Separate Test Jars and Stop Worrying

Currently, our lib/development folder contains a lot of jars that are actually not used in development. Significant number (or, better, significant amount) is used for tests. Among these is selenium-server.jar, a huge jar that contains also classes from many other used frameworks (bcel, commons.*,  bouncycastle, json…).

So what is the problem with this? If you use IntelliJ IDEA as described in our wiki you will notice that no library is set in the 'Test' scope (available only for the test code). And you might experience the following problems:

  • You are able to use test classes in production code, without any compilation error. For example, you can reference a class from selenium jar, without being aware that class exists only there. And selenium jar is especially a problem here, since it contains all those utilities inside.
  • Your IntelliJ (or any other IDE) may load util classes from selenium jar before it loads them from portal jars. And selenium classes are usually older versions, so compiling from IntelliJ may fails. Afaik this happens regularly when running IntelliJ on Linux.
  • And finally, we are talking about 36+ MB of tests jars vs just 13 MB of development jars:) Your IDE would be thankful for reducing internal cache/indexes size for that many jars and award you with more speed!

Here is one way how to separate test Jars in a graceful way.

[1] The first step is to split development jars in two folders. This is a little batch that does that:

@echo off
setlocal
set ROBO_PARAMS=/S /MIR /XF /njh /njs /ndl /nc /ns

set TEST_FILES=selenium-*.jar jmock*.jar spring-test.jar tomcat*.jar derby.jar catalina.jar firebird.jar hsql.jar interbase.jar resin.jar mysql.jar ecj.jar ant*.jar jetty.jar  

robocopy portal\lib\development lib\development %ROBO_PARAMS% /XF %TEST_FILES% 
robocopy portal\lib\development lib\test %TEST_FILES% %ROBO_PARAMS%
endlocal

Not only jars are separated, but above batch also automatically synchronize jars: add new one, delete unused, etc. For linux, you may use rsync to achieve similar behavior.

[2] Go to Project Settings in InteliiJ and add a new library 'test'; then simply attach new lib folders instead of portal ones.

[3] And finally, go to all modules that have dependency on 'development' library and add the 'test' library in 'Test' scope. Move the 'test' library to the bottom of the dependency list. For example:

Note: if you have support-tomcat module, please remove it.

And that is all. Rebuild the project and stop worring ;)

Why is this nice? First, it is just a local fix. Then, we are now safe from selenium issues (explained above). Moreover, test jars are now not included in the exploded artifacts (all 36 MBs of them) -  and therefore not part of the runtime when running server from IntelliJ. And if you are more adventurous, you can create a mirror IntelliJ project with just sources, excluding the tests code and jars – resulting with less memory consumptionand, therefore, more speed.

And best of all, if you want to go back to previous state, just re-attach original portal 'development' folder in the library definition (leave the test library empty).

ブログ