Accessing app R class from my Android library - java

I'm developing a library that needs to access layout items of the app implementing it. The only way I know how to do it is with reflection. In other words, if I create a constructor to my Library API like this:
public MyLibraryAPI(String packageName) {
Class appR = Class.forName(String.format("%s.R", packageName));
...
}
And the developer would instantiate the library with his package name as the parameter in the constructor.
What I ultimately need is to let my inner classes know the Android Views used in the developers layout (.xml files) - both the id and the type. Is there a way to achieve this without reflection and escape the performance overhead? I'm certain it cannot be done, but asking in case there's an expert that sees what I fail to notice.
EDIT: Additionally, proguard, by default, obfuscates the code for protection but, as a consequence, fails to provide JVM with means to achieve reflection at runtime, so if I use reflection I would have to ask the developer to turn off proguard obfuscation for his or her R class which is a bummer.

Reflection on Android is extremely costly. Some well-meaning and popular libraries like Roboguice have fallen over partly because of the performance cost of reflection.
I suspect some kind of code generation is the correct solution here. Dagger 2, Butter Knife and the Data Binding Library are successful examples of Android libraries that employ code generation. Since the data binding library performs inspections on the XML, it must be available to code generation libraries at that stage in the build and you may be able to base your implementation on that: here's a link to the source jars at Maven Central.
Apart from that, yes it seems there will be some compromise between ease of use and difficulty-to-implement. If you force your consumers to annotate their classes with your annotations, it becomes harder to use but probably much easier for you to implement. If you restrict yourself to inspecting XML and the generated R file and generating code from just that then I think your job will be a lot more difficult. On the other hand, using annotations has become rather commonplace and it may not be such an issue with your users.
Good luck!

Related

JVM: most simple way to alter code of a dependency library?

Most of the time, I don't like Javascript and would prefer strict and compiled languages like Scala, Java, Haskell...
However, one thing that can be nice with Javascript is to be able to easily change code of external dependencies. For exemple, if you have a bug and you think it's one of your dependency library you can easily hack around and swap a library method by your own override and check if it's better. You can even add methods to Array ou String prototypes and things like that... One could even go to node_modules and alter the library code here temporarily if he wants to.
In the JVM world this seems to me like an heavy process to just get started:
Clone the dependency sources
Hack it
Compile it
Publish it to some local maven/ivy repository
Integrate the fixed version in your project
This is a pain, I just don't want to do that more than once in a year
Today I was trying to fix a bug in my app, and the lib did not provide me enough information. I would have loved to just be able to put a Logger on one line of that lib to have better insight of what was happening but instead I tried to hack with the debugger with no success (the bug was not reproductible on my computer anyway...)
Isn't there any simple alternative for rapidly altering the code of a dependency?
I would be interested in any solution for Scala, Java, Clojure or any other JVM language.
I'm not looking for a production-deployable solution, just a quick solution to use locally and eventually deployable on a test env.
Edit: I'm talking about library internals that are not intended to be modified by the library author. Please assume that the class to change is final, not replaceable by library configuration, and not injectable by any way into the library.
In Clojure you can re-bind vars, also from other namespaces, by using intern. So as long as the code you want to alter is Clojure code, that's a possible way to monkeypatch.
(intern 'user 'inc dec)
(inc 1)
=> 0
This is not something to do lightly though, since it can and will lead to problems with other code not expecting this behavior. It can be handy to use during development to temporarily fix edge cases or bugs in other libraries, but don't use it in published libraries or production code.
Best to simply fork and fix these libraries, and send a pull request to have it fixed in the original library.
When you're writing a library yourself that you expect people need to extend or overload, implement it in Clojure protocols, where these changes can be restricted to the extending/overloading namespaces only.
I disagree that AspectJ is difficult to use, it, or another bytecode manipulation library is your only realistic alternative.
Load-time weaving is a definite way around this issue. Depending on how you're using the class in question you might even be able to use a mocking library to achieve the same results, but something like AspectJ, which is specifically designed for augmentation and manipulation, would likely be the easiest.

Targeting identical classes in different packages

I have created a library which supports an application, however in the newest version of the application the developer has changed the structure without changing the class names.
So version 1 of the application has classX in package A but version 2 has classX in package B. How can I develop my library in a way which allows supporting both of these in the same build?
Edit: My library is dependent on the application, not the other way around.
That is a bad decision, if you still want to make it work you need to provide skeleton classes with old structure and delegate calls to new version of class but it would get very dirty
better to not provide backward compatibility if you are firm with the renaming decision
Short answer: You can't.
Real answer: Your library should be able to exist independently of any application that uses it. The purpose of a library is to provide a set of reusable, modular code that you can use in any application. If your library is directly dependent on application classes, then it seems like a redesign should be seriously considered, as your dependencies are backwards. For example, have A.classX and B.classX both implement some interface (or extend some class) that your library provides, then have the application pass instances of those objects, or Class's for those objects, to the library.
If your "library" can't be designed this way then consider integrating it into application code, making it a direct part of the application, and come up with a better team workflow for you, the other developer, and others to work on the same project together.
Quick fix answer: Do not provide backward compatibility, as Jigar Joshi states in his answer.
Bad answer: You could hack a fragile solution together with reflection if you really had to. But please note that the "real answer" is going to last in the long run. You are already seeing the issues with the design you have currently chosen (hence your question), and a reflection based solution isn't going to prevent that from happening again (or even be reliable).

Java Libraries Reuse

In software development we are all using the libraries by software providers. Consider in class A there are four functions viz., x,y,z. I just want my development team to avoid using the function x. So instead of telling them not to use, I found an idea. Inherit the class and override all the functions and for the function x an unsupportedmethod exception is thrown and for the rest I'm calling the super methods. There also I found a problem, developers can use the base class A directly, how to avoid the class A being used directly. I found a similar functionality in OSGi, the lib bundles can be brought in and then not exported and so on. Is there are any way to achieve this is java?
I suppose code reviews exist for these reasons. Consider situation where you can not edit the source of a third party, what would you do ? Like Siddharth says, sub class it and throw a meaningful exception and document it with a clear reasons. If someone is using base class even after that, mostly it may not out of ignorance,but it may out of curiosity. That kind of thing can be appreciated personally and for learning, but for the project sake developer has to follow the guidelines.
I think simply telling your developers what to do is preferred over a complex software solution. Sometimes the simple thing is better.
But, if you insist on going down this path, you can enforce your architecture standards using aspects if you're a Spring user. Weave the offending methods with an aspect that throws an exception if they're called.
You can edit library class file in hex editor and modify its access modifier from public to package private. Also you can rename it and then use inheritance to wrap this class. Here you can find class file specification. Once I've tried this technique to substitute jdbc driver class with wraper class that provide some additional logging and other useful tricks.
There is a variety of tools that check source code for adherence to certain rules, such as formatting, dead code, naming conventions for variables etc. Popular ones for Java include the Maven Enforcer plugin, checkstyle and PMD.
These might allow you to write a rule that forbids certain method calls. Then you could check automatically at compile time. As far as I can tell, unfortunately none of the tools above support "illegal method calls" out-of-the-box; however, at least for PMD writing new checks is fairly simple.

Maintainability of Java annotations?

My project is slowly implementing Java annotations. Half of the developers - myself included - find that doing anything complex with annotations seems to add to our overall maintenance burden. The other half of the team thinks they're the bee's knees.
What's your real-world experience with teams of developers being able to maintain annotated code?
My personal experience is that, on average, dealing with annotations is far easier for most developers than dealing with your standard Java XML Configuration hell. For things like JPA and Spring testing they are absolute life-savers.
The good thing about annotations is that they make configuration on your classes self-documenting. Now, instead of having to search through a huge XML file to try and figure out how a framework is using your class, your class tells you.
Usually the issue with changes like this is that getting used to them simply takes time. Most people, including developers, resist change. I remember when I started working with Spring. For the first few weeks I wondered why anyone would put up with the headaches associated with it. Then, a few weeks later, I wondered how I'd ever lived without it.
I feel it breaks into two uses of annotations - annotations to provide a 'description' of a class vs. annotations to provide a 'dependency' of the class.
I'm fine with a 'description' use of annotations on the class - that's something that belongs on the class and the annotation helps to make a shorthand version of that - JPA annotations fall under this.
However, I don't really like the 'dependency' annotations - if you're putting the dependency directly on the class - even if it's determined at runtime from an annotation rather than at compile time in the class - isn't that breaking dependency injection? (perhaps in spirit rather than in rule...)
It may be personal preference, but I like the one big XML file that contains all the dependency information of my application - I view this as 'application configuration' rather than 'class configuration'. I'd rather search through the one known location than searching through all the classes in the app.
It depends highly on IDE support. I feel that annotations should be kept in sync with the code via checks in the IDE, but that support for this is somewhat lacking.
E.g. the older version of IDEA would warn if you overrode a function without #Override, but wouldn't remove the #Override tag if you changed the method signature (or the superclass signature, for that matter) and broke the relation.
Without support I find them a cumbersome way to add metadata to code.
I absolutely love annotations. I use them from Hibernate/JPA, Seam, JAXB....anything that I can. IMO there's nothing worse than having to open up an XML file just to find out how a class is handled.
To my eye annotations allow a class to speak for itself. Also annotations are (hopefully) part of your IDEs content assist, whereas with XML config you are usually on your own.
However, it may come down to how the XML configs and Annotations are actually used by any particular library (as most offer both), and what sort of annotation is used. I can imagine that annotations that define something that is build-specific (eg. file/url paths) may actually be easier as XML config.
i personally feel that the the specific use case you mentioned (auto-generate web forms) is a great use case for annotations. any sort of "framework" scenario where you can write simplified code and let the framework do the heavy (often repetitive) lifting based on a few suggestions (aka annotations) is, i think, the ideal use case for annotations.
i'm curious why you don't like annotations in this situation, and what you consider to be the "maintenance burden"? (and, i'm not trying to insult your position, just understand it).

Sandboxing Java / Groovy / Freemarker Code - Preventing execution of specific methods

I'm developing a system that allows developers to upload custom groovy scripts and freemarker templates.
I can provide a certain level of security at a very high level with the default Java security infrastructure - i.e. prevent code from accessing the filesystem or network, however I have a need to restrict access to specific methods.
My plan was to modify the Groovy and Freemarker runtimes to read Annotations that would either whitelist or blacklist certain methods, however this would force me to maintain a forked version of their code, which is not desirable.
All I essentially need to be able to do is prevent the execution of specific methods when called from Groovy or Freemarker. I've considered a hack that would look at the call stack, but this would be a massive speed hit (and it quite messy).
Does anyone have any other ideas for implementing this?
You can do it by subclassing the GroovyClassLoader and enforcing your constraints within an AST Visitor. THis post explains how to do it: http://hamletdarcy.blogspot.com/2009/01/groovy-compile-time-meta-magic.html
Also, the code referenced there is in the samples folder of Groovy 1.6 installer.
You should have a look at the project groovy-sandbox from kohsuke. Have also a look to his blog post here on this topic and what is solution is addressing: sandboxing, but performance drawback.
OSGi is great for this. You can partition your code into bundles and set exactly what each bundle exposes, and to what other bundles. Would that work for you?
You might also consider the java-sandbox (http://blog.datenwerke.net/p/the-java-sandbox.html) a recently developed library that allows to securely execute untrusted code from within java.
Also see: http://blog.datenwerke.net/2013/06/sandboxing-groovy-with-java-sandbox.html

Categories