Puzzled !

I just got some exception from my MksPlugin,


Thing is, the source for this method (SandboxCacheImpl.getSandboxesIntersecting) is as follows, How can it ever return null ?

 getSandboxesIntersecting(@NotNull final VirtualFile directory) {
		Set result = new HashSet();

		for (List infoList : new ArrayList>(sandboxByFolder.values())) {
			for (MksSandboxInfo sandboxInfo : infoList) {
				if (sandboxInfo.isSubSandbox) continue;
				VirtualFile sandboxFile = sandboxInfo.sandboxPjFile;
				if (sandboxFile == null) {
					synchronized (lock) {
						LOGGER.warn("SandboxInfo with NULL virtualFile !! removing from registered sandboxes");
						infoList.remove(sandboxInfo);
						addRejected(sandboxInfo);
					}
				} else if (VfsUtil.isAncestor(directory, sandboxFile, false)) {
					result.add(sandboxInfo);
				} else {
					final VirtualFile sandboxParentFile = sandboxFile.getParent();
					if (sandboxParentFile != null && VfsUtil.isAncestor(sandboxParentFile, directory, false)) {
						result.add(sandboxInfo);
					}
				}

			}
		}
		return result;
	}
]]>

10 comments
Comment actions Permalink

Hello Thibaut,

We've received a number of similar exception reports, and as far as we can
see this is a HotSpot bug (which got worse in JDK 1.6.0_04). We inspected
the bytecode produced by our instrumentation, and weren't able to see any
problems with the generated code.

I just got some exception from my MksPlugin,

 @NotNull method
> org/intellij/vcs/mks/realtime/SandboxCacheImpl.getSandboxesIntersectin
> g must not return null
> java.lang.IllegalStateException: @NotNull method
> org/intellij/vcs/mks/realtime/SandboxCacheImpl.getSandboxesIntersectin
> g must not return null
> at
> org.intellij.vcs.mks.realtime.SandboxCacheImpl.getSandboxesIntersectin
> g(SandboxCacheImpl.java)
> at
> org.intellij.vcs.mks.MKSChangeProvider.collectSandboxesToRefresh(MKSCh
> angeProvider.java:206)
> at
> org.intellij.vcs.mks.MKSChangeProvider.getChanges(MKSChangeProvider.ja
> va:84)
> at
> com.intellij.openapi.vcs.changes.ChangeListManagerImpl.a(ChangeListMan
> agerImpl.java:96)
> at
> com.intellij.openapi.vcs.changes.ChangeListManagerImpl.access$700(Chan
> geListManagerImpl.java:167)
> at
> com.intellij.openapi.vcs.changes.ChangeListManagerImpl$4.run(ChangeLis
> tManagerImpl.java:1)
> at
> java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441
> )
> at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
> at java.util.concurrent.FutureTask.run(FutureTask.java:138)
> at
> java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.a
> ccess$301(ScheduledThreadPoolExecutor.java:98)
> at
> java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.r
> un(ScheduledThreadPoolExecutor.java:207)
> at
> java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecu
> tor.java:885)
> at
> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.
> java:907)
> at java.lang.Thread.run(Thread.java:619)
> ]]>


Thing is, the source for this method
(SandboxCacheImpl.getSandboxesIntersecting) is as follows, How can it
ever return null ?

 @NotNull
> public Set getSandboxesIntersecting(@NotNull final
> VirtualFile directory) {
> Set result = new HashSet();
> for (List infoList : new
> ArrayList>(sandboxByFolder.values())) {
> for (MksSandboxInfo sandboxInfo : infoList) {
> if (sandboxInfo.isSubSandbox) continue;
> VirtualFile sandboxFile = sandboxInfo.sandboxPjFile;
> if (sandboxFile == null) {
> synchronized (lock) {
> LOGGER.warn("SandboxInfo with NULL virtualFile !! removing from
> registered sandboxes");
> infoList.remove(sandboxInfo);
> addRejected(sandboxInfo);
> }
> } else if (VfsUtil.isAncestor(directory, sandboxFile, false)) {
> result.add(sandboxInfo);
> } else {
> final VirtualFile sandboxParentFile = sandboxFile.getParent();
> if (sandboxParentFile != null &&
> VfsUtil.isAncestor(sandboxParentFile, directory, false)) {
> result.add(sandboxInfo);
> }
> }
> }
> }
> return result;
> }
> ]]>

--
Dmitry Jemerov
Development Lead
JetBrains, Inc.
http://www.jetbrains.com/
"Develop with Pleasure!"


0
Comment actions Permalink

I stumbled upon exactly the same problem in my code yesterday.
Even more puzzling: my return value is final and never can get null.

0
Comment actions Permalink

Dmitry, have you seen it reported on Sun's BugParade ? so that i can wath/vote for it ?

0
Comment actions Permalink

Hello Thibaut,

Dmitry, have you seen it reported on Sun's BugParade ? so that i can
wath/vote for it ?


No, we don't yet have enough information for a specific report, other than
"it crashes sometimes in some cases".

--
Dmitry Jemerov
Development Lead
JetBrains, Inc.
http://www.jetbrains.com/
"Develop with Pleasure!"


0
Comment actions Permalink

the result variable seems to be (wrongly) GC'd

Thibaut wrote:

I just got some exception from my MksPlugin,

 @NotNull method org/intellij/vcs/mks/realtime/SandboxCacheImpl.getSandboxesIntersecting must not return null
> java.lang.IllegalStateException: @NotNull method org/intellij/vcs/mks/realtime/SandboxCacheImpl.getSandboxesIntersecting must not return null
> 	at org.intellij.vcs.mks.realtime.SandboxCacheImpl.getSandboxesIntersecting(SandboxCacheImpl.java)
> 	at org.intellij.vcs.mks.MKSChangeProvider.collectSandboxesToRefresh(MKSChangeProvider.java:206)
> 	at org.intellij.vcs.mks.MKSChangeProvider.getChanges(MKSChangeProvider.java:84)
> 	at com.intellij.openapi.vcs.changes.ChangeListManagerImpl.a(ChangeListManagerImpl.java:96)
> 	at com.intellij.openapi.vcs.changes.ChangeListManagerImpl.access$700(ChangeListManagerImpl.java:167)
> 	at com.intellij.openapi.vcs.changes.ChangeListManagerImpl$4.run(ChangeListManagerImpl.java:1)
> 	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
> 	at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
> 	at java.util.concurrent.FutureTask.run(FutureTask.java:138)
> 	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:98)
> 	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:207)
> 	at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:885)
> 	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:907)
> 	at java.lang.Thread.run(Thread.java:619)
> 
> ]]>


Thing is, the source for this method (SandboxCacheImpl.getSandboxesIntersecting) is as follows, How can it ever return null ?

 	@NotNull
> 	public Set getSandboxesIntersecting(@NotNull final VirtualFile directory) {
> 		Set result = new HashSet();
> 
> 		for (List infoList : new ArrayList>(sandboxByFolder.values())) {
> 			for (MksSandboxInfo sandboxInfo : infoList) {
> 				if (sandboxInfo.isSubSandbox) continue;
> 				VirtualFile sandboxFile = sandboxInfo.sandboxPjFile;
> 				if (sandboxFile == null) {
> 					synchronized (lock) {
> 						LOGGER.warn("SandboxInfo with NULL virtualFile !! removing from registered sandboxes");
> 						infoList.remove(sandboxInfo);
> 						addRejected(sandboxInfo);
> 					}
> 				} else if (VfsUtil.isAncestor(directory, sandboxFile, false)) {
> 					result.add(sandboxInfo);
> 				} else {
> 					final VirtualFile sandboxParentFile = sandboxFile.getParent();
> 					if (sandboxParentFile != null && VfsUtil.isAncestor(sandboxParentFile, directory, false)) {
> 						result.add(sandboxInfo);
> 					}
> 				}
> 
> 			}
> 		}
> 		return result;
> 	}
> ]]>



--
Best regards,
Maxim Mossienko
IntelliJ Labs / JetBrains Inc.
http://www.intellij.com
"Develop with pleasure!"

0
Comment actions Permalink

the result variable seems to be (wrongly) GC'd


wow, if the GC starts garbagin local variables while their owning frame is still on the call stack, we're gonna see strange things !

0
Comment actions Permalink

Following code gets NPE eventually with JDK 7 ea according to blog (in
Russian)
http://blogs.sun.com/vmrobot/entry/%D0%BF%D0%BE%D0%BC%D0%BD%D0%B8%D1%82%D0%B5_%D0%BE%D0%B1_%D0%BE%D0%BF%D1%82%D0%B8%D0%BC%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8

import java.util.logging.*;

public class TestLogger {

static void testLogger(boolean provokeGC) {
String name = "TestLogger";
Logger logger = Logger.getLogger(name);
if (provokeGC)
System.gc();
LogManager.getLogManager().getLogger(name).log(Level.SEVERE,
"Logger works");
}

public static void main(String[] args) {
for (int i = 0; i < 20000; i++) {
System.out.println("Iteration: " + i);
// at this point testLogger method should be compiled
boolean provokeGC = i > 10000;
testLogger(provokeGC);
}
}
}

Thibaut wrote:
>>the result variable seems to be (wrongly) GC'd


wow, if the GC starts garbagin local variables while their owning frame is still on the call stack, we're gonna see strange things !



--
Best regards,
Maxim Mossienko
IntelliJ Labs / JetBrains Inc.
http://www.intellij.com
"Develop with pleasure!"

0
Comment actions Permalink

thanks for the pointer, i managed to get the basics out of it thanks to google translate :)

0
Comment actions Permalink

I wonder if switching to a different garbage collector would help...

Bas

Maxim Mossienko (JetBrains) wrote:

the result variable seems to be (wrongly) GC'd

Thibaut wrote:

>> I just got some exception from my MksPlugin,
>>

> @NotNull method org/intellij/vcs/mks/realtime/SandboxCacheImpl.getSandboxesIntersecting must not return null
>> java.lang.IllegalStateException: @NotNull method org/intellij/vcs/mks/realtime/SandboxCacheImpl.getSandboxesIntersecting must not return null
>> 	at org.intellij.vcs.mks.realtime.SandboxCacheImpl.getSandboxesIntersecting(SandboxCacheImpl.java)
>> 	at org.intellij.vcs.mks.MKSChangeProvider.collectSandboxesToRefresh(MKSChangeProvider.java:206)
>> 	at org.intellij.vcs.mks.MKSChangeProvider.getChanges(MKSChangeProvider.java:84)
>> 	at com.intellij.openapi.vcs.changes.ChangeListManagerImpl.a(ChangeListManagerImpl.java:96)
>> 	at com.intellij.openapi.vcs.changes.ChangeListManagerImpl.access$700(ChangeListManagerImpl.java:167)
>> 	at com.intellij.openapi.vcs.changes.ChangeListManagerImpl$4.run(ChangeListManagerImpl.java:1)
>> 	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
>> 	at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
>> 	at java.util.concurrent.FutureTask.run(FutureTask.java:138)
>> 	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:98)
>> 	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:207)
>> 	at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:885)
>> 	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:907)
>> 	at java.lang.Thread.run(Thread.java:619)
>> 
>> ]]>

>>
>> Thing is, the source for this method (SandboxCacheImpl.getSandboxesIntersecting) is as follows, How can it ever return null ?
>>

> 	@NotNull
>> 	public Set getSandboxesIntersecting(@NotNull final VirtualFile directory) {
>> 		Set result = new HashSet();
>> 
>> 		for (List infoList : new ArrayList>(sandboxByFolder.values())) {
>> 			for (MksSandboxInfo sandboxInfo : infoList) {
>> 				if (sandboxInfo.isSubSandbox) continue;
>> 				VirtualFile sandboxFile = sandboxInfo.sandboxPjFile;
>> 				if (sandboxFile == null) {
>> 					synchronized (lock) {
>> 						LOGGER.warn("SandboxInfo with NULL virtualFile !! removing from registered sandboxes");
>> 						infoList.remove(sandboxInfo);
>> 						addRejected(sandboxInfo);
>> 					}
>> 				} else if (VfsUtil.isAncestor(directory, sandboxFile, false)) {
>> 					result.add(sandboxInfo);
>> 				} else {
>> 					final VirtualFile sandboxParentFile = sandboxFile.getParent();
>> 					if (sandboxParentFile != null && VfsUtil.isAncestor(sandboxParentFile, directory, false)) {
>> 						result.add(sandboxInfo);
>> 					}
>> 				}
>> 
>> 			}
>> 		}
>> 		return result;
>> 	}
>> ]]>


0
Comment actions Permalink

good point, i was using -XX:+UseParallelGC
i'll try without it

0

Please sign in to leave a comment.