Java - java.lang.Error: SWT资源未正确处理

4

我正在重新学习使用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,所以我的风格可能不是最好的。


1
这似乎是Eclipse中的一个错误,与你的代码没有什么关系。 - greg-449
2个回答

6

1
没有对我起作用。 - alrts
我遇到了与jface.wizard.WizardDialog / WizardPage类似的问题,它不能正确地处理创建的图像。您的解决方案只是告诉RCP保持安静,但当然它并没有解决资源泄漏的问题。设置标志也会隐藏这些痕迹,而实际上这是开发人员的责任。 - Chris Lewold
你说得对,这个标志只是隐藏了问题。但是OP的代码没有做任何与RCP相关的事情。实际上,Eclipse本身正在用内部警告消息刷屏日志。Eclipse开发人员有责任解决这些问题(包括你的WizardPage示例)。 - Anho
对我有用,在Eclipse中谢谢。 - Manoj Mali

1

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

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。我尚未尝试使用添加了throw Exception的@BeforeAll函数,因为@BeforeEach适合我的目的。我最好的猜测是缺少"throws Exception"语句导致上述错误。我希望这能帮助其他人解决将来的问题。

2
我不认为这与你的代码有任何关系,而是与Eclipse的问题有关。我也遇到了相同的问题,我使用@BeforeEach。 - pixel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接