HotswapProjects / HotswapAgent

Java unlimited redefinition of classes at runtime.
GNU General Public License v2.0
2.33k stars 491 forks source link

NullPointerException at AnonymousClassInfos.lastModified(AnonymousClassInfos.java:252) #263

Open xtracoder opened 6 years ago

xtracoder commented 6 years ago

I'm constantly receiving NPE in AnonymousClassInfos on my codebase. I just upgraded to JDK 8-181 and hotswap-agent-1.3.0.jar - still the same problem.

I see similar report here (https://github.com/HotswapProjects/HotswapAgent/issues/180) in closed state and without reasonable solution.

PS: I'd like to debug what the problem is in my case and potentially fix it, but could not find guidelines how to debug the hotswap-agent itself.

HOTSWAP AGENT: 22:58:58.015 ERROR (org.hotswap.agent.annotation.handler.PluginClassFileTransformer) - InvocationTargetException in transform method on plugin 'class org.hotswap.agent.plugin.jvm.AnonymousClassPatchPlugin' class 'my/ui/MyTestNav'.
java.lang.reflect.InvocationTargetException
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.hotswap.agent.annotation.handler.PluginClassFileTransformer.transform(PluginClassFileTransformer.java:193)
        at org.hotswap.agent.annotation.handler.PluginClassFileTransformer.transform(PluginClassFileTransformer.java:89)
        at org.hotswap.agent.util.HotswapTransformer.transform(HotswapTransformer.java:184)
        at sun.instrument.TransformerManager.transform(TransformerManager.java:188)
        at sun.instrument.InstrumentationImpl.transform(InstrumentationImpl.java:428)
Caused by: java.lang.NullPointerException
        at org.hotswap.agent.plugin.jvm.AnonymousClassInfos.lastModified(AnonymousClassInfos.java:252)
        at org.hotswap.agent.plugin.jvm.AnonymousClassInfos.<init>(AnonymousClassInfos.java:90)
        at org.hotswap.agent.plugin.jvm.AnonymousClassPatchPlugin.getStateInfo(AnonymousClassPatchPlugin.java:218)
        at org.hotswap.agent.plugin.jvm.AnonymousClassPatchPlugin.patchMainClass(AnonymousClassPatchPlugin.java:160)
        ... 9 more
Seb-Sch commented 6 years ago

same for me - unable to use hotswap agent anymore :(

Any ideas how to get it working again?

skybber commented 6 years ago

Temporary workaround : disable AnonymousClassPatchPlugin using disablePlugin=AnonymousClassPatchPlugin

skybber commented 5 years ago

As far as anonymous class plugin, I have found race condition in it in the past there. Thing happens when I was debugging a web application and an anonymous class was added or changed. Sometimes the hotswap was called before anonymous class is deployed into WEB-INF/classes, then hotswap mechanism does not have required class on disk.

Polish-Civil commented 5 years ago

Still an issue

Tvede-dk commented 4 years ago

I have tried a bit of debugging, and it seems that the problem is caused by lastModified at the place

classPool.find(className);

which could be due to how Kotlin does Anonymous classes: If you look at AnonymousClassPatchPlugin.patchAnonymousClass , where it gets the "mainClass"; that class is not presented as a class file( which is the expectation),and the reason for the null PTR exception.

I have so far been able to "hack" my way though, by simply handling the potential null , followed by the class not found exception and then to use that specific name for the compatible name (in case I try and handle the exception in AnonymousClassPatchPlugin.patchAnonymousClass).

In short, the problem is the code never intended for whatever$1 to be the "main" class (from what I can deduce).

bric3 commented 2 years ago

Hi, I just encountered this.

Context: HA while developing a plugin for IntelliJ, where part of the codebase is in Kotlin.

HOTSWAP AGENT: 17:20:03.599 ERROR (org.hotswap.agent.annotation.handler.PluginClassFileTransformer) - InvocationTargetException in transform method on plugin 'class org.hotswap.agent.plugin.jvm.AnonymousClassPatchPlugin' class 'com/company/intellij/toolpane/SomeToolWindowPanel$makeUI$1'.
java.lang.reflect.InvocationTargetException
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at org.hotswap.agent.annotation.handler.PluginClassFileTransformer.transform(PluginClassFileTransformer.java:218)
    at org.hotswap.agent.annotation.handler.PluginClassFileTransformer.transform(PluginClassFileTransformer.java:112)
    at org.hotswap.agent.util.HotswapTransformer.transform(HotswapTransformer.java:246)
    at java.instrument/java.lang.instrument.ClassFileTransformer.transform(ClassFileTransformer.java:246)
    at java.instrument/sun.instrument.TransformerManager.transform(TransformerManager.java:188)
    at java.instrument/sun.instrument.InstrumentationImpl.transform(InstrumentationImpl.java:563)
Caused by: java.lang.NullPointerException
    at org.hotswap.agent.plugin.jvm.AnonymousClassInfos.lastModified(AnonymousClassInfos.java:270)
    at org.hotswap.agent.plugin.jvm.AnonymousClassInfos.<init>(AnonymousClassInfos.java:108)
    at org.hotswap.agent.plugin.jvm.AnonymousClassPatchPlugin.getStateInfo(AnonymousClassPatchPlugin.java:244)
    at org.hotswap.agent.plugin.jvm.AnonymousClassPatchPlugin.patchAnonymousClass(AnonymousClassPatchPlugin.java:104)
    ... 10 more

The code looks like this

import com.intellij.openapi.ui.DialogPanel
import com.intellij.openapi.ui.SimpleToolWindowPanel
import com.intellij.ui.dsl.builder.bindText
import com.intellij.ui.dsl.builder.panel
import javax.swing.Icon
import javax.swing.SwingUtilities

class SomeToolWindowPanel : SimpleToolWindowPanel(false, true) {
    private var model = MyModel()

    private val simplePanel = makeUI()

    init {
        add(simplePanel)
    }

    private fun makeUI(): DialogPanel {
        return panel {
            row {
                label("file:").bold()
                textField().bindText(model::file)
            }
        }
    }

    internal fun setModel(model: MyModel) {
        this.model = model
        SwingUtilities.invokeLater {
            simplePanel.reset()
            invalidate()
        }
    }

    companion object {
        @JvmField
        val DISPLAY_NAME: String = "A_TAB"
    }
}

This project is using Kotlin 1.5.31 on the JetBrains Runtime 11.0.13+7-b1751.21 x86_64