Skip to content

Commit febacd1

Browse files
committed
JCefComponent leak
1 parent 5fc5a3d commit febacd1

File tree

15 files changed

+62
-42
lines changed

15 files changed

+62
-42
lines changed

src/main/java/org/digma/intellij/plugin/documentation/DocumentationFileEditor.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public class DocumentationFileEditor extends UserDataHolderBase implements FileE
1616
private final VirtualFile file;
1717

1818
@Nullable
19-
private final JCefComponent jCefComponent;
19+
private JCefComponent jCefComponent;
2020

2121

2222
public DocumentationFileEditor(Project project, DocumentationVirtualFile file) {
@@ -99,6 +99,7 @@ public void removePropertyChangeListener(@NotNull PropertyChangeListener listene
9999
public void dispose() {
100100
if (jCefComponent != null) {
101101
jCefComponent.dispose();
102+
jCefComponent = null;
102103
}
103104
}
104105

src/main/java/org/digma/intellij/plugin/jaegerui/JaegerUIFileEditor.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public class JaegerUIFileEditor extends UserDataHolderBase implements FileEditor
1616
private final VirtualFile file;
1717

1818
@Nullable
19-
private final JCefComponent jCefComponent;
19+
private JCefComponent jCefComponent;
2020

2121
public JaegerUIFileEditor(Project project, JaegerUIVirtualFile file) {
2222
this.file = file;
@@ -98,6 +98,7 @@ public void removePropertyChangeListener(@NotNull PropertyChangeListener listene
9898
public void dispose() {
9999
if (jCefComponent != null) {
100100
jCefComponent.dispose();
101+
jCefComponent = null;
101102
}
102103
}
103104

src/main/java/org/digma/intellij/plugin/toolwindow/DigmaSidePaneToolWindowFactory.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import com.intellij.openapi.Disposable;
44
import com.intellij.openapi.diagnostic.Logger;
55
import com.intellij.openapi.project.Project;
6+
import com.intellij.openapi.util.Disposer;
67
import com.intellij.openapi.wm.*;
78
import com.intellij.ui.content.ContentFactory;
89
import com.intellij.util.ui.JBUI;
@@ -76,6 +77,9 @@ public void createToolWindowContent(@NotNull Project project, @NotNull ToolWindo
7677
//mainContent contains the mainCardsPanel ,MainToolWindowCardsController switches between no connection and mainToolWindowPanel
7778
var mainContent = ContentFactory.getInstance().createContent(mainCardsPanel, null, false);
7879

80+
//register disposable for mainContent,any project service is good for parent disposable
81+
Disposer.register(AnalyticsService.getInstance(project), mainContent);
82+
7983
toolWindow.getContentManager().addContent(mainContent);
8084

8185

src/main/kotlin/org/digma/intellij/plugin/ui/insights/InsightsService.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@ class InsightsService(val project: Project) : InsightsServiceImpl(project) {
4444
}
4545
}
4646

47+
override fun dispose(){
48+
jCefComponent = null
49+
}
50+
4751
fun setJCefComponent(jCefComponent: JCefComponent?) {
4852
this.jCefComponent = jCefComponent
4953
}

src/main/kotlin/org/digma/intellij/plugin/ui/jcef/JCefComponent.kt

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ import javax.swing.JComponent
5050
/*
5151
JCefComponentBuilder.build already registers a disposable for this JCefComponent using parentDisposable,
5252
this JCefComponent uses parentDisposable for all its listeners and connections.
53+
5354
*/
5455
class JCefComponent
5556
private constructor(
@@ -323,8 +324,6 @@ private constructor(
323324
try {
324325
jbCefBrowser.jbCefClient.dispose()
325326
jbCefBrowser.dispose()
326-
//todo: not sure this is necessary
327-
//cefMessageRouter.removeHandler(messageRouterHandler)
328327
cefMessageRouter.dispose()
329328
ApplicationUISettingsChangeNotifier.getInstance(project).removeSettingsChangeListener(settingsChangeListener)
330329
} catch (e: Exception) {
@@ -348,41 +347,45 @@ private constructor(
348347
schemeHandlerFactory: BaseSchemeHandlerFactory
349348
) {
350349

351-
private val url = WeakReference(Objects.requireNonNull(url, "url must not be null"))
352-
private val messageRouterHandler = WeakReference(Objects.requireNonNull(messageRouterHandler, "messageRouterHandlers must not be null"))
353-
private val schemeHandlerFactory = WeakReference(Objects.requireNonNull(schemeHandlerFactory, "schemeHandlerFactory must not be null"))
354-
private val parentDisposable = WeakReference(parentDisposable)
355-
private var downloadAdapter: WeakReference<CefDownloadHandler>? = null
350+
private val urlRef = WeakReference(Objects.requireNonNull(url, "url must not be null"))
351+
private val messageRouterHandlerRef = WeakReference(Objects.requireNonNull(messageRouterHandler, "messageRouterHandlers must not be null"))
352+
private val schemeHandlerFactoryRef = WeakReference(Objects.requireNonNull(schemeHandlerFactory, "schemeHandlerFactory must not be null"))
353+
private val parentDisposableRef = WeakReference(parentDisposable)
354+
private var downloadAdapterRef: WeakReference<CefDownloadHandler>? = null
356355

357356

358357
fun build(): JCefComponent {
359358

359+
val url: String = Objects.requireNonNull(urlRef.get(), "url must not be null")!!
360+
val messageRouterHandler = Objects.requireNonNull(messageRouterHandlerRef.get(), "messageRouterHandlers must not be null")!!
361+
val schemeHandlerFactory = Objects.requireNonNull(schemeHandlerFactoryRef.get(), "schemeHandlerFactory must not be null")!!
362+
val parentDisposable = Objects.requireNonNull(parentDisposableRef.get(), "parentDisposable must not be null")!!
363+
364+
360365
val jbCefBrowser = JBCefBrowserBuilderCreator.create()
361-
.setUrl(url.get())
366+
.setUrl(url)
362367
.build()
363368

364369
val jbCefClient = jbCefBrowser.jbCefClient
365370
val cefMessageRouter = CefMessageRouter.create()
366-
cefMessageRouter.addHandler(messageRouterHandler.get()!!, true)
371+
cefMessageRouter.addHandler(messageRouterHandler, true)
367372
jbCefClient.cefClient.addMessageRouter(cefMessageRouter)
368373

369374
jbCefClient.cefClient.addDisplayHandler(JCefDisplayHandler(name))
370375

371-
jbCefBrowser.jbCefClient.addLifeSpanHandler(LifeSpanHandle(schemeHandlerFactory.get()!!), jbCefBrowser.cefBrowser)
376+
jbCefBrowser.jbCefClient.addLifeSpanHandler(LifeSpanHandle(schemeHandlerFactory), jbCefBrowser.cefBrowser)
372377

373-
downloadAdapter?.let {
374-
jbCefClient.cefClient.addDownloadHandler(it.get())
378+
downloadAdapterRef?.get()?.let {
379+
jbCefClient.cefClient.addDownloadHandler(it)
375380
}
376381

377382
val jCefComponent =
378-
JCefComponent(project, parentDisposable.get()!!, name, jbCefBrowser, cefMessageRouter)
383+
JCefComponent(project, parentDisposable, name, jbCefBrowser, cefMessageRouter)
379384

380385
//usually the component that holds a reference to JCefComponent needs to call JCefComponent.dispose.
381386
//when a parentDisposable is supplied then use it also to dispose, worst case dispose will be called twice.
382-
parentDisposable.get()!!.let {
383-
Disposer.register(it) {
384-
jCefComponent.dispose()
385-
}
387+
Disposer.register(parentDisposable) {
388+
jCefComponent.dispose()
386389
}
387390

388391

@@ -391,16 +394,14 @@ private constructor(
391394
}
392395

393396

394-
395-
396397
fun withDownloadAdapter(adapter: CefDownloadHandler): JCefComponentBuilder {
397-
this.downloadAdapter = WeakReference(Objects.requireNonNull(adapter, "downloadAdapter must not be null"))
398+
this.downloadAdapterRef = WeakReference(Objects.requireNonNull(adapter, "downloadAdapter must not be null"))
398399
return this
399400
}
400401
}
401402
}
402403

403-
class LifeSpanHandle(private val schemeHandlerFactory: BaseSchemeHandlerFactory) : CefLifeSpanHandlerAdapter(){
404+
class LifeSpanHandle(private val schemeHandlerFactory: BaseSchemeHandlerFactory) : CefLifeSpanHandlerAdapter() {
404405

405406
override fun onAfterCreated(browser: CefBrowser) {
406407
//schemeHandlerFactory must not be null here!

src/main/kotlin/org/digma/intellij/plugin/ui/mainapp/MainAppPanel.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,9 @@ import javax.swing.JLabel
1919

2020
class MainAppPanel(private val project: Project) : DisposablePanel() {
2121

22-
private var jCefComponent: JCefComponent? = null
23-
2422
init {
2523

26-
jCefComponent = createJcefComponent()
24+
val jCefComponent = createJcefComponent()
2725

2826
val jcefUiComponent: JComponent = jCefComponent?.getComponent() ?: JLabel("JCEF not supported")
2927

@@ -33,6 +31,8 @@ class MainAppPanel(private val project: Project) : DisposablePanel() {
3331
background = listBackground()
3432

3533
Disposer.register(MainAppService.getInstance(project)) {
34+
jCefComponent?.dispose()
35+
remove(jcefUiComponent)
3636
dispose()
3737
}
3838

@@ -67,6 +67,6 @@ class MainAppPanel(private val project: Project) : DisposablePanel() {
6767
}
6868

6969
override fun dispose() {
70-
jCefComponent?.dispose()
70+
//nothing to do
7171
}
7272
}

src/main/kotlin/org/digma/intellij/plugin/ui/mainapp/MainAppService.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ class MainAppService(private val project: Project) : Disposable {
3535

3636

3737
override fun dispose() {
38-
//nothing to do , used as parent disposable
38+
this.jCefComponent = null
3939
}
4040

4141
fun setJCefComponent(jCefComponent: JCefComponent) {

src/main/kotlin/org/digma/intellij/plugin/ui/navigation/CodeButtonCaretContextService.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ class CodeButtonCaretContextService(private val project: Project) : CaretContext
4242
}
4343

4444
override fun dispose() {
45-
//nothing to do
45+
jCefComponent = null
4646
}
4747

4848
override fun contextChanged(methodUnderCaret: MethodUnderCaret) {

src/main/kotlin/org/digma/intellij/plugin/ui/navigation/NavigationService.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ class NavigationService(private val project: Project) : Disposable {
4242

4343

4444
override fun dispose() {
45-
//nothing to do , used as parent disposable
45+
jCefComponent = null
4646
}
4747

4848
fun setJCefComponent(jCefComponent: JCefComponent) {

src/main/kotlin/org/digma/intellij/plugin/ui/recentactivity/LiveViewUpdater.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ class LiveViewUpdater(val project: Project) : Disposable {
4343
myDisposable?.let {
4444
Disposer.dispose(it)
4545
}
46+
jCefComponent = null
4647
}
4748

4849

0 commit comments

Comments
 (0)