1

I'm trying to make an extension for BlueJ (this is a free Java Development Environment designed for beginners). The Extension should help the first year students in our school. The extension has to be a JAR file, that I have to place in a folder where BlueJ can load it at runtime. My already written extension can be loaded from there and it works without any problem.

Now to the reason, for this question: I want to integrate checkstyle (this is a development tool to help programmers write Java code that adheres to a coding standard.) into my extension. So I put the checkstyle jar within my project and tried to use this library inside my code. If I now generate a jar and copy my extension into the BlueJ folder and start BlueJ out of eclipse I get the following error:

java.lang.NoClassDefFoundError: com/puppycrawl/tools/checkstyle/api/CheckstyleException at ch.ntb.sir.ntbbluejextension.NtbBlueJExtension.startup(NtbBlueJExtension.java:79) at bluej.extmgr.ExtensionWrapper.safeStartup(ExtensionWrapper.java:533) at bluej.extmgr.ExtensionWrapper.newExtension(ExtensionWrapper.java:209) at bluej.extmgr.ExtensionsManager.loadDirectoryExtensions(ExtensionsManager.java:164) at bluej.extmgr.ExtensionsManager.loadExtensions(ExtensionsManager.java:100) at bluej.extmgr.ExtensionsManager.getInstance(ExtensionsManager.java:61) at bluej.Main.(Main.java:101) at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:422) at java.lang.Class.newInstance(Class.java:442) at bluej.Boot.bootBluej(Boot.java:348) at bluej.Boot.main(Boot.java:175) Caused by: java.lang.ClassNotFoundException: com.puppycrawl.tools.checkstyle.api.CheckstyleException at java.net.URLClassLoader.findClass(URLClassLoader.java:381) at java.lang.ClassLoader.loadClass(ClassLoader.java:424) at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ... 14 more

At NtbBlueJExtension.java:79 I make this initialization:

`codeAnalysisHandler = new CodeAnalysisHandler();`

Inside the CodeAnalysisHandler class I have imports from the checkstyle libraries:

import com.puppycrawl.tools.checkstyle.Checker;
import com.puppycrawl.tools.checkstyle.ConfigurationLoader;
import com.puppycrawl.tools.checkstyle.PropertiesExpander;
import com.puppycrawl.tools.checkstyle.TreeWalker;
import com.puppycrawl.tools.checkstyle.api.AuditEvent;
import com.puppycrawl.tools.checkstyle.api.AuditListener;
import com.puppycrawl.tools.checkstyle.api.CheckstyleException;
import com.puppycrawl.tools.checkstyle.api.Configuration;

My first though is, that there I should find the cause of my problem? But then I have no idea what to search and how to solve it.

I've added the jar in my project properties in eclipse. The Jar is inside the project structure in my lib folder. BlueJ had no problem to load the bluejext.jar from the "lib" folder. The bluejext.jar comes from BlueJ and is required to write an extension for BlueJ. I have this manifest file:

Manifest-Version: 1.0
Main-Class: ch.ntb.sir.ntbbluejextension.NtbBlueJExtension
Class-Path: lib/bluejext.jar lib/checkstyle-all.jar

I tried to google it, but found mostly information about how difficult it is to find the reason.

EDIT 1: I unzipped my JAR file to look, if the checkstyle-all.jar is really inside my extension and there I found a file .classpath:

<?xml version="1.0" encoding="UTF-8"?>
<classpath>
    <classpathentry kind="src" path="src"/>
    <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
    <classpathentry kind="lib" path="lib/bluejext.jar"/>
    <classpathentry kind="lib" path="lib/checkstyle-all.jar"/>
    <classpathentry kind="output" path="bin"/>
</classpath>

SOLUTION: Use Eclipse Kepler with the fat jar plugin (Neon was to new for the plugin) and export the project with ´Build Fat Jar´. After that the ´java.lang.ClassNotFoundException´ didn't appear anymore.

Thanks for your help.

SirArt
  • 415
  • 6
  • 18
  • Make sure that your jar file contains checkstyle lib. Check this link (http://stackoverflow.com/questions/11033603/how-to-create-a-jar-with-external-libraries-included-in-eclipse) for more information. – hgminh Jan 09 '17 at 08:35
  • @MinhHoàng I unzipped my extension JAR file and the checkstyle-all.jar is inside the lib folder. So this should be ok? – SirArt Jan 09 '17 at 08:41
  • @MinhHoàng I edited my question with some new information. Thanks. – SirArt Jan 09 '17 at 08:46

1 Answers1

1

From Java Document:

The Class-Path header points to classes or JAR files on the local network, not JAR files within the JAR file or classes accessible over Internet protocols

If you want to include checkstyle in the extension jar, you have to explode it into the main jar. Take a look at this for more information.

Here is an example using Gradle.

Community
  • 1
  • 1
hgminh
  • 1,178
  • 1
  • 8
  • 26
  • Ok, i will give that a try. But the bluejext.jar worked perfectly within my jar exactly the way I described. Is it possible that this solution with the "fatjar" is only necessary for some jar? – SirArt Jan 09 '17 at 12:16
  • It is because bluejext.jar is provided by bluej, while checkstyle is not. I think it may work if you add checkstyle-all.jar to lib folder of bluej. – hgminh Jan 09 '17 at 13:17
  • To be more details, bluej does not use the `bluejext.jar` inside your extension jar but the one in `lib` folder of bluej. – hgminh Jan 09 '17 at 13:25
  • Ah! this explains why bluejext.jar works... I've added the checkstyle-all.jar in the lib folder in bluej (same directory like the bluejext.jar from bluej). It didn't worked. I think my code inside my jar doesn't find the checkstyle jar in that lib folder? (I still trying to make this fat jar, but I never worked with gradle so I have to look into that first.) – SirArt Jan 09 '17 at 13:42
  • Maybe bluej use custom code to load jar file, I am not sure about that. If you are not familiar with gradle, you can try maven assembly plugin (for Maven) or eclipse fat jar plugin (never use it though). – hgminh Jan 10 '17 at 06:12
  • Thanks, I'll try the plugin. In eclipse neon the plugin doesn't work. But probably in an older version. I give it a try. It sounds like less time-consuming than to look into maven / gradle. – SirArt Jan 10 '17 at 08:38
  • It looks like it works if I use eclipse Kepler with the Fat Jar plugin. I don't get the Error message `ClassNotFoundException`. Now I have to handle some checkstyle specific exceptions, but that's an other problem. Thanks for your help! – SirArt Jan 10 '17 at 09:26