Fixed a sporadic double unexport attempts to JarLoader.

Channel.export() creates a proxy that implicitly owns a reference count. If that proxy gets sent twice to the other side of the channel, it results in two copies of RemoteInvocationHandler, and each will try to release a reference count when it gets garbage collected, resulting in an attempt to unexport an object that's already unexported.

In case of JarLoader this can happen because the exported proxy object was set as a property that the other side calls waitForRemoteProperty on. The correct thing to do is to create a new proxy every time an object is serialized, via the writeObject method.

The full exception below. This error happened when I was working on an unrelated problem:

WARNING: Failed to monitor bar for Free Swap Space
java.util.concurrent.ExecutionException: java.lang.Error: Unable to load resource com/sun/jna/win32-x86/jnidispatch.dll
	at hudson.remoting.Channel$3.adapt(Channel.java:784)
	at hudson.remoting.Channel$3.adapt(Channel.java:779)
	at hudson.remoting.FutureAdapter.get(FutureAdapter.java:59)
	at hudson.node_monitors.AbstractAsyncNodeMonitorDescriptor.monitor(AbstractAsyncNodeMonitorDescriptor.java:97)
	at hudson.node_monitors.AbstractNodeMonitorDescriptor$Record.run(AbstractNodeMonitorDescriptor.java:302)
Caused by: java.lang.Error: Unable to load resource com/sun/jna/win32-x86/jnidispatch.dll
	at hudson.remoting.RemoteClassLoader.findResource(RemoteClassLoader.java:381)
	at java.lang.ClassLoader.getResource(Unknown Source)
	at com.sun.jna.Native.extractFromResourcePath(Native.java:830)
	at com.sun.jna.Native.loadNativeDispatchLibraryFromClasspath(Native.java:751)
	at com.sun.jna.Native.loadNativeDispatchLibrary(Native.java:736)
	at com.sun.jna.Native.<clinit>(Native.java:131)
	at com.sun.jna.Pointer.<clinit>(Pointer.java:41)
	at com.sun.jna.Structure.<clinit>(Structure.java:1949)
	at org.jvnet.hudson.Windows.monitor(Windows.java:42)
	at hudson.node_monitors.SwapSpaceMonitor$MonitorTask.call(SwapSpaceMonitor.java:113)
	at hudson.node_monitors.SwapSpaceMonitor$MonitorTask.call(SwapSpaceMonitor.java:103)
	at hudson.remoting.UserRequest.perform(UserRequest.java:121)
	at hudson.remoting.UserRequest.perform(UserRequest.java:49)
	at hudson.remoting.Request$2.run(Request.java:324)
	at hudson.remoting.InterceptingExecutorService$1.call(InterceptingExecutorService.java:68)
	at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source)
	at java.util.concurrent.FutureTask.run(Unknown Source)
	at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
	at hudson.remoting.Engine$1$1.run(Engine.java:63)
	at java.lang.Thread.run(Unknown Source)
	at ......remote call to bar(Native Method)
	at hudson.remoting.Channel.attachCallSiteStackTrace(Channel.java:1356)
	at hudson.remoting.UserResponse.retrieve(UserRequest.java:221)
	at hudson.remoting.Channel$3.adapt(Channel.java:782)
	... 4 more
Caused by: java.util.concurrent.ExecutionException: java.lang.IllegalStateException: Invalid object ID 2 iota=6
	at hudson.remoting.AsyncFutureImpl.get(AsyncFutureImpl.java:75)
	at hudson.remoting.FutureAdapter.get(FutureAdapter.java:55)
	at hudson.remoting.RemoteClassLoader.findResource(RemoteClassLoader.java:373)
	at java.lang.ClassLoader.getResource(Unknown Source)
	at com.sun.jna.Native.extractFromResourcePath(Native.java:830)
	at com.sun.jna.Native.loadNativeDispatchLibraryFromClasspath(Native.java:751)
	at com.sun.jna.Native.loadNativeDispatchLibrary(Native.java:736)
	at com.sun.jna.Native.<clinit>(Native.java:131)
	at com.sun.jna.Pointer.<clinit>(Pointer.java:41)
	at com.sun.jna.Structure.<clinit>(Structure.java:1949)
	at org.jvnet.hudson.Windows.monitor(Windows.java:42)
	at hudson.node_monitors.SwapSpaceMonitor$MonitorTask.call(SwapSpaceMonitor.java:113)
	at hudson.node_monitors.SwapSpaceMonitor$MonitorTask.call(SwapSpaceMonitor.java:103)
	at hudson.remoting.UserRequest.perform(UserRequest.java:121)
	at hudson.remoting.UserRequest.perform(UserRequest.java:49)
	at hudson.remoting.Request$2.run(Request.java:324)
	at hudson.remoting.InterceptingExecutorService$1.call(InterceptingExecutorService.java:68)
	at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source)
	at java.util.concurrent.FutureTask.run(Unknown Source)
	at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
	at hudson.remoting.Engine$1$1.run(Engine.java:63)
	at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.IllegalStateException: Invalid object ID 2 iota=6
	at hudson.remoting.ExportTable.diagnoseInvalidId(ExportTable.java:354)
	at hudson.remoting.ExportTable.get(ExportTable.java:330)
	at hudson.remoting.Channel.getExportedObject(Channel.java:604)
	at hudson.remoting.RemoteInvocationHandler$RPCRequest.perform(RemoteInvocationHandler.java:317)
	at hudson.remoting.Request$2.run(Request.java:324)
	at hudson.remoting.InterceptingExecutorService$1.call(InterceptingExecutorService.java:68)
	at jenkins.util.ContextResettingExecutorService$2.call(ContextResettingExecutorService.java:46)
	at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
	at java.util.concurrent.FutureTask.run(FutureTask.java:166)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
	at java.lang.Thread.run(Thread.java:722)
	at ......remote call to channel(Native Method)
	at hudson.remoting.Channel.attachCallSiteStackTrace(Channel.java:1356)
	at hudson.remoting.Request.call(Request.java:171)
	at hudson.remoting.RemoteInvocationHandler.invoke(RemoteInvocationHandler.java:182)
	at $Proxy5.writeJarTo(Unknown Source)
	at hudson.remoting.FileSystemJarCache.retrieve(FileSystemJarCache.java:66)
	at hudson.remoting.JarCacheSupport$1.run(JarCacheSupport.java:62)
	at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
	at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source)
	at java.util.concurrent.FutureTask.run(Unknown Source)
	at hudson.remoting.AtmostOneThreadExecutor$Worker.run(AtmostOneThreadExecutor.java:104)
	... 1 more
Caused by: java.lang.Exception: Object was recently deallocated
    #2 (ref.0) : object=null type=hudson.remoting.JarLoaderImpl interfaces=[hudson.remoting.JarLoader]
      Created at Tue Dec 16 15:59:14 PST 2014
    	at hudson.remoting.ExportTable$Entry.<init>(ExportTable.java:99)
    	at hudson.remoting.ExportTable.export(ExportTable.java:305)
    	at hudson.remoting.Channel.internalExport(Channel.java:600)
    	at hudson.remoting.Channel.export(Channel.java:591)
    	at hudson.remoting.Channel.<init>(Channel.java:472)
    	at hudson.remoting.ChannelBuilder.build(ChannelBuilder.java:280)
    	at hudson.remoting.ChannelBuilder.build(ChannelBuilder.java:290)
    	at org.jenkinsci.remoting.nio.NioChannelBuilder.build(NioChannelBuilder.java:36)
    	at org.jenkinsci.remoting.nio.NioChannelBuilder.build(NioChannelBuilder.java:52)
    	at jenkins.slaves.JnlpSlaveAgentProtocol$Handler.jnlpConnect(JnlpSlaveAgentProtocol.java:120)
    	at jenkins.slaves.DefaultJnlpSlaveReceiver.handle(DefaultJnlpSlaveReceiver.java:63)
    	at jenkins.slaves.JnlpSlaveAgentProtocol2$Handler2.run(JnlpSlaveAgentProtocol2.java:57)
    	at jenkins.slaves.JnlpSlaveAgentProtocol2.handle(JnlpSlaveAgentProtocol2.java:31)
    	at hudson.TcpSlaveAgentListener$ConnectionHandler.run(TcpSlaveAgentListener.java:156)
      Released at Tue Dec 16 15:59:14 PST 2014
    	at hudson.remoting.ExportTable$Entry.release(ExportTable.java:131)
    	at hudson.remoting.ExportTable.unexportByOid(ExportTable.java:382)
    	at hudson.remoting.Channel.unexport(Channel.java:612)
    	at hudson.remoting.UnexportCommand.execute(UnexportCommand.java:43)
    	at hudson.remoting.Channel$2.handle(Channel.java:483)
    	at hudson.remoting.AbstractByteArrayCommandTransport$1.handle(AbstractByteArrayCommandTransport.java:61)
    	at org.jenkinsci.remoting.nio.NioChannelHub$2.run(NioChannelHub.java:597)
    	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
    	at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
    	at java.util.concurrent.FutureTask.run(FutureTask.java:166)
    	at hudson.remoting.SingleLaneExecutorService$1.run(SingleLaneExecutorService.java:111)
    	at jenkins.util.ContextResettingExecutorService$1.run(ContextResettingExecutorService.java:28)
    	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
    	at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
    	at java.util.concurrent.FutureTask.run(FutureTask.java:166)
    	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
    	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
    	at java.lang.Thread.run(Thread.java:722)
    Caused by: Command hudson.remoting.UnexportCommand@4e2050eb created at
    	at hudson.remoting.Command.<init>(Command.java:67)
    	at hudson.remoting.Command.<init>(Command.java:50)
    	at hudson.remoting.UnexportCommand.<init>(UnexportCommand.java:33)
    	at hudson.remoting.RemoteInvocationHandler.finalize(RemoteInvocationHandler.java:240)
    	at java.lang.ref.Finalizer.invokeFinalizeMethod(Native Method)
    	at java.lang.ref.Finalizer.runFinalizer(Unknown Source)
    	at java.lang.ref.Finalizer.access$100(Unknown Source)
    	at java.lang.ref.Finalizer$FinalizerThread.run(Unknown Source)
    Caused by: java.lang.Exception: Proxy hudson.remoting.RemoteInvocationHandler@2 was created for interface hudson.remoting.JarLoader
    	at hudson.remoting.RemoteInvocationHandler.<init>(RemoteInvocationHandler.java:99)
    	at hudson.remoting.RemoteInvocationHandler.wrap(RemoteInvocationHandler.java:111)
    	at hudson.remoting.Channel.export(Channel.java:592)
    	at hudson.remoting.Channel.<init>(Channel.java:472)
    	at hudson.remoting.ChannelBuilder.build(ChannelBuilder.java:280)
    	at hudson.remoting.ChannelBuilder.build(ChannelBuilder.java:290)
    	at org.jenkinsci.remoting.nio.NioChannelBuilder.build(NioChannelBuilder.java:36)
    	at org.jenkinsci.remoting.nio.NioChannelBuilder.build(NioChannelBuilder.java:52)
    	at jenkins.slaves.JnlpSlaveAgentProtocol$Handler.jnlpConnect(JnlpSlaveAgentProtocol.java:120)
    	at jenkins.slaves.DefaultJnlpSlaveReceiver.handle(DefaultJnlpSlaveReceiver.java:63)
    	at jenkins.slaves.JnlpSlaveAgentProtocol2$Handler2.run(JnlpSlaveAgentProtocol2.java:57)
    	at jenkins.slaves.JnlpSlaveAgentProtocol2.handle(JnlpSlaveAgentProtocol2.java:31)
    	at hudson.TcpSlaveAgentListener$ConnectionHandler.run(TcpSlaveAgentListener.java:156)
	at hudson.remoting.ExportTable.diagnoseInvalidId(ExportTable.java:347)
	at hudson.remoting.ExportTable.get(ExportTable.java:330)
	at hudson.remoting.Channel.getExportedObject(Channel.java:604)
	at hudson.remoting.RemoteInvocationHandler$RPCRequest.perform(RemoteInvocationHandler.java:317)
	at hudson.remoting.Request$2.run(Request.java:324)
	at hudson.remoting.InterceptingExecutorService$1.call(InterceptingExecutorService.java:68)
	at jenkins.util.ContextResettingExecutorService$2.call(ContextResettingExecutorService.java:46)
	at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
	at java.util.concurrent.FutureTask.run(FutureTask.java:166)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
	at java.lang.Thread.run(Thread.java:722)
Caused by:   Released at Tue Dec 16 15:59:14 PST 2014
	at hudson.remoting.ExportTable$Entry.release(ExportTable.java:131)
	at hudson.remoting.ExportTable.unexportByOid(ExportTable.java:382)
	at hudson.remoting.Channel.unexport(Channel.java:612)
	at hudson.remoting.UnexportCommand.execute(UnexportCommand.java:43)
	at hudson.remoting.Channel$2.handle(Channel.java:483)
	at hudson.remoting.AbstractByteArrayCommandTransport$1.handle(AbstractByteArrayCommandTransport.java:61)
	at org.jenkinsci.remoting.nio.NioChannelHub$2.run(NioChannelHub.java:597)
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
	at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
	at java.util.concurrent.FutureTask.run(FutureTask.java:166)
	at hudson.remoting.SingleLaneExecutorService$1.run(SingleLaneExecutorService.java:111)
	at jenkins.util.ContextResettingExecutorService$1.run(ContextResettingExecutorService.java:28)
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
	... 5 more
Caused by: Command hudson.remoting.UnexportCommand@5e7a6d32 created at
	at hudson.remoting.Command.<init>(Command.java:67)
	at hudson.remoting.Command.<init>(Command.java:50)
	at hudson.remoting.UnexportCommand.<init>(UnexportCommand.java:33)
	at hudson.remoting.RemoteInvocationHandler.finalize(RemoteInvocationHandler.java:240)
	at java.lang.ref.Finalizer.invokeFinalizeMethod(Native Method)
	at java.lang.ref.Finalizer.runFinalizer(Unknown Source)
	at java.lang.ref.Finalizer.access$100(Unknown Source)
	at java.lang.ref.Finalizer$FinalizerThread.run(Unknown Source)
Caused by: java.lang.Exception: Proxy hudson.remoting.RemoteInvocationHandler@2 was created for interface hudson.remoting.JarLoader
	at hudson.remoting.RemoteInvocationHandler.<init>(RemoteInvocationHandler.java:99)
	at hudson.remoting.RemoteInvocationHandler.wrap(RemoteInvocationHandler.java:111)
	at hudson.remoting.Channel.export(Channel.java:592)
	at hudson.remoting.Channel.<init>(Channel.java:472)
	at hudson.remoting.ChannelBuilder.build(ChannelBuilder.java:280)
	at hudson.remoting.ChannelBuilder.build(ChannelBuilder.java:290)
	at org.jenkinsci.remoting.nio.NioChannelBuilder.build(NioChannelBuilder.java:36)
	at org.jenkinsci.remoting.nio.NioChannelBuilder.build(NioChannelBuilder.java:52)
	at jenkins.slaves.JnlpSlaveAgentProtocol$Handler.jnlpConnect(JnlpSlaveAgentProtocol.java:120)
	at jenkins.slaves.DefaultJnlpSlaveReceiver.handle(DefaultJnlpSlaveReceiver.java:63)
	at jenkins.slaves.JnlpSlaveAgentProtocol2$Handler2.run(JnlpSlaveAgentProtocol2.java:57)
	at jenkins.slaves.JnlpSlaveAgentProtocol2.handle(JnlpSlaveAgentProtocol2.java:31)
	at hudson.TcpSlaveAgentListener$ConnectionHandler.run(TcpSlaveAgentListener.java:156)