Well it's actually not in the library itself, it's in a different library which depends on the annoration processor.
I have the roughly the following project structure.
Annotation Processor -> Android Library module -> Android App module
In the Android app I use annotations on some classes and the processor generates class that I'd like to use (and call its methods) in the library module. Is that even possible?
Right now I can only access it from the App module itself.
I actually feel like it all quite makes sense, just wonder if there is some way how to workaround that.
(When I pull the classes referencing generated code from the library module into app module itself, it works perfectly, I just want to have them in the library)
So far the only solution I was able to come up with was to not use the generated class itself, but rather define an interface, use that and let the code generator generate an implementation of it. Then provide the implementation from the app module back to the library module at runtime.
Related
I'm writing an annotation processor for an Android project and have run into a situation. I would like to process annotated classes from a library module, i.e. app module depends on library module and needs to process annotated classes from the library module.
However, the annotation processor isn't able to "see" the annotations from the dependency, presumably because the code is already compiled. See here for an issue on another library. A demonstration of the problem with my project is on the branch here. The annotations from sample module are processed but the ones from the lib module are not.
This is all well and good and I'd resigned myself to living without this feature, but it turns out the Android data-binding library can process annotations from modules and even third party libraries. This library, for example, provides #BindingAdapter methods that are processed fine by the app.
I played around with setting retention types on the annotations I use to no avail. The only significant difference I can see is that the data-binding processors target methods while my methods target classes (types), but I don't think that should make a difference from the processor. So I'm thinking it might have something to do with the data-binding processor being part of the Android plugin but I'm not sure how that helps here.
Anyone know how this is done?
Android Data Binding can't process annotations on dependencies, either. Instead, it processes the libraries at the compile time of the library and saves the information to an intermediate file as part of its archive (e.g. jar file). It then loads that intermediate file information from the dependency instead of reading the annotations.
If you save the intermediate information as a resource of the jar file dependency, you can pull it from the jar file pretty easily. If I recall correctly, it should be in your class path and you can use the ClassLoader's getResource() method. My memory may be a little stale on this as it doesn't use the jar file to store the intermediate file information any more.
I'm trying to do something clever. I am creating a weather application in which we can replace the weather API with another weather API without affecting the code base. So I started with a Maven project with multiple modules.
I have a Base module that contains the Interface class and the Base class. The Interface class contains the calls to the APIs (all calls are similar, if not exact) and the Base class contains the properties to the APIs (again, all properties are similar, if not exact).
I have a module for each of the two weather APIs we are testing with plans to create more modules for new weather APIs as we grow the application.
Finally, I have created a Core module (includes main) to implement the specific module class for the weather API I want to test.
Now, I know the simplest way to do this would be to use a switch statement and enumeration. But I want to know if there is a more clever way to do this. Maybe using a Pattern? Any suggestions?
Here is a picture of the structure I have just described:
Here is the UML representation:
This is a learning process for me. I want to discover how a real Java Guru would implement the appropriate module and class based on a specified configuration.
Thank you for your suggestions.
I'm trying to do something clever. I am creating a weather application
in which we can replace the weather API with another weather API
without affecting the code base.
Without reading further down, this first statement makes me think about a plugin architecture design, but in the process of software design, decisions must not be rushed, the more you delay, the more information you have and a better informed decision can be made, for now is just an idea to keep in mind.
I have a Base module that contains the Interface class and the Base
class. The Interface class contains the calls to the APIs (all calls
are similar, if not exact) and the Base class contains the properties
to the APIs (again, all properties are similar, if not exact).
When different modules share behaviour/state, it is a good idea to refactor them and produce base abstract classes and interfaces, so you are on the right track, but, if there are differences, those shouldn't be refactored into the base module. The reason behind that is simple, maintainability. If you start adding if clauses or switches to deal with these differences, you just introduced coupling between modules, and you'll be always having to make changes in the base module, whenever you add/modify other modules, and this is not desirable at all.
This is reflected by the Open/Closed principle form the SOLID principles, which states that a class should be open for extension but closed for modifications.
So after you've refactored the common behaviour into the base modules, then each new API should extend the base module, as you did.
Finally, I have created a Core module (includes main) to implement the
specific module class for the weather API I want to test.
Now, I know the simplest way to do this would be to use a switch
statement and enumeration. But I want to know if there is a more
clever way to do this. Maybe using a Pattern? Any suggestions?
Indeed, making use of a switch, makes it work, but its not a clean design at all, for the same reason as before, when adding, modifying or removing modules, would require to modify this module aswell, and also this code can potentially break.
One possible solution, would be to delegate this responsability on a new component and make use of a creational design pattern like the Abstract Factory, which will provide a interface to instantiate components without specifying its classes.
As for the architecture, so far, the plugin architecture still makes sense, but what if the different modules extend the base contract adding more features? One option is to use the Facade pattern to adapt the module calls and provide an output that implements an interface that clients expect.
But then again, with the provided details, this is the solution I'd suggest, but the scenario should be studied carefully and in greater detail, in order to be able to assure that these are the right tools for the job, and commit to them.
In addition to Salvador Juan Martinez's answer...
To implement a plugin architecture Java's Jar File Specification provides support for service provider interfaces (SPI) and how they are looked up.
As of Java 1.6. you can use the ServiceLoader to lookup service providers. For Java 1.5. and less you must do it on your own or use a library. E.g. commons-discovery.
The usage is quiet simple. In your case put a META-INF/services/com.a2i.weatherbase.IWeather file in each plugin module.
In the Weather Forecast IO module the file should contain only one line
com.a2i.weatherforecastio.ForecastIO
The line must be the full quallified name of an IWeather implementation class.
Do the same for the other module and you can load the implementations via ServiceLoader.
ServiceLoader<IWeather> weatherServicesLoader = ServiceLoader.load(IWeather.class);
Iterator<IWeather> weatherServices = weatherServicesLoader.iterator();
Now it depends on your runtime classpath how many services will be found. Try to add and remove module jar archives from the classpath and run your application.
EDIT
I wrote a blog about a pluggable architecture with standard java. See http://www.link-intersystems.com/blog/2016/01/02/a-plug-in-architecture-implemented-with-java/
Source code is also available at https://github.com/link-intersystems/blog/tree/master/java-plugin-architecture
One solution is you have to define the common interface with all the identified common operations. The extensions/plugins need to implement that interface and have to provide the implementation to common operations.
You can use an abstract factory design pattern to hook up the exact implementation at runtime based on the input parameters.
Interfaces and abstract classes are always good in such scenarios, Thanks.
I want to emulate a given type from a third-party library (GAE),
a Java class that is not supported by GWT:
com.google.appengine.api.datastore.GeoPt;
How do I emulate this class so GWT will support it? Where should I put the GeoPt.java file in my GWT app?
I cannot put it in the client path the packaging is different that my app. What could be the solution for this?
Further I assume, you have a module com.example.Example.gwt.xml .
I think you have two options. You can create a separate module, eg. AppEngine.gwt.xml, which source tag set to "api" and you put it into on com.google.appengine level. Then, you module need to inherit it - <inherits name="com.google.appengine.AppEngine"/>. It can be even in the same project - one project might have multiple modules.
Another approach is when you eg. want to reimplement a class only in GWT, while use same one in pure Java. Then in your module you create tag which points to a folder that will be a kind of root for a replaced classes. So, in your module you add <super-source path="appengine"/> and then you would put the class to com.example.appengine.com.google.appengine.api.datastore.GeoPt. You can read more on this at Organizing Projects, go to Overriding one package implementation with another section
I have a gwt project that acts as a semantic engine for other projects.
I recently realized very very little of the code is specific to gwt. Its almost all pretty basic java. In fact, the only things specific to gwt is retrieving files.
So what I would like to do is to separate out the gwt completely so I can use the same basic code for other Java projects - such as Android or Processing apps.
So, "Semantic Core" project could be inherited by GWT,Android and Processing apps and I wont have to maintain separate versions for each.
To do this, however, I need some way for other projects to "give" the Semantic Core project their own file-handleing methods.
My current idea how to do this;
One method I thought how to do this was to have SemanticCore define a Interface for FileManager with a method like;
getFile(String,MyErrorHandler,MySuccessHandler)
And then have the class's for MyErrorHandler and MySuccessHandler defined also in the SemanticCore project, effectively being runnables that take a string as a parameter.
With this Interface defined, other projects (GWT,Android etc) have to define their own class that implements it
eg, GWTFileHandler implements FileManager
Then create a object of this class, and pass it to the SemanticCore;
SemanticCore.setFileManager(new GWTFileHandler());
The semantic core can then use it at its leisure to retrieve files in a way suitable for the platform its on.
Question;
Is this a good way to do it? It seems wrong to me I am creating a new object, when I'll only be using static methods from that class.
Alternatives?
I hope my description is clear. As this all has to be GWT compatible in the "SemanticCore" project, any use of reflections is ruled out.
Thanks,
The recommended approach IMO is to use Deferred Binding to pick the GWT compatible version of your FileHandler or other GWT specific implementations. Extract the common interface for all versions and in your GWT module file you point to correct GWT implementation.
You can then instantiate your specific implemenation using GWT.create :
MyInterface implemenation = GWT.create(MyInterface.class);
more in depth info on the gwtproject site.
Deferred Binding is a technique used by the GWT compiler to create and
select a specific implementation of a class based on a set of
parameters. In essence, deferred binding is the GWT answer to Java
reflection. It allows the GWT developer to produce several variations
of their applications custom to each browser environment and have only
one of them actually downloaded and executed in the browser.
I have a Java project that expects external modules to be registered with it. These modules:
Implement a particular interface in the main project
Are packaged into a uni-jar (along with any dependencies)
Contain some human-readable meta-information (like the module name).
My main project needs to be able to load at runtime (e.g. using its own classloader) any of these external modules. My question is: what's the best way of registering these modules with the main project (I'd prefer to keep this vanilla Java, and not use any third-party frameworks/libraries for this isolated issue)?
My current solution is to keep a single .properties file in the main project with key=name, value=class |delimiter| human-readable-name (or coordinate two .properties files in order to avoid the delimiter parsing). At runtime, the main project loads in the .properties file and uses any entries it finds to drive the classloader.
This feels hokey to me. Is there a better way to this?
The standard approach in Java is to define a Service Provider.
Let all module express their metadata via a standard xml file. Call it "my-module-data.xml".
On your main container startup it looks for a classpath*:my-module-data.xml" (which can have a FrontController class) and delegates to the individual modules FrontController class to do whatever it wants :)
Also google for Spring-OSGI and their doco can be helpful here.
Expanding on #ZZ Coder...
The Service Provider pattern mentioned, and used internally within the JDK is now a little more formalized in JDK 6 with ServiceLoader. The concept is further expanded up by the Netbeans Lookup API.
The underlying infrastructure is identical. That is, both API use the same artifacts, the same way. The NetBeans version is just a more flexible and robust API (allowing alternative lookup services, for example, as well as the default one).
Of course, it would be remiss to not mention the dominant, more "heavyweight" standards of EJB, Spring, and OSGi.