I would like to call the following Scala code in Java:
Scala code
package calculate
import java.io._
class CalculationScala
object CalculationScala {
def main(args: Array[String]) {
def operate(a: Double, b: Double, op: (Double, Double) => Double): Double = (op(a, b))
println(operate(5, 15, _-_))
}
}
Java code
package calculate;
public class Calculation {
public static void main(String[] args) {
CalculationScala calculationScala = new CalculationScala();
calculationScala.main(args);
}
}
but the following error occurs.
Error
Exception in thread "main" java.lang.NoClassDefFoundError: scala/Function2
at calculate.CalculationScala.main(CalculationScala.scala)
at calculate.Calculation.main(Calculation.java:79)
Caused by: java.lang.ClassNotFoundException: scala.Function2
at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
... 2 more
How to solve this issue?
It looks like you are missing scala-library.jar on your runtime classpath.
Related
The compiler for a JVM-based programming language currently that I am working on uses this code to run a specified main method after compilation:
URL url = DyvilCompiler.config.outputDir.toURI().toURL();
Class c = Class.forName(mainType, false, new URLClassLoader(new URL[] { url }, ClassLoader.getSystemClassLoader()));
Method m = c.getMethod("main", String[].class);
m.invoke(null, new Object[] { args });
However, when compiling this code:
package dyvil.test
// some uninteresting import stuff
public class Main
{
#ArrayConvertible
case class IntVector([int] ints = [ 1, 2 ])
public static void main([String] args)
{
println(IntVector())
println([ 1, 2, 3 ] as IntVector)
}
}
The ClassLoader fails with the inner class (that is actually a nested static class):
java.lang.ClassFormatError: Illegal class name "Ldyvil/test/Main$IntVector;" in class file dyvil/test/Main$IntVector
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:760)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:455)
at java.net.URLClassLoader.access$100(URLClassLoader.java:73)
at java.net.URLClassLoader$1.run(URLClassLoader.java:367)
at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:360)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at dyvil.test.Main.main(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at dyvil.tools.compiler.util.TestThread.run(TestThread.java:32)
Note that the class files generated for Main dyvil/test/Main and IntVector dyvil/test/Main$IntVector do define the inner class relation:
Inner classes:
[inner class info: #2 dyvil/test/Main$IntVector, outer class info: #7 dyvil/test/Main
inner name: #9 IntVector, accessflags: 8 static]
Enclosing Method: #7 #0 dyvil/test/Main
What is the problem with the Ldyvil/test/Main$IntVector; signature?
Also, when adding the output directory to the classpath and changing the code to
Class c = Class.forName(mainType)
everything works well without any errors.
EDIT: Not only does this cause problems with the JVM, but when using a class like this in Eclipse by importing it, Code Completions stop working completely.
I have a maven project in the following structure.
TestRun
|
|--src/main/java/com/main/CallAddNumbers.java (Package - Com.main)
|
|--src/test/java/com/test/RunTest.java (package com.test)
and here is the sample program
package com.main;
public class CallAddNumbers {
public static void main(String[] args) {
com.test.AddNumbers.addNumbers(5, 4);
}
}
package com.test;
public class AddNumbers {
public static void addNumbers (int a, int b){
System.out.println(a+b);
}
}
When I am calling addNumbers method from main, I am ending up with the following error. May be something simple, but can't figure it out.
Exception in thread "main" java.lang.NoClassDefFoundError: com/test/RunTest
at com.main.CallAddNumbers.main(CallAddNumbers.java:6)
Caused by: java.lang.ClassNotFoundException: com.test.RunTest
at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
... 1 more
you said it might be something simple, just wanted to check that this is your actual file structure before looking any further!
|
|--src/main/java/com/main/CallAddNumbers.java (Package - com.main)
|
|--src/test/java/com/test/addNumbers.java (package com.test)
Add this import statement to the CallAddNumbers class
import test.java.com.test.AddNumbers;
It will work fine. Btw better dont write production codes in test package
I'm writing a program for homework and running into an issue I can't seem to resolve. The problem involves simulating the probabilities of a randomwalk ending on any given node (just background, not really relevant to the problem). I've written my own class that uses a hash map to hold node objects (UndirectedGraph and NodeEntry respectively). I've also written a test harness.
Originally all these were in one file but I decided to move the UndirectedGraph and NodeEntry to a separate package...cause that seems like the right thing to do. I've gotten everything fixed up so that testHarness will compile but at runtime I get the following:
Exception in thread "main" java.lang.NoClassDefFoundError: GraphWalker/NodeEntry
at java.lang.Class.getDeclaredMethods0(Native Method)
at java.lang.Class.privateGetDeclaredMethods(Class.java:2531)
at java.lang.Class.getMethod0(Class.java:2774)
at java.lang.Class.getMethod(Class.java:1663)
at sun.launcher.LauncherHelper.getMainMethod(LauncherHelper.java:494)
at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:486)
Caused by: java.lang.ClassNotFoundException: GraphWalker.NodeEntry
at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
... 6 more
from looking around I find a few answers for this, primarily that the classes aren't on the classpath. Thing is I have all these files in the same folder, and my understanding is the current folder is always on the classpath.
here's abbreviated copies of the code:
testHarness:
import java.util.*;
import GraphWalker.*;
public class testHarness {
public static void main (String args[]) {
new testHarness();
}
public testHarness() {
GraphWalker.UndirectedGraph graph = new GraphWalker.UndirectedGraph(3);
// System.out.println(graph.containsNode(1));
graph.addNode(1);
graph.addNode(2);
graph.addNode(3);
UndirectedGraph:
package GraphWalker;
import java.util.*;
public class UndirectedGraph {
/*
* Based in part on UndirectedGraph.java by Keith Schwarz (htiek#cs.stanford.edu)
*/
public HashMap graphMap;
public UndirectedGraph(int numNodes) {
this.graphMap = new HashMap(numNodes);
}
public void addNode (Integer nodeNum) {
graphMap.put(nodeNum, new NodeEntry(1.0f,0.0f));
}
NodeEntry:
package GraphWalker;
import java.util.*;
public class NodeEntry {
// four inherent values
// credit is the current credit of the node
// nextCredit holds the credit for the next step
// adjList holds a list of adjacent node IDs
// degree holds the number of neighbors
public Float credit;
public Float nextCredit;
public ArrayList adjList;
public Integer degree;
public NodeEntry(Float credit, Float nextCredit) {
this.credit = credit;
this.nextCredit = nextCredit;
this.adjList = new ArrayList();
this.degree = 0;
}
public void addEdge(Integer neighbor) {
this.adjList.add(neighbor);
this.degree += 1;
}
each class has quite a bit more code but I don't think it's relevant to the issue. I'm working on Ubuntu 12.04 and trying to compile and run from both command line and using Geany (simple IDE) same behavior either way.
Any help?
Alrighty,
The issue was that the package files needed to be in a separate folder (named for the package, in my case GraphWalker). I'm not entirely clear on why it compiled fine but at runtime when it went to look for the package it seems to have expected/required them to be in their own folder.
I wouldn't consider that a class path issue, per se, since the files being looked for were in a folder that was on the classpath, just not the folder they needed to be in.
Why does the following code cause ClassNotFoundException?
public class App02 {
public static class A {
}
public static void main(String[] args) throws ClassNotFoundException {
try {
System.out.println("A.class.getCanonicalName() = " + A.class.getCanonicalName());
Class c = Class.forName("tests.App02.A"); //error on this line
System.out.println(c.getName());
}
catch(Exception e) {
e.printStackTrace();
}
}
}
Output:
A.class.getCanonicalName() = tests.App02.A
java.lang.ClassNotFoundException: tests.App02.A
at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:190)
at tests.App02.main(App02.java:15)
Try Class c = Class.forName("tests.App02$A"). It's not a top-level class, so use $ to locate it.
You need to use $ to access the nested class:
Class c = Class.forName("tests.App02$A");
When you compile your class, you will notice that the nested class is named as: App02$A.class, under package tests. It would make more sense then.
Because you are using a canonical name, but you should use name (A.class.getName()).
In your case you should use Class c = Class.forName("tests.App02$A");
There is a helpful util in commons-lang which support these classes:
org.apache.commons.lang3.ClassUtils.get("tests.App02.A")
Suppose I have the following interface deceleration :
public interface classListener<classEvent> {
void classMethod1(classEvent x);
void classMethod2(classEvent y);
void classMethod3(classEvent z);
}
and suppose I want to add this interface to whatever.something package.
What should i do ?
Put a package statement at the top of the file:
package your.package.name;
public interface classListener<classEvent> {
void classMethod1(classEvent x);
void classMethod2(classEvent y);
void classMethod3(classEvent z);
}
suppose I want to add this interface to java.something package
You cannot add to the java. packages. That's just for the JDK (currently controlled by Oracle since they acquired Sun). It'll compile, but when you try to use it you'll get a SecurityException:
Exception in thread "main" java.lang.SecurityException: Prohibited package name: java.util
at java.lang.ClassLoader.preDefineClass(ClassLoader.java:479)
at java.lang.ClassLoader.defineClassCond(ClassLoader.java:625)
at java.lang.ClassLoader.defineClass(ClassLoader.java:615)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:283)
at java.net.URLClassLoader.access$000(URLClassLoader.java:58)
at java.net.URLClassLoader$1.run(URLClassLoader.java:197)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClassCond(ClassLoader.java:631)
at java.lang.ClassLoader.defineClass(ClassLoader.java:615)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:283)
at java.net.URLClassLoader.access$000(URLClassLoader.java:58)
at java.net.URLClassLoader$1.run(URLClassLoader.java:197)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
Could not find the main class: UsePackage. Program will exit.
My code that gave me that error:
In ~/temp/java/util/AddPackage.java:
package java.util;
public interface AddPackage {
void doSomething();
}
In ~/temp/UsePackage.java:
import java.util.AddPackage;
class UsePackage implements AddPackage {
public static final void main(String[] args) {
new UsePackage().doSomething();
}
public void doSomething() {
System.out.println("Hi");
}
}
Commands:
~/temp$ javac java/util/AddPackage.java
~/temp$ javac UsePackage.java
~/temp$ java UsePackage
...whereupon the error occured. Using Oracle's (Sun's) JVM.
The package decl creates a namespace for the content below. Just add a package decl as first line in your interface file.
package org.whatever.foo
public interface ....