Plugin Development: ClassNotFoundException in runtime but not in debug

Answered

Hi,

i have a strange ClassNotFound exception in my plugin i want to develop.

In development i can run everything just fine in simple main() methods. Everything is inside the classpath.

When the plugin is build a zip file, every dependency is included and i see every dependency in my sandbox plugin directory.

 

If i run my sandbox ide with the plugin, my action fails with a ClassNotFoundException of my dependencies.

But what is really strange: I i took the ClassLoader of my plugin and just try to loadClass() the missing class i can be found.

I dont know why this is happening, so i want to ask if somebody can help me.

 

Greetings,

Steffen

 

My gradle file, and the example code: https://gist.github.com/Jukkales/f86b27f76862f1573d942948b56f4651

Debug view:

6 comments
Comment actions Permalink

Did you try clearing out the sandbox completely? http://www.jetbrains.org/intellij/sdk/docs/basics/ide_development_instance.html

If it still doesn't work, please share the full sources of your plugin.

0
Comment actions Permalink

I was able to identify and workaround the problem - i don't think it can be "solved".

IntelliJ gives the plugin a own classloader, to load classes with own dependencies. But this classloader can be bypass by using the contextclassloader from the current thread.

In my case i use Apache CommonsConfiguration, which uses "ClassUtils" from ApacheCommons. ClassUtils.getClass() is static and can only load classes from the current thread, which is the AWT Worker - so IntelliJ's classloader itself. So it is impossible to load my requested class. Running this in a main() ensures that the Thread has all classes, so this is working.

My workaround is to build the PropertiesConfiguration class without the builder API - witch is optional by the way :)

At least i cannot say if this is a bug in Apache Commons Lang (by only using the thread classloader) or by me.

0
Comment actions Permalink

I see, there's nothing IJ can do about such things. AFAIU ClassUtils _does_ have an overload to pass in Classloader that should work properly.

Another workaround is using this snippet around critical code Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader()

What exactly are you trying to do with accessing the .properties configuration? Did you see http://www.jetbrains.org/intellij/sdk/docs/basics/persisting_state_of_components.html#using-propertiescomponent-for-simple-non-roamable-persistence?

 

0
Comment actions Permalink

Yes ClassUtils dose have a way to pass the classloader, but CommonsConfiguration dose not use it.

Personally, I avoid to replace the classloader of the current thread. In this case it may be safe, but had some issues with it in older projects :)

 

I want to rewrite my plugin: https://plugins.jetbrains.com/plugin/9883-intellij-idea-properties-sorter

We have some "special" formatting and sorting requirements from our customers. The current version is stupid easy and breaks all control sequences and comments. CommonsConfiguration have a nice parser which loads all types of comments and escape sequences.

But thanks for that link, was thinking about a way to remember user selection for the Sort Settings dialog :)

0
Comment actions Permalink

You can simply use existing Properties language PSI to access all elements and sort/delete/move them at will.

0
Comment actions Permalink

Thanks for this advice, never used a language psi. Seams to be more easy than i thought. By move you just mean remove+insertAt? Did not find a dedicated move method.

I have just one issue with this. Not all comments are parsed

# This is a comment
one = one <- property.getDocCommentText() = This is a comment

! This is a comment too
two = two <- property.getDocCommentText() = null

# This is a comment
! This is a comment too
three = three <- property.getDocCommentText() = null

How can i read out comments with '!' ?

0

Please sign in to leave a comment.