Proguard causes org.hibernate.AnnotationException - proguard

this is my first time using a obfuscator (ProGuard) for obfuscation of my code. I have two J2EE projects EJB and webProject. Currently I am obfuscating only my EJB.jar project and it is also hosting webservices but before i reach that part i am getting an error
I successfully generated the output jar using ProGuard GUI app, but when I deploy that jar on my server (wildfly) it gave me this exception:
org.hibernate.AnnotationException: No identifier specified for entity: com.metadatatool.b.a
This b.a is the obfuscated code original names were different.
This exception is basically being invoked on a entity i.e. a View and it has a #Id identifier it works normal if I don't obfuscate my code but when I do it gives me this error.
I am using the -keep attributes feature of ProGuard but still i am getting this error

EJB uses reflection and requires that some classes keep their original names, methods and annotations when they go through obfuscation. To fix your problem, you need add a couple of rules such as:
-keepattributes RuntimeVisibleAnnotations
-keep #javax.persistence.* class * {
*;
}
to make ProGuard not strip annotations and not touch classes annotated with #Id.

Related

Why dagger requires to provide entities where I don't want to provide them?

I have two modules - core and auth. In auth module I am trying to integrate Google Sign In to Firebase. All dependencies resolving correctly, but not a GoogleSignInClient. I don't want use dagger for this entity to provide this client somewhere. I want to use it only in this class. But dagger shows me an error :
class file for com.google.android.gms.auth.api.signin.GoogleSignInClient not found
Consult the following stack trace for details.
com.sun.tools.javac.code.Symbol$CompletionFailure: class file for com.google.android.gms.auth.api.signin.GoogleSignInClient not found
e: D:\Projects\<project path>\build\tmp\kapt3\stubs\internalProductionDebug\<class path>\di\components\AppComponent.java: error:
[ComponentProcessor:MiscError] dagger.internal.codegen.ComponentProcessor was unable to process this interface because not all of its dependencies could be resolved. Check for compilation errors or a circular dependency with generated code.
Unfortunately it wasn't dagger problem. It happens with using several Android modules when you use api and implementation in gradle incorrectly.
I don't know why, but when I fixed my dependencies in Gradle - all become working.

how to avoid warnings in ProGuard GUI

While trying to use ProGuard (5.3.2) to obfuscate a Automation framework getting lot of warnings i've resolved most of the warnings by adding respective library's but could not able to resolve below warnings. i have tried by adding com.hibernate-core jar but still getting same.
Warning: com.test.utils.DBOperations: can't find referenced method 'org.hibernate.Session openSession()' in library class org.hibernate.SessionFactory
Warning: com.test.utils.DBOperations: can't find referenced method 'void close()' in library class org.hibernate.Session
I have tried searching for a solution but the answer would always be for an android application.
I have find there is an option that I can select inside the Proguard GUI. Please check the picture:
This method is good for obfuscation the class name or method name inside the .jar file.
If you want to ignore the warning when creating from android studio or eclipse... just put some "-dontwarn" or "-ignorewarning" command inside the proguard-rule.pro file.

What are the recommended ProGuard rules for Smack 4.1?

What are the proper ProGuard rules for Smack 4.1 when building an Android release apk?
Currently, I'm using the rules from aSmack 4.0.x from the README.asmack file on the aSmack github repository which is outdated (references old class names, and intended for 4.0.x). I could not find any references to what the proper proguard rules to use for 4.1.x are, could anyone shed light on this?
What are the proper Proguard rules for Smack 4.1 when building an
Android release apk?
Depends on what "proper" means for you.
The easiest way is likely to tell ProGuard to keep all classes and interfaces of Smack.
-keep class org.jivesoftware.smack.** { *; }
-keep class org.jivesoftware.smackx.** { *; }
Alternatively you can configure ProGuard so that it only keeps those parts of Smack that you actually use, and let ProGuard strip everything else. But to do so, you'll need a good understanding how your App uses Smack. See for example the ProGuard configuration of MAXS's Transport XMPP: https://bitbucket.org/projectmaxs/maxs/src/75efeba8d8470b89da8cd8551304bb00648e4945/transport-xmpp/proguard-project.txt?at=master#cl-20
Note that if you don't know exactly what are you doing, then Smack could behave unexpectedly or even crash. Only fine tune ProGuard if you know what you are doing!
Actually, my experience suggests you may actually need an additional line if you are also using proguard and have minify enabled. If you get the error
java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType
Then the following config is needed instead:
-keepattributes Signature
-keep class org.jivesoftware.smack.** { *; }
-keep class org.jivesoftware.smackx.** { *; }
See: smack for android fails when using proguard for more details.

How to integrate Proguard obfuscation in my JavaFX's IntelliJ artifact?

I'm developing a JavaFX application using IntelliJ IDEA as the IDE.
So far, everything runs smoothly, I have all my external libs configured and my JavaFX artifact being correctly created.
Now I would like to integrate obfuscation (using Proguard) when the artifact is created.
IntelliJ have a 'Pre-processing' and 'Post-processing' option in artifact's properties where I can define an Ant task to be runned.
But I have no idea how to create that task and tell the compiler my obfuscation options.
Thank you very much in advance for any clues,
Best regards
There are 3 basic ways you do it:
Create a normal proguard.cfg file, and reference it from ant
Put your proguard settings directly inside ant using XML notation
Put your proguard settings directly inside ant using the proguard.cfg format
Here's a basic example of using Proguard with Ant with the 3rd approach:
http://www.reviewmylife.co.uk/blog/2007/10/20/proguard-eclipse-ant-buildxml/
The important thing to remember about Proguard is that everything you want to obfuscate has to be inside a JAR file, and you'll need to explicitly tell it not to obfuscate certain things (like your program entry point, things you access via reflection, etc).
JavaFX creates a file used as an entry point you want to prevent obfuscating:
-keepclasseswithmembers public class com.javafx.main.Main {
public *; public static *;
}
Make sure to include Java/JavaFX libs
-libraryjars "${java.home}/lib/rt.jar"
-libraryjars "${java.home}/lib/ant-javafx.jar"
-libraryjars "${java.home}/lib/jfxrt.jar"
If you're using FXML files, you'll want to make sure your FXML files are renamed similarly to their respective controller file:
-adaptresourcefilecontents **.fxml
Anything annotated with #FXML is accessed through reflection, so don't obfuscate them:
-keepclassmembernames class * {
#javafx.fxml.FXML *;
}
The Proguard website has a lot of information, but it can be difficult to grok.
Honestly, there are plenty of examples on the web that show you how to do this. Just google javafx proguard, and you'll probably find some good complete examples.
Edit: as far as how IntelliJ passes information to Ant.. I don't know. There are probably some variables it passes in that you reference like a normal Ant propertly. I'm sure JetBrains website has info on that on their website if you can't find it on the net.
If it was me, I'd just create an ant script to compile my application without obfuscation, then add in proguard once you've got that squared away.
Just some complementing information, regarding running an Ant task in idea's 'post-processing'.
Make sure you have a 'default' target. Else the task wont execute. Example of build.xml:
<?xml version="1.0"?>
<project name="ant_task" default="obfuscate" basedir=".">
<target name="obfuscate">
<taskdef resource="proguard/ant/task.properties"
classpath="/opt/proguard5.2.1/lib/proguard.jar" />
<proguard configuration="proguard.cfg"/>
</target>
</project>

How do I inject a local stateless session bean into a JAX-RS resource using CDI?

I have an .ear file with the standard lib directory.
I have a .jar file in that lib directory. It contains UserInfoManager, which is an interface. It contains (for these purposes) no other classes. It also contains a META-INF/beans.xml file.
I have another .jar file in that lib directory. It contains a class named UserInfoResource that is a JAX-RS resource class. That class has the following inside it:
#Inject
private UserInfoManager userManager;
Next, I have an EJB .jar file at the root of the .ear file. It contains a class named UserManagerBean that implements the UserInfoManager interface. This class is annotated with #Stateless and basically nothing else (thus making it a local stateless session bean exposed via its local business interface (UserInfoManager). This .jar file also has a META-INF/beans.xml file.
Next, I have a .war file with an Application class in it and nothing else. This serves as the "mounting point" for any and all JAX-RS resources discovered at deployment time present in the lib directory. I do not declare this Java EE 6 module as a CDI bean archive since it contains no beans.
This spec-compliant arrangement fails at deployment time. Weld (the CDI implementation in GlassFish 3.1.2) claims that the injection point detailed above cannot be satisfied, as there are no known implementations of UserInfoManager available to it.
When that injection point is annotated with #EJB instead, everything works fine.
How do I get CDI to inject a local stateless session bean reference into a JAX-RS resource that is present on the classpath?
Update: Because no matter how I look at this it seems like a specification violation, I have filed a bug with a testcase attached. I encourage readers to take a look and see if they can get it to work.
Update: The workaround is to make sure that your JAX-RS classes are not bean archives, but are annotated with #ManagedBean. In addition, the {{.war}} file that serves as their mount point must be a bean archive (must have a {{WEB-INF/beans.xml}} file). Some combination of these requirements is a CDI specification violation. The following bug tracks these issues: http://java.net/jira/browse/GLASSFISH-18793
Jersey does not treat Resources as managed beans unless there is an explicit scope/#ManagedBean annotation attached to it. So, you need to annotate your resource with #ManagedBean or #RequestScoped for the injection to work.
Seems the problem occurs only if beans.xml is included in the resource jar file. When I remove it and attach #ManagedBean annotation to the resource class (instead of #RequestScoped, since #RequestScoped does not work if no beans.xml is present) it works. I am not a CDI expert, so not sure if this is as designed or a bug.