Using ProGuard to obfuscate code - java

I chose ProGuard and here's the options I configured it with:
Shrinking
Options:
Shrink
Keep:
Applications
Applets
Also keep:
Enumerations
Database drivers
Swing UI L&F
Obfuscation
Options:
Obfuscate (duh! :P)
Overload aggressively
Use unique class member names
Use mixed-casee class names
Flatten package hierarchy
Repackage classes
Keep names:
native method names
.class method names
Optimization
Options:
Optimize
Merge interfaces aggressively
Remove:
[All boxes checked]
Information
Preverifiaction and targeting:
Preverify
Consistency and correctness:
Note potential mistakes in the configuration
Warn about possibly errornous input
Skip non-public library class members
and when I take the jar and put it as:
I get this applet error upon launch:
java.lang.RuntimeException: java.lang.NoClassDefFoundError: b
at sun.plugin2.applet.Plugin2Manager.createApplet(Unknown Source)
at sun.plugin2.applet.Plugin2Manager$AppletExecutionRunnable.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.NoClassDefFoundError: b
at java.lang.Class.getDeclaredConstructors0(Native Method)
at java.lang.Class.privateGetDeclaredConstructors(Unknown Source)
at java.lang.Class.getConstructor0(Unknown Source)
at java.lang.Class.newInstance0(Unknown Source)
at java.lang.Class.newInstance(Unknown Source)
at sun.plugin2.applet.Plugin2Manager$12.run(Unknown Source)
at java.awt.event.InvocationEvent.dispatch(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
Caused by: java.lang.ClassNotFoundException: b
at sun.plugin2.applet.Applet2ClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
... 14 more
Caused by: java.io.IOException: open HTTP connection failed:http://mystikrpg.com/b.class
at sun.plugin2.applet.Applet2ClassLoader.getBytes(Unknown Source)
at sun.plugin2.applet.Applet2ClassLoader.access$000(Unknown Source)
at sun.plugin2.applet.Applet2ClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
... 17 more
Exception: java.lang.RuntimeException: java.lang.NoClassDefFoundError: b
Here is what is INSIDE the jar file BEFORE the obfuscation clientOffline.jar:
line_tile/
META-INF/
and here is what that jar file is AFTER the obfuscation to newOne.jar:
line_tile/
META-INF/
weapon/
me.gif
a.class
b.class
I hope this is good enough to help me solve this. What am I doing wrong?

I guess that b.class is generated from the GamePanel inner class. So there can be a problem with inner classes. Here at Stackoverflow Tom mentioned that he could not obfuscate inner classes correctly. The suggestion there also applies here: try to obfuscate with verbose=true (or with java -jar proguard.jar #myconfig.pro -verbose).
I would also suggest to use -keepnames option (see manual) for GamePanel and/or tileOffline since it will leave these classes unchanged by the obfuscation (at least for finding the root cause of the problem).
A side note is try to use CamelCase class names when programming in Java.

Related

Weird ClassNotFoundException

This line of code is working fine when I debug in eclipse.
this.primaryStage.addEventHandler(KeyEvent.KEY_PRESSED, new EventHandler<KeyEvent>() {
#Override
public void handle(KeyEvent keyEvent) {
InputManager.Instance().addEvent(keyEvent);
}
});
When I export it into .jar ussing my own code (not script), it throws a rather long exception.
Exception in Application start method
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(Unk
nown Source)
at com.sun.javafx.application.LauncherImpl.launchApplication(Unknown Sou
rce)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at sun.launcher.LauncherHelper$FXHelper.main(Unknown Source)
Caused by: java.lang.RuntimeException: Exception in Application start method
at com.sun.javafx.application.LauncherImpl.launchApplication1(Unknown So
urce)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$156(
Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.NoClassDefFoundError: test/Game$1
at test.Game.start(Game.java:62)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$163
(Unknown Source)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$176(Unknown
Source)
at com.sun.javafx.application.PlatformImpl.lambda$null$174(Unknown Sourc
e)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$175(Unknown S
ource)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(Unknown Source)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$149(Unknown Source)
... 1 more
Caused by: java.lang.ClassNotFoundException: test.Game$1
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)
... 10 more
Exception running application test.Game
Yet when I export it the same way, but with the handler commented out, it works fine.
I have tried root.addEventHandler, root/primaryStage.setOnKeyPressed, declaring the handler separately, ..
Can you spot the ex reason?
export it into .jar using my own code
Your "own code" is not doing it right, because it is not including the test/Game$1.class file in the .jar file.
Your class is called Game in the test package. When the class uses anonymous classes, those classes must be given a name in order for the .class file to be created (also need the name internally). The name of such files can be anything, but the current scheme is to name it after the defining class, adding a sequence number after a $ sign, so the first anonymous class is called Game$1.class, the second would be called Game$2.class, and so on.
That is why, when you compile Game.java, you end up with 2 files: Game.class and Game$1.class. Both of those files must be added to the .jar file.
You shouldn't rely on this naming convention, if at all possible, because it could change in the future, and other compilers might do it differently.
ClassNotFound exception is usually due to your CLASSPATH environment variable not getting set correctly.
The JVM must have transversed everywhere from the CLASSPATH directory but was not able to find your compiled *.class and java jar files. One way to fix this would be to use the -cp option from the java binary. Or you can set your CLASSPATH environment to the directory where your java files are sitting.
Things run fine in Ecplipse because the classPath set to the workspace and the IDE has got this handled for you.
Read here for more information about CLASSPATH.
https://docs.oracle.com/javase/tutorial/essential/environment/paths.html

How to get the full StackTrace when using SuperDevMode in GWT 2.7?

I use GWT 2.7 with super dev mode. When it comes to an exception the stack trace looks like the following:
SEVERE: UncaughtExceptioncom.github.nmorel.gwtjackson.client.exception.JsonDeserializationException: Unknown property 'uploadImageId'
at Unknown.AHc_g$(Unknown Source)
at Unknown.vHc_g$(Unknown Source)
at Unknown.OHc_g$(Unknown Source)
at Unknown.VHc_g$(Unknown Source)
at Unknown.aIc_g$(Unknown Source)
at Unknown.gIc_g$(Unknown Source)
at Unknown.rDc_g$(Unknown Source)
at Unknown.qDc_g$(Unknown Source)
at Unknown.vNb_g$(Unknown Source)
at Unknown.nNb_g$(Unknown Source)
at Unknown.oNb_g$(Unknown Source)
at Unknown.pNb_g$(Unknown Source)
at Unknown.gNb_g$(Unknown Source)
at Unknown.fNb_g$(Unknown Source)
at Unknown.$Cc_g$(Unknown Source)
at Unknown.ZCc_g$(Unknown Source)
at Unknown.zOm_g$(Unknown Source)
at Unknown.anonymous(Unknown Source)
at Unknown.ZDe_g$(Unknown Source)
at Unknown.aEe_g$(Unknown Source)
at Unknown.anonymous(Unknown Source)
at Unknown.anonymous(Unknown Source)
at Unknown.anonymous(Unknown Source)
at Unknown.anonymous(Unknown Source)
at Unknown.anonymous(Unknown Source)
at Unknown.anonymous(Unknown Source)
I have a GWT project running in a GWT-PhoneGap environment on my iPhone and I use the Safari Console for Debugging.
How can I get the full stack track deobfuscated with SuperDevMode?
Edit: I also use the following flag:
-XmethodNameDisplayMode Full
It does not work.
As of GWT 2.7.0, this isn't possible. You might want to follow this GWT bug.
The -XmethodNameDisplayMode Full only applies to the browser's dev tools. So if you set this parameter and set a breakpoint in the source code, the method names of the call stack will be displayed correctly in dev tools. This doesn't affect the call stack produced by log output (which is what you posted in your question).
Try setting the compiler option style to PRETTY or DETAILED
-style Script output style: DETAILED, OBFUSCATED or PRETTY (defaults to OBFUSCATED)
see GWT compiler options

Java get resource InvalidJarIndexException

I have a class names test.java and another file "log4j.properties" in the same folder but following call
getClass().getResource("log4j.properties")
fails with
ms
Trace:
sun.misc.InvalidJarIndexException: Invalid index
at sun.misc.URLClassPath$JarLoader.getResource(Unknown Source)
at sun.misc.URLClassPath$JarLoader.getResource(Unknown Source)
at sun.misc.URLClassPath$JarLoader.findResource(Unknown Source)
at sun.misc.URLClassPath.findResource(Unknown Source)
at java.net.URLClassLoader$2.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findResource(Unknown Source)
at java.lang.ClassLoader.getResource(Unknown Source)
at java.lang.ClassLoader.getResource(Unknown Source)
at java.lang.Class.getResource(Unknown Source)
But getClass().getClassLoader().getResource("log4j.properties") works. What can be the reason?
The InvalidJarIndexException is normally caused by a corrupt INDEX.LIST file in the JAR. So check the JAR for any problems. See http://littletechsecrets.wordpress.com/2008/12/01/why-does-invalidjarindexexception-occur/
The different results you describe are probably related to Class.getResource() resolving a path relative to the classes package, and ClassLoader.getResource() resolving a path relative to the root. So getClass().getResource("/log4j.properties") might fix your problem.

Why cleaning in Eclipse can cause error messages?

I cleaned my project in Eclipse and because of that, I think, I started to get the following error message:
at check.GameWindow$12.run(MyWindow.java:1253)
at java.awt.event.InvocationEvent.dispatch(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
So, I would like to ask why cleaning can cause error messages? I mean, the code before and after the cleaning is the same. Why it works differently before and after the cleaning.
In my opinion, something has changed in your code that you are not aware of. When you clean your project, the only thing Eclipse does is to delete .class files in your build/ directory and recompile all sources.
If you don't have compilation errors, there should be something wrong in an an anonymous inner class in check.GameWindow.
Please check.

Access restriction on JARs (what is the proper way to get VecMath?)

I need Vecmath, so I went to Oracle to get the latest version of Java 3D. I didn't see a place to download a JAR, but it had an installer. I downloaded and ran it. I assume that the installer added the JAR as a JDK extension
I restarted Eclipse, and it sees that VecMath is present. However, it still complains:
Access restriction: The type Vector3f
is not accessible due to restriction
on required library C:\Program
Files\Java\jre6\lib\ext\vecmath.jar
Bummer. I am able to change it from a compiler error to a warning, but it crashes as soon as I try to run it. Although, I'm using this in conjunction with OpenGL, and the crash could have nothing to do with vecmath. I'm not sure. Here is the exception:
Exception in thread "Timer-0" javax.media.opengl.GLException: java.lang.RuntimeException: javax.imageio.IIOException: Can't read input file!
at com.jogamp.opengl.impl.awt.AWTThreadingPlugin.invokeOnOpenGLThread(AWTThreadingPlugin.java:101)
at com.jogamp.opengl.impl.ThreadingImpl.invokeOnOpenGLThread(ThreadingImpl.java:192)
at javax.media.opengl.Threading.invokeOnOpenGLThread(Threading.java:164)
at javax.media.opengl.awt.GLCanvas.maybeDoSingleThreadedWorkaround(GLCanvas.java:591)
at javax.media.opengl.awt.GLCanvas.display(GLCanvas.java:301)
at com.jogamp.opengl.util.AnimatorImpl.display(AnimatorImpl.java:50)
at com.jogamp.opengl.util.Animator.display(Animator.java:154)
at com.jogamp.opengl.util.FPSAnimator$1.run(FPSAnimator.java:95)
at java.util.TimerThread.mainLoop(Unknown Source)
at java.util.TimerThread.run(Unknown Source)
Caused by: java.lang.RuntimeException: javax.imageio.IIOException: Can't read input file!
at cs4620.nth23.assignment1.GraphicsApp.loadTextures(GraphicsApp.java:98)
at cs4620.nth23.assignment1.GraphicsApp.init(GraphicsApp.java:65)
at com.jogamp.opengl.impl.GLDrawableHelper.init(GLDrawableHelper.java:111)
at com.jogamp.opengl.impl.GLDrawableHelper.init(GLDrawableHelper.java:124)
at javax.media.opengl.awt.GLCanvas$InitAction.run(GLCanvas.java:643)
at com.jogamp.opengl.impl.GLDrawableHelper.invokeGL(GLDrawableHelper.java:273)
at javax.media.opengl.awt.GLCanvas$DisplayOnEventDispatchThreadAction.run(GLCanvas.java:674)
at java.awt.event.InvocationEvent.dispatch(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
Caused by: javax.imageio.IIOException: Can't read input file!
at javax.imageio.ImageIO.read(Unknown Source)
at cs4620.nth23.assignment1.GraphicsApp.loadTextures(GraphicsApp.java:95)
... 14 more
I'm using:
x84 Windows 7
Eclipse Helios
JavaSE-1.6
JDK 1.6
What am I doing wrong here?
The exception was caused by being unable to find a file referenced in the code - it has nothing to do with VecMath.
The app runs fine, despite the access restrictions. I don't know if it'll come back to bite me later or what.

Categories