Strange NPE when iterating over result of ClassLoader.getResources() - java

I would assume that the following code is safe, nevertheless I am getting an NPE while invoking hasMoreElements(). Any ideas what might be wrong?
I should add that I am using Java 1.7.0_55-b13 on Windows, 64 bit.
final List<URL> urls = new ArrayList<URL>();
final String plUri = "META-INF/plugin.xml";
Enumeration<URL> urlsEn =
Thread.currentThread().getContextClassLoader().getResources(pluginsUri);
if (urlsEn != null) {
while (urlsEn.hasMoreElements()) { // NPE happens here
final URL u = urlsEn.nextElement();
urls.add(u);
}
}
Stack trace:
java.lang.NullPointerException
at sun.misc.MetaIndex.mayContain(MetaIndex.java:243)
at sun.misc.URLClassPath$JarLoader.getResource(URLClassPath.java:830)
at sun.misc.URLClassPath$2.next(URLClassPath.java:273)
at sun.misc.URLClassPath$2.hasMoreElements(URLClassPath.java:283)
at java.lang.ClassLoader$2.hasMoreElements(ClassLoader.java:1322)
at sun.misc.CompoundEnumeration.next(CompoundEnumeration.java:45)
at sun.misc.CompoundEnumeration.hasMoreElements(CompoundEnumeration.java:54)
at sun.misc.CompoundEnumeration.next(CompoundEnumeration.java:45)
at sun.misc.CompoundEnumeration.hasMoreElements(CompoundEnumeration.java:54)
at com.github.jochen.afw.core.guice.GuiceComponentFactoryBuilder.getComponentUrls(GuiceComponentFactoryBuilder.java:256)
at com.github.jochen.afw.core.guice.GuiceComponentFactoryBuilder.build(GuiceComponentFactoryBuilder.java:160)
at com.github.jochen.afw.core.guice.GuiceComponentFactoryBuilderTest.testSuccessfullConfiguration(GuiceComponentFactoryBuilderTest.java:20)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
....

I hate to suggest your problem is something so simple, but could pluginsUri be null here? At least in your code snippet, you create a plUri variable but then pass in an unmentioned pluginsUri to ClassLoader.getResources().
From your stack trace, searching for "URLClassPath null pointer exception" uncovered this question which looks to be the same stack trace. In their case the argument to getResources() is clearly null.
Looking at the Java 7 codebase, we see that MetaIndex:243 is:
if (entry.startsWith(conts[i])) {
And entry could be null at this line. Looking higher up the stack, entry looks to be the name argument you passed to ClassLoader.getResources().
This SSCCE:
public class ClassLoaderNPE {
public static void main(String[] args) throws IOException {
Enumeration<URL> urls = ClassLoader.getSystemClassLoader().getResources(null);
System.out.println(urls.hasMoreElements());
}
}
replicates your stack trace (in Java 8, no less):
$ java -version
java version "1.8.0_45"
Java(TM) SE Runtime Environment (build 1.8.0_45-b15)
Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02, mixed mode)
$ java -cp . ClassLoaderNPE
Exception in thread "main" java.lang.NullPointerException
at sun.misc.MetaIndex.mayContain(MetaIndex.java:242)
at sun.misc.URLClassPath$JarLoader.getResource(URLClassPath.java:995)
at sun.misc.URLClassPath$2.next(URLClassPath.java:288)
at sun.misc.URLClassPath$2.hasMoreElements(URLClassPath.java:298)
at java.lang.ClassLoader$2.hasMoreElements(ClassLoader.java:1278)
at sun.misc.CompoundEnumeration.next(CompoundEnumeration.java:45)
at sun.misc.CompoundEnumeration.hasMoreElements(CompoundEnumeration.java:54)
at sun.misc.CompoundEnumeration.next(CompoundEnumeration.java:45)
at sun.misc.CompoundEnumeration.hasMoreElements(CompoundEnumeration.java:54)
at ClassLoaderNPE.main(ClassLoaderNPE.java:9)
The JDK does not appear specify what happens if name is null. I've filed a bug to suggest fixing this behavior, or at least clarifying the documentation. I'll update this post if/when Oracle accepts the issue.
Update: The report is tracked as JDK-8136831, and has been fixed in Java 9.

Related

Pattern Matching for instanceof throwing a confusing error: expression type Triple is a subtype of pattern type Triple

I have Java 19, and I am attempting to do some simple pattern-matching on a record that I created. However, Java is giving me a very confusing compilation error. Here is the simplest example I could make that causes the error.
public class ExpressionTypeIsASubsetOfPatternType
{
public record Triple(int a, int b, int c) {}
public static void main(String[] args)
{
System.out.println("Java Version = " + System.getProperty("java.version"));
final Triple input = new Triple(1, 2, 3);
if (input instanceof Triple t)
{
System.out.println("Made it here");
}
}
}
And here is the error that it gives me when I try to run/compile.
$ java ExpressionTypeIsASubsetOfPatternType.java
ExpressionTypeIsASubsetOfPatternType.java:15: error: expression type Triple is a subtype of pattern type Triple
if (input instanceof Triple t)
^
1 error
error: compilation failed
Surprisingly enough, googling this error showed up nothing useful. I am so used to punching in an error and immediately seeing the problem. I imagine that it is because this feature is so new.
Anyways, the closest thing I could find is a bug that is related, but definitely not the same issue that I am dealing with.
Finally, here is the relevant info about my java version.
$ java --version
openjdk 19 2022-09-20
OpenJDK Runtime Environment (build 19+36-2238)
OpenJDK 64-Bit Server VM (build 19+36-2238, mixed mode, sharing)
$ javac --version
javac 19
Java is just being "nice": it recognizes that the test will always succeed (because input is known to be a Triple, which is already a subtype of the test type Triple), so it produces an error telling you that you're doing something useless (with a roundabout message).
This is the same idea that makes
void foo() {
return;
return; // error: unreachable statement
}
an error: there is a useless piece of code that might indicate (serious) programmer error, so the compiler forces you to rethink the code.
The relevant section of the JLS is 15.20.2, which says
InstanceofExpression:
...
RelationalExpression instanceof Pattern
...
The following rules apply when instanceof is the pattern match operator:
...
If the type of the RelationalExpression is a subtype of the type of the Pattern, then a compile-time error occurs.
I.e. this is indeed an intended part of the language and not just a compiler bug or something.

Why does Java 8's Nashorn engine in strict mode throw a java.lang.ClassCastException when calling apply() and passing the arguments object directly?

When I call eval (in strict mode) on a nashorn engine with the following script I get an exception:
var yfunc = function () {
(null).apply(null, arguments);
};
yfunc();
I've truncated my personal situation heavily. The "(null)" on line 2 can be replaced with anything between parenthesis or a local variable, either way just something that shouldn't throw a compile error, and it will yield the same result.
The issue seems to be explicitly that "arguments" is passed directly as the second argument of calling a method called "apply". Any of the following changes will undo the thrown exception:
Putting "arguments" in a variable first (but simply wrapping it in parenthesis doesn't work!)
Calling something other than apply
Passing "arguments" in a different argument slot when calling apply
Calling print() (with or without passing any arguments) as a preceding line of code inside yfunc() (weird huh?)
Defining more than 0 parameters for yfunc()
Binding yfunc first and then calling the bound method
Calling yfunc via Function.apply (not so much with Function.call!)
The Exception thrown is this:
Exception in thread "main" java.lang.ClassCastException: Cannot cast jdk.nashorn.internal.runtime.Undefined to jdk.nashorn.internal.runtime.ScriptFunction
at java.lang.invoke.MethodHandleImpl.newClassCastException(MethodHandleImpl.java:361)
at java.lang.invoke.MethodHandleImpl.castReference(MethodHandleImpl.java:356)
at jdk.nashorn.internal.scripts.Script$\^eval\_.:program(<eval>:4)
at jdk.nashorn.internal.runtime.ScriptFunctionData.invoke(ScriptFunctionData.java:637)
at jdk.nashorn.internal.runtime.ScriptFunction.invoke(ScriptFunction.java:494)
at jdk.nashorn.internal.runtime.ScriptRuntime.apply(ScriptRuntime.java:393)
at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:449)
at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:406)
at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:402)
at jdk.nashorn.api.scripting.NashornScriptEngine.eval(NashornScriptEngine.java:155)
at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:264)
When I call this method with an owner, the exception thrown changes. Example code:
var yfunc = {
method: function () {
(null).apply(null, arguments);
}
};
var x = yfunc.method();
Then the thrown exception looks like this:
Exception in thread "main" java.lang.ClassCastException: Cannot cast jdk.nashorn.internal.scripts.JO4 to jdk.nashorn.internal.runtime.ScriptFunction
at java.lang.invoke.MethodHandleImpl.newClassCastException(MethodHandleImpl.java:361)
at java.lang.invoke.MethodHandleImpl.castReference(MethodHandleImpl.java:356)
at jdk.nashorn.internal.scripts.Script$\^eval\_.:program(<eval>:5)
at jdk.nashorn.internal.runtime.ScriptFunctionData.invoke(ScriptFunctionData.java:637)
at jdk.nashorn.internal.runtime.ScriptFunction.invoke(ScriptFunction.java:494)
at jdk.nashorn.internal.runtime.ScriptRuntime.apply(ScriptRuntime.java:393)
at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:449)
at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:406)
at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:402)
at jdk.nashorn.api.scripting.NashornScriptEngine.eval(NashornScriptEngine.java:155)
at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:264)
I've reproduced the issue so far on specifically these environments:
windows 7 64bit -> jdk 1.8.0_60 64bit
windows 8 64bit -> jdk 1.8.0_131 64bit
I can't seem to find anything on the internet about similar issues. Do I need to report this to Oracle/OpenJDK?
Minor update
Added items 6 and 7 to list of "following changes will undo the thrown exception".
Final update
Bug filed: JDK-8184720
Yes, it appears to be a bug. Please file a bug.

Unable to compile MPI programs in Java - UnsupportedClassVersionError

I am totally new to MPJ which is an API for developing MPI based programs in Java. I wrote a simple code as follows:
import mpi.MPI;
import mpi.Status;
public class Send {
public static void main(String[] args) throws Exception
{
MPI.Init(args);
int rank = MPI.COMM_WORLD.Rank();
int size = MPI.COMM_WORLD.Size();
int peer;
int buffer[] = new int[10];
int len = 1;
int dataToBeSent = 99;
int tag = 100;
if(rank == 0)
{
buffer[0] = dataToBeSent;
peer = 1;
MPI.COMM_WORLD.Send(buffer, 0, len, MPI.INT, peer, tag);
System.out.println("process <"+rank+"> sent a msg to process <"+peer+">");
}
else if(rank == 1)
{
peer = 0 ;
Status status = MPI.COMM_WORLD.Recv(buffer, 0, buffer.length, MPI.INT, peer, tag);
System.out.println("process <"+rank+"> recv'ed a msg\n"+ "\tdata <"+buffer[0]+"> \n"+"\tsource <"+status.source+"> \n"+"\ttag<"+status.tag+"> \n"+"\tcount <"+status.count +">");
}
MPI.Finalize();
}
}
When I compile, I get the following error:
Exception in thread "main" java.lang.UnsupportedClassVersionError: mpi/MPI : Unsupported major.minor version 51.0
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:620)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:124)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:260)
at java.net.URLClassLoader.access$000(URLClassLoader.java:56)
at java.net.URLClassLoader$1.run(URLClassLoader.java:195)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:276)
at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319)
at Send.main(Send.java:7)
Java Result: 1
To resolve this issue, I came to know that both my JDK and JRE versions must be the same. After executing the following commands, I found that they are same and not different:
C:\Users\Dev>javac -version
javac 1.6.0
C:\Users\Dev>java -version
java version "1.6.0"
Java(TM) SE Runtime Environment (build 1.6.0-b105)
Java HotSpot(TM) Client VM (build 1.6.0-b105, mixed mode, sharing)
In Ubuntu Java 8, I get the following Exception:
Exception in thread "main" mpi.MPIException: Usage: java MPI <myrank> <conf_file> <device_name> conf_file can be, ../conf/xdev.conf <Local>OR http://holly.dsg.port.ac.uk:15000/xdev.conf <Remote>
at mpi.MPI.Init(MPI.java:233)
at mpi.MPI.Init(MPI.java:233) at mpi.MPI.Init(MPI.java:233)
at Send.main(Send.java:7)
Java Result: 1
How do I resolve this issue and get MPI running on my system in Java?
This is an old question but I think I can summarize what happened here, having used this library myself.
The compilation error that you obtained, "Unsupported major.minor version 51.0" indicates that the version of java you are using to run your program is too old. Most likely some parts of your program were compiled with a newer version of Java. Probably the MPJ library you downloaded?
When you tried to run your program with Java 8, you actually solved this problem on your own! However, as you correctly identified in the second half of your question, you still have a problem with the arguments of your program. The MPJ-express main expects some specific arguments to know how many processes are being launched. In the absence of these arguments, you get the error Exception in thread "main" mpi.MPIException: Usage: java MPI <myrank> <conf_file> <device_name>
Basically, the MPJ-Express library comes with a number of small scripts that will arrange the MPI specific arguments for you. Depending on the mode (multicore / cluster) that you want to use, the script and the procedure will be different. All the details are explained in the guides available on this page: http://mpj-express.org/guides.html. If that's what you are using, you can also launch programs from within the Eclipse IDE.

Why does java.lang.VerifyError mean?

While I've tried to use the following code snippet with the Groovy in-operator explanation the VerifyError has occured. Have you guys any idea about?
The code and console output is below.
class Hello extends ArrayList {
boolean isCase(Object val) {
return val == 66
}
static void main(args) {
def myList = new Hello()
myList << 55
assert 66 in myList
assert !myList.contains(66)
}
}
The error log:
Exception in thread "main" java.lang.VerifyError: (class: Hello, method: super$1$stream signature: ()Ljava/util/stream/Stream;) Illegal use of nonvirtual function call
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:259)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:116)
The code origin from the topic How does the Groovy in operator work?.
Update:
Groovy Version: 1.8.6 JVM: 1.6.0_45 Vendor: Sun Microsystems Inc. OS: Linux
Check this out.
It's for Java, but generally problem is, that you are using wrong library versions. The class is there, but different version than expected.
http://craftingjava.blogspot.co.uk/2012/08/3-reasons-for-javalangverfiyerror.html
Probably you have messed up Groovy or Java SDK installations.

StringBuilder: ArrayIndexOutOfBoundsException

We're experiencing a strange issue with WebSphere 7/ IBM JDK 6, where one of the nodes has some initialization issue.
We have some code which calls InitialContext.lookup and on this node we're getting sometimes the following exception:
Caused by: java.lang.ArrayIndexOutOfBoundsException
at java.lang.String.getChars(String.java:666)
at java.lang.StringBuilder.append(StringBuilder.java:207)
at javax.naming.spi.NamingManager.getURLContext(NamingManager.java:646)
at javax.naming.InitialContext.getURLOrDefaultInitCtx(InitialContext.java:422)
at javax.naming.InitialContext.lookup(InitialContext.java:436)
[...]
We had a look at the source code of javax.naming.spi.NamingManager.getURLContext:
public static Context getURLContext(String schema, Hashtable<?, ?> envmt)
throws NamingException {
if (null == schema || 0 == schema.length() || null == envmt) {
return null;
}
// obtain pkg prefixes from hashtable
String pkgPrefixes[] = EnvironmentReader
.getFactoryNamesFromEnvironmentAndProviderResource(envmt, null,
Context.URL_PKG_PREFIXES);
for (String element : pkgPrefixes) {
// create factory instance
ObjectFactory factory;
String clsName = element + "." //$NON-NLS-1$
+ schema + "." //$NON-NLS-1$
+ schema + "URLContextFactory"; //$NON-NLS-1$
[...]
Line 646 is the enhanced for-loop, but the next statement is a String concatenation and is probably replaced with a StringBuilder by the compiler.
We did some quick unit tests on StringBuilder but couldn't provoke an ArrayIndexOutOfBoundsException.
How can an ArrayIndexOutOfBoundsException be thrown here and how can we avoid it?
Edit:
We are using the following java version:
java version "1.6.0"
Java(TM) SE Runtime Environment (build pxa6460sr9fp2ifix-20110913_02(SR9 FP2+IV03622+IZ99243))
IBM J9 VM (build 2.4, JRE 1.6.0 IBM J9 2.4 Linux amd64-64 jvmxa6460sr9-20110912_90359 (JIT enabled, AOT enabled)
J9VM - 20110912_090359
JIT - r9_20101028_17488ifx31
GC - 20101027_AA)
JCL - 20110727_04
This is a known bug of the JIT compiler of the IBM JVM. The workaround seems to be the exclusion of getChars from the JIT compilation:
-Xjit:exclude={ProgramClass.callStringGetChars*}
See IZ78413: JIT-COMPILED STRING.GETCHARS THROWS UNEXPECTED ARRAYINDEXOUTOFBO UNDSEXCEPTION for reference.
The code above seems to return null if you pass a null environment hashtable.
This makes me wonder if you are instantiating InitialContext with an argument of some sort.
If the code above is indeed the source, passing a null environment hashtable will short-circuit getURLContext() to return null prior to the string concatenation loop.
Can you try new InitialContext() or new InitialContext(null) if you do not need to specify JNDI environment vars (e.g. use default JNDI env)?

Categories

Resources