I'm trying to optimize / obfuscate a java project with ProGuard.
I extract the project as a runnable jar from eclipse, and it runs just fine.
When I try to compress it with ProGuard, I get thousands of warning and errors, in particular at the end:
Note: there were 1 classes trying to access generic signatures using reflection.
You should consider keeping the signature attributes
(using '-keepattributes Signature').
Note: there were 14 unresolved dynamic references to classes or interfaces.
You should check if you need to specify additional program jars.
Note: there were 2 class casts of dynamically created class instances.
You might consider explicitly keeping the mentioned classes and/or
their implementations (using '-keep').
Note: there were 15 accesses to class members by means of introspection.
You should consider explicitly keeping the mentioned class members
(using '-keep' or '-keepclassmembers').
Warning: there were 13229 unresolved references to classes or interfaces.
You may need to add missing library jars or update their versions.
If your code works fine without the missing classes, you can suppress
the warnings with '-dontwarn' options.
Warning: there were 61 instances of library classes depending on program classes.
You must avoid such dependencies, since the program classes will
be processed, while the library classes will remain unchanged.
Warning: there were 18 unresolved references to program class members.
Your input classes appear to be inconsistent.
You may need to recompile the code.
The external libs I used in the project are added to the jar upon exporting it from eclipse. ("Extract required libraries into jar"). I did not use the "repack into jar" option because it really slows jars down.
The libs in particular are:
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
Am I doing something fondamentally wrong here?
I have tried without success the suggestions of proguard, and my code compiles in eclipse with no warnings.
It's a very big project so I can't really provide an MCVE, but if someone could point me in the right direction here as to what I'm missing, I'd really appreciate it.
Example of the warning: (It goes on for every single method)
http://pastebin.com/m9hX9LJA
Obviously this might be too general of a problem for you guys to fix, however I might be doing some major obvious mistake that I'm not realizing, that's what I'm going for with this.
Notes are just suggestions, but warnings point out inconsistencies in the input. Notably, the 13229 unresolved references suggest that you are providing the main code of your application (with -injars), but not its libraries (with -injars or -libraryjars). I don't know of Eclipse's Extract or Repack options, but you should check the contents of your input jar(s).
See the ProGuard manual > Troubleshooting > Warning: can't find referenced class.
Related
I'm generating PDF report using JasperReports library. I this report I have a QRCode which makes problem. I had to add many libraries:
jasperreports, itext, itext-pdfa, itext-pdf, commons-beanutils, commons-collections, commons-digester, commons-logging, groovy-all, barbecue, barcode, barcode4j, batik-anim, batik-bridge, core, w3c.css.sac, w3c,xmlgraphics-commons, batik-all
I receive an exception:
java.lang.ClassCastException: org.apache.batik.anim.dom.SVGOMDocument cannot be cast to org.apache.batik.dom.svg.SVGOMDocument
at org.apache.batik.bridge.BridgeContext.setDocument(Unknown Source)
at org.apache.batik.bridge.GVTBuilder.build(Unknown Source)
at net.sf.jasperreports.renderers.AbstractSvgDataToGraphics2DRenderer.ensureSvg(AbstractSvgDataToGraphics2DRenderer.java:166)
at net.sf.jasperreports.renderers.AbstractSvgDataToGraphics2DRenderer.getDimension(AbstractSvgDataToGraphics2DRenderer.java:111)
at net.sf.jasperreports.engine.export.JRPdfExporter$InternalImageProcessor.processGraphics2D(JRPdfExporter.java:1793)
at net.sf.jasperreports.engine.export.JRPdfExporter$InternalImageProcessor.process(JRPdfExporter.java:1582)
at net.sf.jasperreports.engine.export.JRPdfExporter$InternalImageProcessor.access$300(JRPdfExporter.java:1535)
at net.sf.jasperreports.engine.export.JRPdfExporter.exportImage(JRPdfExporter.java:1475)
at net.sf.jasperreports.engine.export.JRPdfExporter.exportElements(JRPdfExporter.java:1093)
at net.sf.jasperreports.engine.export.JRPdfExporter.exportPage(JRPdfExporter.java:1056)
at net.sf.jasperreports.engine.export.JRPdfExporter.exportReportToStream(JRPdfExporter.java:920)
at net.sf.jasperreports.engine.export.JRPdfExporter.exportReport(JRPdfExporter.java:537)
at reports.JasperReport.generatePdf(JasperReport.java:178)
What is wrong?
If this is your own code (you wrote it), it is just because of you have imported the wrong SVGOMDocument class (which belongs to different Java package).
You should be able to figured it out quickly with decent Java IDE (Eclipse, IntelliJ, NetBeans).
Also, as much as possible try to avoid implicit imports such as:
import org.apache.batik.dom.svg.*;
import org.apache.batik.anim.dom.*;
That might reduce your code stability, e.g. lines added above might alter your reference of existing working code.
Use explicit imports (import org.apache.batik.dom.svg.SVGOMDocument).
Find out what's the return type of the method you invoke, and import from the correct Java package. In Eclipse IDE, you can just remove the import that contains the package/class above, and choose Source > Organize Imports (Ctrl-Shift-O).
If you have both classes in single source code file, you might need to use full class name for one of the classes, e.g.:
org.apache.batik.dom.svg.SVGOMDocument document = SomeLibrary.getSomething();
I was using JD-GUI to get readable content of the several .class files in order to create a custom one, because many parts of the original libraries are not used (save space and performance)
So I read the code and started creating an eclipse library project in eclipse pasting them in.
soon apeared the first weird errors:
The method getLogger(Class) from the type Logger refers to the missing type Class
Implicit super constructor Object() is undefined for default constructor. Must define an explicit constructor
and so on.
Does anyone has experience in creating libraries from other libraries in eclipse? what is going wrong?
thank you.
EDIT:
it seems that several imports are not found:
error example:
The import org.w3c.dom.stylesheets cannot be resolved
how can this be, when the original libraries are working fine? I did not remove a single class. my custom library is just a merged one with 100% the same content.
So, I've got this problem - a strange problem. I have a library as part of an IDEA project - in which all the code is publicly visible under 'tk.*' (IE: all classes exist in sub-packages of tk). Should the attempt be made to import a class residing within that package IDEA highlights the import statement (only th 'tk' mind you - which is strange enough), citing the reason mentioned later. Despite the apparent "errors", the project (consisting of a formidable number of files) compiles successfuly - very much so, infact.
Info:
The highlight reason (when you hover over the aforementioned highlight): 'tk' is not public in ''
Note about this: the file importing from said package IS NOT in the default package.
It would seem that the importing from packages residing in other libraries is not found at fault by IDEA
The class(es) imported by aforementioned file(s) are not package-private, nor protected, nor private - they are public
The project's path settings should be correct, however I am open to the suggestion that these may be at fault
Notes:
Sorry if this quiestion reads wierdly - I'm rather distracted by the environment in which I currently reside.
I'm getting desperate with this Problem: I want to export/run my Android Application with one additional .jar I added to the buildpath. I'm sure I added it correctly, there are 5 other .jars included and they all work fine.
with this special one I get the mentioned error.
I've already tried everything that can be found in this question:
"Conversion to Dalvik format failed with error 1" on external JAR
and several other links google spat out. The main Problem is, I actually do not understand what the message I appended want's to tell me because if I add all the jars to a "normal" javaproject, it runs perfectly fine...
Developing on Android 4.0.3,
proguard 4.8,
adt 16.0.1.v201112150204-238534,
eclipse 3.7.1.r37
please help me
[2012-07-18 10:45:48 - myapp] Dx warning: Ignoring InnerClasses attribute for an anonymous inner
class (iaik.xml.crypto.XSecProvider$1) that doesn't come with an
associated EnclosingMethod attribute. This class was probably produced
by a compiler that did not target the modern .class file format. The
recommended solution is to recompile the class from source, using an
up-to-date compiler and without specifying any "-target" type options.
The consequence of ignoring this warning is that reflective operations
on this class will incorrectly indicate that it is not an inner
class.
...
...
[2012-07-18 10:45:48 - myapp] Dx warning: Ignoring InnerClasses attribute for an anonymous inner
class (iaik.xml.crypto.XSecProvider$2) that doesn't come with an
associated EnclosingMethod attribute. This class was probably produced
by a compiler that did not target the modern .class file format. The
recommended solution is to recompile the class from source, using an
up-to-date compiler and without specifying any "-target" type options.
The consequence of ignoring this warning is that reflective operations
on this class will incorrectly indicate that it is not an inner
class.
Ill-advised or mistaken usage of a core class (java.* or javax.*) when
not building a core library.
This is often due to inadvertently including a core library file in
your application's project, when using an IDE (such as Eclipse). If
you are sure you're not intentionally defining a core class, then this
is the most likely explanation of what's going on.
However, you might actually be trying to define a class in a core
namespace, the source of which you may have taken, for example, from a
non-Android virtual machine project. This will most assuredly not
work. At a minimum, it jeopardizes the compatibility of your app with
future versions of the platform. It is also often of questionable
legality.
If you really intend to build a core library -- which is only
appropriate as part of creating a full virtual machine distribution,
as opposed to compiling an application -- then use the
"--core-library" option to suppress this error message.
If you go ahead and use "--core-library" but are in fact building an
application, then be forewarned that your application will still fail
to build or run, at some point. Please be prepared for angry customers
who find, for example, that your application ceases to function once
they upgrade their operating system. You will be to blame for this
problem.
If you are legitimately using some code that happens to be in a core
package, then the easiest safe alternative you have is to repackage
that code. That is, move the classes in question into your own package
namespace. This means that they will never be in conflict with core
system classes. JarJar is a tool that may help you in this endeavor.
If you find that you cannot do this, then that is an indication that
the path you are on will ultimately lead to pain, suffering, grief,
and lamentation.
[2012-07-18 10:45:48 - myapp] Dx 1 error; aborting
[2012-07-18 10:45:48 - myapp] Conversion to Dalvik format
failed with error 1
This is how my project looks int he explorer:
The problem is that the jar you are including has a class in the java.* or javax.* namespace. dx does not allow this, as mentioned in the last big error message.
If you actually need these classes, you'll need to move them to a different package, using something like the jarjar tool. Otherwise, you'll need to remove them from the jar -- it may be possible to have proguard to remove them before everything gets dx'd, I'm not sure.
I faced the same problem, I finally resolved it by exporting my private library explicitly.
Like:
Project >> properties >> Java Build Path >> Libraries >> Add External Jars.
Note: Removed my all private libraries from libs folder. I know it is not correct but it worked for me.
Thanks,
Anil
Do as follows :
project
> properties
> java build path
> libraries
> remove all including android jars
Now, go the project browser, right click on the project you are working on, then
android tools
> fix project properties.
Do a clean and then build.
Just restart eclipse, and the error won't occur anymore
If you work on Win7 change this line:
call %java_exe% -jar "%PROGUARD_HOME%"\lib\proguard.jar %*
in proguard.bat file to this:
call %java_exe% -jar "%PROGUARD_HOME%"\lib\proguard.jar %1 %2 %3 %4 %5 %6 %7 %8 %9
proguard.bat is in:
[Android SDK Installation Directory]\tools\proguard\bin\proguard.bat
Edit:
I hope a combine of these help you:
1-Try to delete libraries projects from your project.
2-Try to export your project(as archive file),delete project and it's source from workspace and then import it again.
3-Try to remove your jars from path,do clean-build and then add them again to your project.
I had the same error when using my own obfuscated lib jar.
my log:
warning:Ignoring InnerClasses attribute for an anonymous inner class that doesn't come with an associated EnclosingMethod attribte.This class was probably prouduced by a compiler that did not target the morden .class file format...
And I solved it like this:before I obfuscate my jar,I added "-keepattributes EnclosingMethod" to the proguard.cfg(or proguard-project.txt in latest android adt version).
Agree with hasanghaforian. The easiest solution is to remove libraries project.
Right click your project->Properties->Java Build Path then remove Library Projects
I am having problems compiling some Scala with Maven or Eclipse where I try to import a class from a Java jar which contains both a namespace and class of the same name.
I can compile with scalac, however.
E.g. the Java project (jar) contains:
src/foo/bar.java
src/foo/bar/some_resource.txt
-> foobar.jar
Scala project references foobar.jar
Foobartest.scala:
import foo.bar
class foobartest {
}
The compiler complains with:
package foo contains object and package with same name: bar
one of them needs to be removed from classpath
Using Maven 3.0.03/Eclipse 3.7.1 with Scala 2.9.0.1 (and maven-scala-plugin).
The jar which I am having problems with is jenkins-core-1.399.jar - it definitely contains several instances where there is a namespace and object of the same name.
I am attempting to write a Jenkins plugin in Scala (I could do this in Java but would prefer scala since all of our libraries are in scala), which is dependent on using Maven -
https://wiki.jenkins-ci.org/display/JENKINS/Plugin+tutorial.
That kind of limitation was outlined in SI-4695: package object misbehaves in the presence of classfiles.
As suggested in SI-2089 (naming restriction makes some jars unusable), you could try and use the "resolve-term-conflict", as implemented in changeset 25145:
Added a -Y option to resolve namespace collisions between package and object.
It's a blunt instrument: if people have lots of these conflicts they need to resolve in individually nuanced fashion, they'll probably remain out of luck.
val termConflict = ChoiceSetting ("-Yresolve-term-conflict", "strategy", "Resolve term conflicts", 113 List("package", "object", "error"), "error")
// Some jars (often, obfuscated ones) include a package and
// object with the same name. Rather than render them unusable,
// offer a setting to resolve the conflict one way or the other.
// This was motivated by the desire to use YourKit probes, which
// require `yjp.jar` at runtime. See SI-2089.
The actual compiler option is "-Yresolve-term-conflict:strategy" where strategy is either package, object, error.