I am using Eclipse IDE 2019-12 and using jre1.8.0_231
I wanted to make a library for an adventure game that was able to read json files to convert them to objects. When I exported the library to a .jar file (not runable) an then imported it into my test project in order to make sure everything worked fine, I made the assets source folder and put in Lantern.json, fillied out what i needed and tried to use my library to convert the json file's values into an Item object and ran the method. However when I ran it I got this error...
Exception in thread "main" java.lang.NoClassDefFoundError: org/json/JSONObject
at com.ferisjumbo.adventure.JSONReader.JSONUtil.getJSONObjectFile(JSONUtil.java:28)
at com.ferisjumbo.adventure.JSONReader.JSONReader.getJSONItem(JSONReader.java:11)
at Main.main(Main.java:7)
Caused by: java.lang.ClassNotFoundException: org.json.JSONObject
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
... 3 more
I have tried researching the error, but to me it sounds like jibberish and doesn't make any sense.
Here are some snippits of whats going on...
//Main (located in src folder in project)
import com.ferisjumbo.adventure.JSONReader.Item;
import com.ferisjumbo.adventure.JSONReader.JSONReader;
public class Main {
public static void main(String[] args) {
Item Lantern = JSONReader.getJSONItem("Lantern.json");
System.out.println(Lantern.toString());
}
}
//JSONReader (located in library)
package com.ferisjumbo.adventure.JSONReader;
import java.util.ArrayList;
import java.util.List;
import org.json.JSONObject;
public class JSONReader {
public static Item getJSONItem(String path) {
JSONObject item = JSONUtil.getJSONObjectFile(path);
.....
//JSONUtil (located in library)
package com.ferisjumbo.adventure.JSONReader;
import java.io.InputStream;
import java.util.Scanner;
import org.json.JSONObject;
public class JSONUtil {
public static String getJSONString(String path) {
Scanner scanner;
InputStream IStream = FileHandler.inputStreamFromFile(path);
scanner = new Scanner(IStream);
String json = scanner.useDelimiter("\\z").next();
scanner.close();
return json;
}
public static JSONObject getJSONObjectFile(String path) {
return new JSONObject(getJSONString(path));
}
Here is the Project tree if you need it
If you need aditional information I can put up more. Thanks!
Related
I have a spring application with multiple dependent libraries that have the inner properties/xml that I want to read.
test-app.jar
dep1.jar
dep2.jar
dep3.jar
...
Each of the dep1/2/3 jars have the file called META-INF/config.properties which contains the files to further read within that dependent jars.
I tried the ResourceUtils.getURL("classpath:/META-INF/config.properties"), but it always reads from the first dependent file.
How can I read from each jars that contains the same name?
I found this solution after searching:
final Enumeration<URL> resEnum =
MyClass.class.getClassLoader()
.getResources("META-INF/config.properties");
final List<URL> resources =
Collections.list(resEnum);
//Copied from riptutorial.com
Refs:
https://riptutorial.com/java/example/19290/loading-same-name-resource-from-multiple-jars
https://stackoverflow.com/a/6730897
Updated solution:
package abc;
import java.io.IOException;
import java.net.URL;
import java.util.Enumeration;
public class MultipleClasspathEntries {
public static void main(String[] args) throws IOException {
final Enumeration<URL> resEnum =
MultipleClasspathEntries.class.getClassLoader()
.getResources("META-INF/MANIFEST.MF");
while (resEnum.hasMoreElements()) {
System.out.println(resEnum.nextElement());
}
}
}
//Copied from riptutorial.com
$JAVA_HOME/bin/javac abc/*.java
$JAVA_HOME/bin/java -cp /c/so-67847004/commons-lang-2.4.jar:/c/so-67847004/commons-collections-3.2.1.jar:. abc.MultipleClasspathEntries
Output:
jar:file:/C:/so-67847004/commons-lang-2.4.jar!/META-INF/MANIFEST.MF
jar:file:/C:/so-67847004/commons-collections-3.2.1.jar!/META-INF/MANIFEST.MF
This is the screenshot of my Eclipse project files.
I get the error below when I try to initiated a new Sound("Res/MouseClick.ogg") object in my class AudioPlayer at line 15.
package com.game;
import java.util.HashMap;
import java.util.Map;
import org.newdawn.slick.Music;
import org.newdawn.slick.Sound;
public class AudioPlayer {
public static Map<String, Sound> soundMap = new HashMap<String, Sound>();
public static Map<String, Music> musicMap = new HashMap<String, Music>();
public static void load() {
try {
soundMap.put("menu_sound", new Sound("Res/MouseClick.ogg")); // <- throws error
musicMap.put("music", new Music("Res/Background.ogg"));
} catch (Exception e) {
e.printStackTrace();
}
}
public static Music getMusic(String key) {
return musicMap.get(key);
}
public static Sound getSound(String key) {
return soundMap.get(key);
}
}
Exception in thread "main" java.lang.NoClassDefFoundError: sun/misc/Unsafe
at lwjgl/org.lwjgl.MemoryUtilSun$AccessorUnsafe.getUnsafeInstance(MemoryUtilSun.java:74)
at lwjgl/org.lwjgl.MemoryUtilSun$AccessorUnsafe.<init>(MemoryUtilSun.java:62)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:500)
at java.base/java.lang.reflect.ReflectAccess.newInstance(ReflectAccess.java:166)
at java.base/jdk.internal.reflect.ReflectionFactory.newInstance(ReflectionFactory.java:404)
at java.base/java.lang.Class.newInstance(Class.java:590)
at lwjgl/org.lwjgl.MemoryUtil.loadAccessor(MemoryUtil.java:324)
at lwjgl/org.lwjgl.MemoryUtil.<clinit>(MemoryUtil.java:66)
at lwjgl/org.lwjgl.openal.ALC10.alcOpenDevice(ALC10.java:202)
at lwjgl/org.lwjgl.openal.AL.init(AL.java:160)
at lwjgl/org.lwjgl.openal.AL.create(AL.java:138)
at lwjgl/org.lwjgl.openal.AL.create(AL.java:102)
at lwjgl/org.lwjgl.openal.AL.create(AL.java:201)
at slick/org.newdawn.slick.openal.SoundStore$1.run(SoundStore.java:295)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:310)
at slick/org.newdawn.slick.openal.SoundStore.init(SoundStore.java:292)
at slick/org.newdawn.slick.Sound.<init>(Sound.java:54)
at Wave/com.game.AudioPlayer.load(AudioPlayer.java:15)
at Wave/com.game.Game.<init>(Game.java:37)
at Wave/com.game.Game.main(Game.java:157)
Caused by: java.lang.ClassNotFoundException: sun.misc.Unsafe
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:583)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
... 23 more
From your posted IDE screenshot I can see that you are using
Java 12, and
the Java Module System (module-info.java)
Note that sun/misc/Unsafe is a (legacy) Java internal API which for that reason and by default is encapsulated (hidden) away when using the Java Module System.
In order for your application (and your used library) to access it, you need to explicitly include it in your module-info.java by adding requires jdk.unsupported;
Alternatively, you may also not use the Java Module System – in which case it should simply work. However, I recommend to continue using the module system.
I try to get classes that implements an interface in a given package, using reflections library.
I have the following code :
package TestClass;
import org.reflections.Reflections;
import org.reflections.scanners.SubTypesScanner;
import java.io.DataInputStream;
import java.io.InputStream;
import java.net.URL;
import java.util.*;
public class Checks {
public static void main(String[] args) {
Reflections reflections = new Reflections("TestReflection.src.testclass");
try{
Set<Class<? extends CheckingClass>> classes = reflections.getSubTypesOf(CheckingClass.class);
}catch(Exception e){
System.out.println(e.toString());
}
}
}
It gives me this error : org.reflections.ReflectionsException: Scanner SubTypesScanner was not configured
It surprises me because i got the code from an example of how to use reflections library, so it should work.
The library, i think, is well imported because other methods work.
I've tried a lot of things and can't make this code work.
Maybe i'm missing an important details. Any idea?
Thanks
EDIT : Here's the tree of my project, so you can see if my path is good :
EDIT 2 : I changed
Reflections reflections = new Reflections("TestReflection.src.testclass", new SubTypesScanner());
to
Reflections reflections = new Reflections("testclass", new SubTypesScanner());
and i have an other error :
Exception in thread "main" java.lang.NoClassDefFoundError: javassist/bytecode/ClassFile
at org.reflections.adapters.JavassistAdapter.getOrCreateClassObject(JavassistAdapter.java:107)
at org.reflections.adapters.JavassistAdapter.getOrCreateClassObject(JavassistAdapter.java:34)
at org.reflections.scanners.AbstractScanner.scan(AbstractScanner.java:28)
at org.reflections.Reflections.scan(Reflections.java:270)
at org.reflections.Reflections.scan(Reflections.java:216)
at org.reflections.Reflections.<init>(Reflections.java:137)
at org.reflections.Reflections.<init>(Reflections.java:182)
at org.reflections.Reflections.<init>(Reflections.java:155)
at testclass.Checks.main(Checks.java:12)
Caused by: java.lang.ClassNotFoundException: javassist.bytecode.ClassFile
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:602)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
... 9 more
Process finished with exit code 1
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.
I am new to reflection and to practice, I downloaded a random Java project from a website. I decided to find out which class has the main method so I wrote the following code:
package reflection;
import java.io.IOException;
import java.lang.reflect.*;
import java.nio.file.*;
public class FindMethods {
public static void main(String[] args) throws IOException{
if(args.length==0){
System.out.println("Exiting");
System.exit(1);
}else{
Path p = Paths.get(args[0]);
DirectoryStream<Path> allClassFiles = Files.newDirectoryStream(p, "*.class");
for(Path each : allClassFiles){
// System.out.println(each.getFileName());
try {
findMethods(each.getFileName().toString());
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
}
public static void findMethods(String file) throws ClassNotFoundException{
System.out.println(file);
Class c = Class.forName(file);
Method[] m = c.getDeclaredMethods();
for(Method each : m){
System.out.println(each.toString());
}
}
}
System.out.println(each.getFileName()); properly returns the .class files in the folder however, it is interspersed with stack trace of ClassNotFoundException
The classes are as follows:
Addwindow$1.class
Addwindow$2.class
Addwindow.class
Authorwindow.class
clsConnection.class
clsSettings$1.class
clsSettings.class
Deletewindow$1.class
Deletewindow$2.class
Deletewindow.class
Editwindow$1.class
Editwindow$2.class
Editwindow.class
Emprptwindow$PrintCommand.class
Emprptwindow.class
Helpwindow.class
LoginFrame$1.class
LoginFrame.class
MainMenu$1.class
MainMenu$2.class
MainMenu.class
Payrptwindow.class
printwindow$1.class
printwindow.class
Settingswindow$1.class
Settingswindow.class
What changes do I need to make to the code to get the methods from each class ?
Stack trace:
java.lang.ClassNotFoundException: Settingswindow
at java.net.URLClassLoader$1.run(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Unknown Source)
at reflection.FindMethods.findMethods(FindMethods.java:33)
at reflection.FindMethods.main(FindMethods.java:22)
Random project being talked about:
http://projectseminar.org/java-projects/payroll-accounting-system/98/
.class is part of the filename, but it isn't part of the class name. You need to strip it before passing it to Class.forName.
Another issue is that forName expects packages to be separated using periods, rather than than slashes or whatever directory separator your filesystem uses. If everything is in the default package, this shouldn't be an issue though.
If it's still not working, you should double check the classpath.
Class names that contain a $ are anonymous classes within the outer class (determined by the name to the left of the $). You can safely ignore those in your search for main. Just test for the presence of a $ in the class names in your main loop and skip the processing.
Without knowing more about what app you are looking at, I can't say why your code can't find some of the other classes (like clsConnection).
There is a problem in this approach - you load all project's classes. It is better to analize classes without loading them. There are tools for that. Here's what we can do with http://www.jboss.org/javassist
public static void findMethods(String file) throws Exception {
ClassPool cp = ClassPool.getDefault();
try (InputStream is = new FileInputStream(file)) {
CtClass cc = cp.makeClass(is);
for (CtMethod m : cc.getMethods()) {
System.out.println(m);
}
}
}