Menu

Changing Member Access To Public

Anonymous
2005-08-17
2012-12-17
  • Anonymous

    Anonymous - 2005-08-17

    Can anyone confirm for me that ProGuard will change the access for package/protected members of classes in a package even if that package was specified to keep all classes using
      -keep class com.mycompany.mypackage

    If so, does anyone know what would it take to make ProGuard leave the access alone for classes and their members in packages that had no classes  moved to the default package?

     
    • Anonymous

      Anonymous - 2005-08-17

      PS: The reason I ask is because I have a JAR where I want to obfuscate all but two public packages.  But it appears, even though I keep all of the classes in these two packages that the methods which are protected become public, causing subclasses which declare them as protected to get the following message from the compiler: "attempting to assign weaker access privileges; was public". It's important to the integrity of my code that the access on these two packages are not changed, as well as to allowing subclasses to not be forced to declare things as public which needed only to be protected.

       
    • Anonymous

      Anonymous - 2005-08-17

      PPS: The reason I must move the obfuscated classes to a common package instead of leaving them in their original package is because I have one application which hosts plugins.  Some of these plugins are written by our team and use the same set of obfuscated library classes which will have been obfuscated differently when the plugin's JAR was created.  This creates a conflict in the packaged references between the plugin's JAR and the hosting system's JAR.  And we do not want to distribute multiple JAR's - we vastly prefer to package the shared code into a complete JAR.

       
    • Eric Lafortune

      Eric Lafortune - 2005-08-17

      Correct; when using the -defaultpackage option (to repackage obfuscated classes into a single package), all package/protected access modifiers are made public. You may be able to achieve what you want using two processing passes, with incremental obfuscation.

      Eric.

       
      • Anonymous

        Anonymous - 2005-08-17

        Eric,

        What possible justification is there for changing the access modifiers for a package that has not had any classes moved to the default package?  To do so would seem to me to be a bug.

        How would you envisage I could accomplish this in two passes? As far as I can see, regardless of when I move the other packages to the default package, the classes in the two packages that I need left alone will have their modifiers changed.

        --
        Lawrence.

         
        • Eric Lafortune

          Eric Lafortune - 2005-08-17

          Changing the access modifiers on all classes is the sledge-hammer approach to making sure all classes can access each other's fields and methods, whether they are obfuscated or not, and whether they are repackaged or not. The -defaultpackage option is primarily intended for end-applications in which noone cares about the access modifiers anymore. Its implementation is open for refinement.

          You may be able to process classes that have to be repackaged first, with the -defaultpackage option. You may then be able to process the two special packages incrementally, without the -defaultpackage option. Of course, I don't know the dependencies between your packages, so this may or may not be possible.

          Eric.

           
          • Anonymous

            Anonymous - 2005-08-18

            Eric,

            I've managed to solve it, but it was inordinately complicated.  And it's taken me all day to hit upon the right combination.

            As a result I feel very strongly that the -defaultpackage option needs to be augmented with something like -keeppackage packagename which would (a) prevent package's classes from being moved to the defaultpackage and (b) causes the member and class access settings to remain unchanged.

            To reiterate, the essence of my problem is that we have a pluggable framework for which we write some of the plugins, and our customers write others.  The plugins we write use a large number of packages common to framework, but which are not public for our customers to use (more for reasons of API commitment and maintainability than because the code is particurlarly proprietary). In addition, there are a small number of packages (5) which support the framework and must be public for all. However, these packages contain package level APIs that MUST NOT be made public, because to do so exposes APIs that could be used to compromise the runtime operation and security of the framework.  Our customers need to know that as long as they protect access to our framework JAR that no plugin they configure can mess around with their system.

            The common classes have dependancies on the framework classes and vice-versa.

            For the benefit of others, what I did to solve this was:
              1. Create a JAR with the common classes.
              2. Create a JAR with the framework API classes.
              3. Obfuscate, but don't shrink the common JAR, with the framework JAR as a libraryjar.
              4. Obfuscate, but don't shrink the framework JAR, with the common JAR as a libraryjar and the common mapping from (3) applied.
              5. Combine and shrink the common and framework JARs into a single distribution JAR with the mappings for the common and framework JARs applied.

            We will have to repeat this 3 sweep process for all variations of our framework. This will number about 5 or 6.

            This is a lot of work for what could have been simply adding:
              -keeppackage com.mycompany.framework.pkg1
              -keeppackage com.mycompany.framework.pkg2
              -keeppackage com.mycompany.framework.pkg3
              -keeppackage com.mycompany.framework.pkg4
              -keeppackage com.mycompany.framework.pkg5
            to my ProGuard options.

            A second major negative of having to do this is that it means that all my keep options are doubled up; once in the config for the non-shrunk JAR and once in the config for the final distribution JAR.

            A third problem is that I now have 2 mappings to apply for deobfuscating stack traces (can Retrace even do that?).

            Forth is that now  have 2 seed files. 

            Fifth, and also significant, is that the usage log is much less useful because it refers to all the obfuscated names since it is only produced by the 3rd sweep.

            Eric - can you point me to key places in the code where I could make such a change myself?  And, will you consider adding such a keep option or similar in the 3.4 ProGuard release?  I think this would benefit ProGuard immensely.

            Thanks for your help and for this great utility.

            --
            Lawrence.

             
            • Eric Lafortune

              Eric Lafortune - 2005-08-19

              The manual already quite clearly describes the implications and counter-indications of the -defaultpackage option. I am considering refining the implementation, but it is unlikely this will happen for version 3.4 or even 4.0. I understand the difficulties that you face, but the problem you describe seems quite particular. If you browse through these forums, you'll notice how everyone else also thinks their requested enhancements are primordial. I am open to suggestions, but I prefer to set my own course.

              Question 2: You can use "-include <filename>" to share common pieces of configuration.

              Question 3: Yes, you can pipe a stack trace through ReTrace as many times as needed, e.g.:

              java -jar retrace.jar names1.map stacktrace.txt |
              java -jar retrace.jar names2.map

              Last question: src/proguard/obfuscate/ClassFileOpener.java changes the access modifiers when obfuscation with -defaultpackage. Maybe you can just disable it entirely for your code, or hard-code some exceptions.

              Cheers,

              Eric.

               
              • Anonymous

                Anonymous - 2005-08-22

                Thanks Eric.  Let me reiterate that ProGuard is a great package and I certainly appreciate having it available to use. I do appreciate the fact the everyone thinks there requirement is of primary importance and should comment that my requirement only matters if you have a "plugin" style framework for which the majority of is likely to be using existing open-source frameworks which don't need to be obfuscated.

                Anyway, thanks again, and I will proceed with making my own mods to ProGuard as soon as time permits.

                --
                Lawrence.