【问题标题】:Java - java.lang.Error: SWT Resource was not properly disposedJava - java.lang.Error: SWT 资源未正确处理
【发布时间】:2021-05-28 02:18:05
【问题描述】:

我正在重新开始使用 JAVA 编程语言。为了重新介绍自己,我正在编写一个简单的银行程序,其中包含单元测试以适应语法。我在编译代码时遇到了问题,因为我看到了一个以前从未见过的错误。

java.lang.Error: SWT Resource was not properly disposed
    at org.eclipse.swt.graphics.Resource.initNonDisposeTracking(Resource.java:172)
    at org.eclipse.swt.graphics.Resource.<init>(Resource.java:120)
    at org.eclipse.swt.graphics.Image.<init>(Image.java:498)
    at org.eclipse.e4.ui.workbench.renderers.swt.CTabRendering.createShadow(CTabRendering.java:910)
    at org.eclipse.e4.ui.workbench.renderers.swt.CTabRendering.setShadowColor(CTabRendering.java:1054)
    at org.eclipse.e4.ui.css.swt.dom.CTabFolderElement.reset(CTabFolderElement.java:136)
    at org.eclipse.e4.ui.css.swt.engine.AbstractCSSSWTEngineImpl.reset(AbstractCSSSWTEngineImpl.java:126)
    at org.eclipse.e4.ui.css.swt.internal.theme.ThemeEngine.setTheme(ThemeEngine.java:453)
    at org.eclipse.e4.ui.css.swt.internal.theme.ThemeEngine.setTheme(ThemeEngine.java:434)
    at org.eclipse.ui.internal.dialogs.ViewsPreferencePage.performOk(ViewsPreferencePage.java:264)
    at org.eclipse.jface.preference.PreferenceDialog$7.run(PreferenceDialog.java:905)
    at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:45)
    at org.eclipse.jface.util.SafeRunnable.run(SafeRunnable.java:174)
    at org.eclipse.jface.preference.PreferenceDialog.okPressed(PreferenceDialog.java:889)
    at org.eclipse.ui.internal.dialogs.FilteredPreferenceDialog.okPressed(FilteredPreferenceDialog.java:461)
    at org.eclipse.jface.preference.PreferenceDialog.buttonPressed(PreferenceDialog.java:233)
    at org.eclipse.jface.dialogs.Dialog.lambda$0(Dialog.java:619)
    at org.eclipse.swt.events.SelectionListener$1.widgetSelected(SelectionListener.java:84)
    at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:252)
    at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:89)
    at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4209)
    at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1043)
    at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:4026)
    at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3626)
    at org.eclipse.jface.window.Window.runEventLoop(Window.java:823)
    at org.eclipse.jface.window.Window.open(Window.java:799)
    at org.eclipse.ui.internal.OpenPreferencesAction.run(OpenPreferencesAction.java:66)
    at org.eclipse.jface.action.Action.runWithEvent(Action.java:474)
    at org.eclipse.jface.action.ActionContributionItem.handleWidgetSelection(ActionContributionItem.java:580)
    at org.eclipse.jface.action.ActionContributionItem.lambda$4(ActionContributionItem.java:414)
    at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:89)
    at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4209)
    at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1043)
    at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:4026)
    at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3626)
    at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1157)
    at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:338)
    at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1046)
    at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:155)
    at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:644)
    at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:338)
    at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:551)
    at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:156)
    at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:152)
    at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:203)
    at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134)
    at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104)
    at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:401)
    at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:255)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:564)
    at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653)
    at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590)
    at org.eclipse.equinox.launcher.Main.run(Main.java:1461) 

我在 Google 上进行了大量研究,但尚未找到解决方案。有谁知道为什么我在错误日志中两次收到此错误?

我正在使用 Eclipse IDE。这是我的代码:

BankAccount.java:

package simplebank;

public class BankAccount {

    private double balance;
    
    public BankAccount()
    {
        balance = 0;
    }
    
    public BankAccount(double initialBalance)
    {
        balance = initialBalance;
    }
    
    public double getBalance()
    {
        return balance;
    }
    
    boolean deposit(double amount)  
    {
        
        if(amount > 0 && balance - amount > 0)
        {   
            balance = balance + amount;
            return true; 
        }
        return false;
    }
    
    public boolean withdrawl(double amount)
    {
        if (amount > 0)
        {   
            balance = balance - amount;
            return true;
        }
        
        return false;
    }
    
    public boolean transfer(BankAccount transferTo, double amount)
    {
        
        if (amount > 0)
        {
            if(this.withdrawl(amount))
            {
                if(transferTo.deposit(amount))
                {
                    
                }
                else // Return bank account to normal 
                {
                    this.deposit(amount);
                    return false;
                }
            }   
            
            return true;
        }
        
        return false;
    }
    
}

BankAccountTest.java

package simplebank;

import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;

class BankAccountTest {

    BankAccount account1  = null;
    BankAccount account2 = null;
    @BeforeAll
    public void setup() {
        account1 = new BankAccount(20.00);
        account2 = new BankAccount();
    }
    
    @Test
    void testGetBalance() {
        assert(account1.getBalance() == 20.00);
    }

    @Test
    void testDeposit() {
        account1.deposit(20);
        assert(account1.getBalance() == 40.00);
    }

    @Test
    void testWithdrawl() {
        account1.withdrawl(10);
        assert(account1.getBalance() == 30.00);
    }

    @Test
    void testTransfer() {
        account1.transfer(account2, 10);
        assert(account1.getBalance() == 20.00);
        assert(account2.getBalance() == 10.00);
    }
}

作为旁注,如果有人对我如何改进这个简单的代码有任何建议,请留下您的建议!我刚刚回到 JAVA,所以我的风格可能不是最好的。

【问题讨论】:

  • 这看起来像是 Eclipse 中的一个错误,与您的代码没有任何关系

标签: java eclipse compilation


【解决方案1】:

在 Eclipse 4.19 (2021-03) 中添加了一个用于跟踪正确资源处置的 API,请参阅 https://www.eclipse.org/eclipse/news/4.19/platform_isv.php#resource-disposal-tracking

这就是这些错误的来源。

尝试在你的 eclipse.ini 中设置从 truefalse -Dorg.eclipse.swt.graphics.Resource.reportNonDisposed=true 摆脱他们。不确定它会起作用。

【讨论】:

  • 对我不起作用
  • 我对 jface.wizard.WizardDialog / WizardPage 有类似的问题,它不会正确处理它创建的图像。您的解决方案只是告诉 RCP 保持沉默,但它当然不能解决资源泄漏的问题。设置标志还会隐藏这些真正是开发人员错误的痕迹。
【解决方案2】:

在尝试了各种代码示例后,我将测试文件更改为包含以下代码:

package simplebank;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import junit.framework.ComparisonFailure;

class BankAccountTest {
    BankAccount account1  = null;
    BankAccount account2 = null;
    
    @BeforeEach
    void setUp() throws Exception {
        account1 = new BankAccount(20.00);
        account2 = new BankAccount();
    }

    @AfterEach
    void tearDown() throws Exception {
        account1 = null;
        account2 = null;
    }

    @Test
    void testGetBalance() {
        assert(account1.getBalance() == 20.00);
    }
    
    void testDeposit() {
        account1.deposit(20);
        assert(account1.getBalance() == 40.00);
    }
    
    @Test
    void testWithdrawl() {
        account1.withdrawl(10);
        assert(account1.getBalance() == 10.00);
    }
    
    @Test
    void testTransfer() {
        account1.transfer(account2, 10);
        assert(account1.getBalance() == 10.00);
        assert(account2.getBalance() == 10.00);
    }
}

它现在编译并运行所有测试。不同之处在于我现在使用@BeforeEach 和@AfterEach 而不是@BeforeAll。另一个区别是每个 before 和 after 函数在声明中都包含一个 throws Exception 。我还没有尝试使用 @BeforeAll 函数添加 throw Exception,因为 @BeforeEach 适合我的目的。我最好的猜测是缺少“抛出异常”语句导致了上述错误。我希望这可以帮助其他人将来解决此问题。

【讨论】:

  • 我认为这与您的代码无关,而是与 Eclipse 问题有关。我也看到了,我使用@BeforeEach
猜你喜欢
  • 2013-03-13
  • 2018-08-19
  • 2010-11-10
  • 2021-12-29
  • 2017-10-09
  • 1970-01-01
  • 1970-01-01
  • 2011-08-25
  • 2023-04-08
相关资源
最近更新 更多