简体   繁体   中英

Why is finalize method called 2 times in wicket model

In my application I have class which extend wicket model and override finalized method(just delete file which is generated asynchronous). Problem is that finalized method is called immediately after wicket page is loaded for the first time and then once more

public class TournamentFileReadOnlyModel<I> extends AbstractReadOnlyModel<File> {

    private static final long serialVersionUID = 1L;

    private CallableService callableService;
    private String uuid;

    public TournamentFileReadOnlyModel(CallableService callableService, I input,
            Class<? extends AbstractPdfCallable<I>> callableClass) {
        this.uuid = UUID.randomUUID().toString();
        this.callableService = callableService;
        callableService.createFile(uuid, WicketApplication.getFilesPath(), input, callableClass);
    }

    @Override
    public File getObject() {
        return callableService.getFile(uuid);
    }

    @Override
    protected void finalize() throws Throwable {
        super.finalize();
        callableService.finalizeFile(uuid);
    }
}

I created link with this model:

    private void addPrintGroupButton() {
        add(new DownloadModelLink("printGroup", new TournamentFileReadOnlyModel<GroupPageDto>(callableService,
                groupPageDto, GroupPdfCallable.class)));
    }

log:

  1. time is called for me with no reason because I just load web page and still have reference for model

    17:50:45.493 [Finalizer] INFO org.tahom.processor.service.callable.CallableService - Cleaning file from cache with uuid: 61286bf6-da4c-4905-b65d-d6061eb1466f

  2. time is load for me OK because I load another web page and already lost reference for this model

    17:51:10.913 [Finalizer] INFO org.tahom.processor.service.callable.CallableService - Error when cleaning file from cache with uuid: 61286bf6-da4c-4905-b65d-d6061eb1466f java.lang.NullPointerException at org.tahom.processor.service.callable.CallableService.finalizeFile(CallableService.java:65) [tahom-processor-0.2.0-SNAPSHOT.jar:?] at WICKET_org.tahom.processor.service.callable.CallableService$$FastClassByCGLIB$$82eb5c9b.invoke() [cglib-3.1.jar:?] at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204) [cglib-3.1.jar:?] at org.apache.wicket.proxy.LazyInitProxyFactory$AbstractCGLibInterceptor.intercept(LazyInitProxyFactory.java:350) [wicket-ioc-7.1.0.jar:7.1.0] at WICKET_org.tahom.processor.service.callable.CallableService$$EnhancerByCGLIB$$41212df1.finalizeFile() [cglib-3.1.jar:?] at org.tahom.web.model.TournamentFileReadOnlyModel.finalize(TournamentFileReadOnlyModel.java:33) [classes/:?] at java.lang.ref.Finalizer.invokeFinalizeMethod(Native Method) ~[?:1.7.0_25] at java.lang.re f.Finalizer.runFinalizer(Finalizer.java:101) [?:1.7.0_25] at java.lang.ref.Finalizer.access$100(Finalizer.java:32) [?:1.7.0_25] at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:190) [?:1.7.0_25]

UPDATE

hm you are right. There is another intance of model. But then I dont how can be same uuid shared by different model. But this is another question

21:08:55.980 [qtp13530976-43] DEBUG org.tahom.processor.service.callable.CallableService - Creating file with uuidb485a4d1-ef67-4255-af64-4d7df6001b09 21:08:55.980 [qtp13530976-43] DEBUG org.tahom.web.model.TournamentFileReadOnlyModel - UUID b485a4d1-ef67-4255-af64-4d7df6001b09 generated for classorg.tahom.web.model.TournamentFileReadOnlyModel@1ba03be

21:08:56.794 [Finalizer] DEBUG org.tahom.web.model.TournamentFileReadOnlyModel - Class org.tahom.web.model.TournamentFileReadOnlyModel@14be425 21:08:56.907 [Finalizer] INFO org.tahom.processor.service.callable.CallableService - Cleaning file from cache with uuid: b485a4d1-ef67-4255-af64-4d7df6001b09

21:09:23.696 [Finalizer] WARN org.tahom.processor.service.callable.CallableService - Error when cleaning file from cache with uuid: b485a4d1-ef67-4255-af64-4d7df6001b09 21:09:23.696 [Finalizer] DEBUG org.tahom.web.model.TournamentFileReadOnlyModel - Class org.tahom.web.model.TournamentFileReadOnlyModel@1d76f52

Odds are you are dealing with (in other areas of your code) two instances of the TournamentFileReadOnlyModel .

Many frameworks create and destroy instances instead of hold them. Some do it to isolate one instance from another (web services isolating connections, for example) others do it to verify classes are of the right inheritance chain (SWT's Service interface, for example), some just do it to validate a detail.

In any case, putting required logic in a finalize block is a known "really bad pattern", and while you may be tempted to find the reason why your class is constructed twice, please instead consider not using a finalize block.

This might mean using a different approach for managing the temporary files you talked about; but, with a different approach, you can explicitly detail the policy instead hoping that the JVM (which has no guarantee to do so) follow your policy.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM