I wan't to try to load a class and if this class can't be loaded to continue my program.
protected void checkClass(){
classChecked = false;
try {
ClassLoader cl = Thread.currentThread().getContextClassLoader();
Class<?> compiledClass = cl.loadClass(sTestclass); // << EXCEPTIOn lINE
cRun = compiledClass;
classChecked = true;
} catch (Exception e) {
e.printStackTrace();
System.err.println("- Testclass not found!");
System.err.println("- Make sure you typed the package name\n and the Class name correctly!");
}
}
But instead the whole progam exits with this:
Exception in thread "main" java.lang.NoClassDefFoundError: data/testcases/comman
do/ctest (wrong name: data/testcases/commando/CTest)
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:14
1)
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 cmd.TwCmd.checkClass(TwCmd.java:214)
at cmd.TwCmd.askForTestcase(TwCmd.java:107)
at cmd.TwCmd.anotherTestcase(TwCmd.java:146)
at cmd.TwCmd.executeInteractiveTw(TwCmd.java:85)
at cmd.TwCmd.runThrough(TwCmd.java:60)
at cmd.TwCmd.main(TwCmd.java:260)
I already surrounded it with Try/Catch but still the whole program exits on this error?
NoClassDefFoundError is not an Exception, it derives from Error.
Try catching Throwable if you want to catch them all.
You see an Error, not an Exception. Catch the NoClassDefFoundError and you should be able handle it in a catch block and continue.
(java.lang.NoClassDefFoundError is not a subclass of java.lang.Exception)
Related
I am trying to instrument one of my class and it works fine if I added
System.out.println(somevariable)
but it throws
Caused by: compile error: no such class: logger
when adding
logger.debug(somevariable);
Here is the code with logger:
public class SleepingClassTransformer implements ClassFileTransformer {
public Logger logger = Logger.getLogger(SleepingClassTransformer.class);
public byte[] transform(ClassLoader loader, String className, Class classBeingRedefined,
ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
byte[] byteCode = classfileBuffer;
if (className.equals("com/acc/instrument/Sleeping")) {
logger.debug("in class transformer");
try {
StringBuilder endBlock = new StringBuilder();
ClassPool cp = ClassPool.getDefault();
CtClass cc = cp.get("com.acc.instrument.Sleeping");
CtMethod m = cc.getDeclaredMethod("randomSleep");
m.addLocalVariable("elapsedTime", CtClass.longType);
m.insertBefore("elapsedTime = System.currentTimeMillis();");
endBlock.append("{elapsedTime = System.currentTimeMillis() - elapsedTime;"
+ "System.out.println(\"Method Executed in ms: \" + elapsedTime);}");
endBlock.append("{logger.debug(elapsedTime);}");
m.insertAfter(endBlock.toString());
byteCode = cc.toBytecode();
cc.detach();
} catch (Exception ex) {
ex.printStackTrace();
}
}
return byteCode;
}
}
Complete exception:
DEBUG | 2018-10-16 16:10:03 | [main] instrument.SleepingClassTransformer (SleepingClassTransformer.java:23) - in class transformer
javassist.CannotCompileException: [source error] no such class: logger
at javassist.CtBehavior.insertAfter(CtBehavior.java:819)
at javassist.CtBehavior.insertAfter(CtBehavior.java:743)
at com.accenture.instrument.SleepingClassTransformer.transform(SleepingClassTransformer.java:35)
at sun.instrument.TransformerManager.transform(TransformerManager.java:169)
at sun.instrument.InstrumentationImpl.transform(InstrumentationImpl.java:365)
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)
at com.accenture.instrument.Main.main(Main.java:11)
Caused by: compile error: no such class: logger
at javassist.compiler.MemberResolver.searchImports(MemberResolver.java:436)
at javassist.compiler.MemberResolver.lookupClass(MemberResolver.java:412)
at javassist.compiler.MemberResolver.lookupClassByJvmName(MemberResolver.java:330)
at javassist.compiler.TypeChecker.atCallExpr(TypeChecker.java:671)
at javassist.compiler.JvstTypeChecker.atCallExpr(JvstTypeChecker.java:156)
at javassist.compiler.ast.CallExpr.accept(CallExpr.java:45)
at javassist.compiler.CodeGen.doTypeCheck(CodeGen.java:241)
at javassist.compiler.CodeGen.atStmnt(CodeGen.java:329)
at javassist.compiler.ast.Stmnt.accept(Stmnt.java:49)
at javassist.compiler.CodeGen.atStmnt(CodeGen.java:350)
at javassist.compiler.ast.Stmnt.accept(Stmnt.java:49)
at javassist.compiler.Javac.compileStmnt(Javac.java:568)
at javassist.CtBehavior.insertAfterAdvice(CtBehavior.java:833)
at javassist.CtBehavior.insertAfter(CtBehavior.java:785)
... 17 more
Whats wrong with the logger statement?
Maybe the class you are instrumenting does not have a logger object.
try this instead
endBlock.append("{new java.util.logging.Logger.getGlobal().log(java.util.logging.Level.debug,elapsedTime);}")
I have a base and sub class. The requirement is to invoke sub class' method using reflection. Both programs are below.
base.java
import java.io.File;
import java.net.URL;
import java.net.URLClassLoader;
public class base {
public static void main(String[] args) {
URLClassLoader loader = null;
Class<?> cls;
try {
File file = new File("sub.jar" );
URL[] urls = { file.toURI().toURL() };
loader = new URLClassLoader(urls);
cls = loader.loadClass("sub");
base obj = (base) cls.newInstance();
obj.print();
}
catch(Exception e) {
System.out.println("Exception occured:" + e);
e.printStackTrace();
}
}
public void print() {
System.out.println("In Base class");
}
}
sub.java
public class sub extends base {
public void print() {
System.out.println("In subclass");
}
}
compile both in to jars.
javac base.java;
jar cvf base.jar base.class
javac sub.java;
jar cvf sub.jar sub.class
If I invoke the base.jar as "java -cp", it works fine
java -cp base.jar base
output: "In subclass"
But if I invoke it with "hadoop jar" command, I get
hadoop jar base.jar base
Exception in thread "main" java.lang.NoClassDefFoundError: base
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:467)
at java.net.URLClassLoader.access$100(URLClassLoader.java:73)
at java.net.URLClassLoader$1.run(URLClassLoader.java:368)
at java.net.URLClassLoader$1.run(URLClassLoader.java:362)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:361)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at base.main(base.java:15)
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:498)
at org.apache.hadoop.util.RunJar.run(RunJar.java:221)
at org.apache.hadoop.util.RunJar.main(RunJar.java:136)
Caused by: java.lang.ClassNotFoundException: base
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
Any help is greatly appreciated.
I believe your issue is on line 15 where you try to case the loader as your base class. I believe the compiler doesn't know how to handle that. Additionally, I'm not sure why you're trying to run this program with Hadoop since it does not have any of the hadoop implementations or classes
The problem is solved by placing base.jar in hadoop classpath. Run "hadoop classpath" command which lists all classpath dirs. Place the jar in one of these directories.
I want to modifly the class in app which is running. So I use java agent to do this. My java code like this:
/**
*
* #param args
* #param inst
*/
public static void agentmain(String args, Instrumentation inst) {
try {
inst.addTransformer(new GameClassFileTransformer(), true);
parseFiles();
List<Class<?>> retransformClasses = new ArrayList<>();
for (JarClassInfo jarClassInfo : GameAgentMain.bugFiles.values()) {
retransformClasses.add(Class.forName(jarClassInfo.getClassName()));
}
Class<?>[] classes = new Class[retransformClasses.size()];
retransformClasses.toArray(classes);
inst.retransformClasses(classes);
} catch (Exception e) {
LogUtil.error(e);
}
}
The JarClassInfo is a class about the class I want to reload.There hava two fields in JarClassInfo ,first is className,second is bytecode(java type is byte[]),The classname is which class want to reload.But the class is loaded by
custom classLoad
.When the app run at :
retransformClasses.add(Class.forName(jarClassInfo.getClassName()));
That is a exception be thrown:
Exception in thread "Attach Listener" java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at sun.instrument.InstrumentationImpl.loadClassAndStartAgent(InstrumentationImpl.java:382)
at sun.instrument.InstrumentationImpl.loadClassAndCallAgentmain(InstrumentationImpl.java:407)
Caused by: java.lang.ClassFormatError: Incompatible magic value 2329931675 in class file com/jingqi/game/module/chat/command/SendChatMsgCMD
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:800)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:449)
at java.net.URLClassLoader.access$1(URLClassLoader.java:409)
at java.net.URLClassLoader$2.run(URLClassLoader.java:361)
at java.net.URLClassLoader$2.run(URLClassLoader.java:1)
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)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:190)
at com.jingqi.game.agent.GameAgentMain.agentmain(GameAgentMain.java:60)
... 6 more
My custom classloader(EncrypClassLoader) is used to decode my class.
So the methd call stack indicate sun.misc.Launcher$AppClassLoader to load SendChatMsgCMD .The SendChatMsgCMD is not a normal class file(because I encrypt this class file).
So ,what method can be solved 。
Your custom classloader isn't doing what it's supposed to do: decrypt classes.
That's why you're getting the java.lang.ClassFormatError about the invalid magic value.
EDIT: you need to also realise that Class.forName() will load the class referred by the classname argument using the current class's classloader.
I would like to save data from each partition to MySQL Database. For doing that I created Class which implements VoidFunction<> :
public class DatabaseSaveFunction implements VoidFunction<Iterator<String>> {
/**
*
*/
private static final long serialVersionUID = -7039277486852158360L;
public void call(Iterator<String> it) {
Connection connect = null;
PreparedStatement preparedStatement = null;
try {
Class.forName("com.mysql.jdbc.Driver");
connect = DriverManager.getConnection("jdbc:mysql://"
+ "xxx.us-west-2.rds.amazonaws.com" + "/"
+ "xxx", "xxx", "xxx");
preparedStatement = connect
.prepareStatement("insert into testdatabase.test values (default, ?)");
while (it.hasNext()) {
String outputElement = it.next();
preparedStatement.setString(1, "" + outputElement.length());
preparedStatement.executeUpdate();
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
connect.close();
preparedStatement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
And in my main method class I'm calling:
output.foreachPartition(new DatabaseSaveFunction());
I'm getting following error:
15/05/06 15:34:00 WARN scheduler.TaskSetManager: Lost task 0.0 in stage 1.0 (TID 4, ip-172-31-36-44.us-west-2.compute.internal): java.lang.ClassNotFoundException: DatabaseSaveFunction
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 java.lang.ClassLoader.loadClass(ClassLoader.java:358)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:274)
Worker log:
15/05/06 15:34:00 ERROR executor.Executor: Exception in task 1.0 in stage 1.0 (TID 5)
java.lang.ClassNotFoundException: DatabaseSaveFunction
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 java.lang.ClassLoader.loadClass(ClassLoader.java:358)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:274)
Can anybody tell me what I'm doing wrong ? I would be very grateful for that.
Export the external class to jar and add that like sc.addJar("/path/x.jar") where sc is JavaSparkContext in your main. Then you wont get this error. The error is because you spark program is not able to find the class. Moreover in spark 1.3 and greater you can simple use a map options of jdbc and then use load("jdbc", options) to create a data frame and load data from any RDBMS. its really handy. I am not sure if this method works for connecting any RDBMS into spark. Please tell me if you have any other question.
I am trying to read a N-Triples (.nt) DBpedia file with NxParser, but I had the following error, and I don't know what to do.
Exception in thread "main" java.lang.NoClassDefFoundError: org/semanticweb/yars/nx/parser/NxParser$1
at org.semanticweb.yars.nx.parser.NxParser.stringItFromBufferedReader(Unknown Source)
at org.semanticweb.yars.nx.parser.NxParser.<init>(Unknown Source)
at org.semanticweb.yars.nx.parser.NxParser.<init>(Unknown Source)
at SentencesMatching_prova.main(SentencesMatching_prova.java:29)
Caused by: java.lang.ClassNotFoundException: org.semanticweb.yars.nx.parser.NxParser$1
at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
... 4 more
The source code of the script is:
import java.io.*;
import org.semanticweb.yars.nx.parser.*;
public class SentencesMatching_prova {
public static void main(String[] args) {
try {
String relationFileName = "../zzz-trash/revisions_en.nt";
FileInputStream is = new FileInputStream(relationFileName);
NxParser nxp = new NxParser(is);
while (nxp.hasNext()) {
// do stuff
}
} catch (Exception ex) {
ex.printStackTrace(System.out);
}
}
}