Manage Lite and Pro versions of app in Eclipse - java

I just finished my Full version on my app. I am now looking around trying to figure out how to make my Lite version of the app. Not a whole lot is different but there are differences especially when you are playing the trivia game. How do I go about managing both of these versions in Eclipse? I looked at this guide:
http://blog.donnfelker.com/2010/08/05/howto-android-full-and-lite-versions/
But it seems like the linked tutorial is outdated based on the comments below the tutorial about adding Proguard to the code. There has to be an easy way to do this. Is the best way still to make 3 projects like the above linked tutorial says but just find away to get around the Proguard issue?

Not sure if this counts as an answer but I have positive experiences from using library projects when creating dual version Apps like free/pro, lite/paid or whatever you choose to call them.
You can separate the differences in logic either by using simple if-statements, like if(AppType.isFree(context)) where in the helper method you check if the context package is that of the free or paid version.
Or by using inheritance and interfaces to take advantage of polymorphism and dynamic binding.
For example the menu activity in your lib might invoke a getGameActivity, which depending on sub class (free or paid) returns the appropriate version of the game and where most of the logic is in the abstract lib GameActivity class.
And about ProGuard, if you are not very afraid of reverse engineering, it's not really necessary to bother with it.

Related

Is there a way to import a specific version of a java sdk in a project with multiple versions of the same sdk?

Because of, reasons, I cannot just update the old version of the aws sdk I'm working with, but I also need some new things that are in a more recent version.
The problem is that if put both version of the sdk the project I get a "java.lang.NoSuchMethodError" because I think it's trying to use the old version of the sdk. If I delete the old one and just use the updated one it works fine. Is there a way to keep both version of the sdk and tell my java class which one to exclusively import?
There are a couple of ways, but they're pretty nasty.
The arguably "more correct" approach is to could use a custom classloader - see this answer for details. However, that's not exactly simple, and can lead to weird outcomes.
A simpler, but somewhat nastier approach is to get the source code of both SDKs (if available), and rename the packages. For example if we have sdk_v1 and sdk_v2, we can rename the packages to com.example.sdk.v1 and com.example.sdk.v2,
Once there's no package name collision, there's no problem using two different SDKs, even in the same class - just use fully qualified imports (see answer):
com.example.sdk.v1.SomeClass.someFunc() will not collide with com.example.sdk.v2.SomeClass.someFunc()

Minor changes in code or preprocess in Java for different builds?

I am working on my Android game called Flat Out Hockey using eclipse as an IDE, Java and native C++.
My issue is with the Java part of the code.
Since I need to build my game for both FireTV, Google Play and OUYA I have different ways to deal with gamepad input on each platform.
One issue is that FireTV uses a different "Project Build Target" than Google Play and OUYA, something specifically made for FireTV by Amazon.
This means I need to use imports and classes that are available under one build target but not on the other and keep switching between them when I build for each platforms.
The issue is that as far as I know there is no preprocessor in Java?
So I just can't do #ifdef like in C++.
This makes the amount of code I need to comment/uncomment or change the values more than it should be.
One "trick" I did was to create a kind of a mimic class for the Amazon gamepad class so I would just change the imports and have a class with the same name but different functionality.
But there are other issues, like the Immersive attribute which is only available on Android OS 5.
And other stuff.
So maybe I am missing some feature in Java, but I would really like to just have to set a single value in a single place to switch between different builds.
Is there anything like that in Java/eclipse?
One approach would be to split your project into several components: a "core" module that defines the main implementation in terms of common interfaces (which it defines), and then a module per target that declares implementations of those interfaces.
So for instance, your core module may define a GamePad interface, and then your FireAdapter module would depend on both the core and Fire's API to create a FireGamePad (which implements GamePad).
Each module then becomes it own build, with its own deliverable.
you could try to use java Comment Preprocessor https://github.com/raydac/java-comment-preprocessor , I made some experiments with usage for Android https://github.com/raydac/java-comment-preprocessor/wiki/AndroidGradlePreprocessing but not very deeply, the preprocessor was developed in 2002 specially for small changes in J2ME projects to avoid huge number of the classes with the same functionality but with small differences for vendor specific parts

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).

Keeping track of utility classes

I've recently been more and more frustrated with a problem I see emerging in my projects code-base.
I'm working on a large scale java project that has >1M lines of code. The interfaces and class structure are designed very well and the engineers writing the code are very proficient. The problem is that in an attempt to make the code cleaner people write Utility classes whenever they need to reuse some functionality, as a result over time and as the project grows more and more utility methods crop up. However, when the next engineer comes across the need for the same functionality he has no way of knowing that someone had already implemented a utility class (or method) somewhere in the code and implements another copy of the functionality in a different class. The result is a lot of code duplication and too many utility classes with overlapping functionality.
Are there any tools or any design principles which we as a team can implement in order to prevent the duplication and low visibility of the utility classes?
Example: engineer A has 3 places he needs to transform XML to String so he writes a utility class called XMLUtil and places a static toString(Document) method in it. Engineer B has several places where he serializes Documents into various formats including String, so he writes a utility class called SerializationUtil and has a static method called serialize(Document) which returns a String.
Note that this is more than just code-duplication as it is quite possible that the 2 implementations of the above example are different (say one uses transformer API and the other uses Xerces2-J) so this can be seen as a "best-practices" problem as well...
Update: I guess I better describe the current environment we develop in.
We use Hudson for CI, Clover for code coverage and Checkstyle for static code analysis.
We use agile development including daily talks and (perhaps insufficient) code reviews.
We define all our utility classes in a .util which due to it's size now has 13 sub-packages and about 60 classes under the root (.util) class. We also use 3rd party libraries such as most of the apache commons jars and some of the jars that make up Guava.
I'm positive that we can reduce the amount of utilities by half if we put someone on the task of refactoring that entire package, I was wondering if there are any tools which can make that operation less costly, and if there are any methodologies which can delay as much as possible the problem from recurring.
A good solution to this problem is to start adding more object-orientation. To use your example:
Example: engineer A has 3 places he needs to transform XML to String so he writes a utility class called XMLUtil and places a static toString(Document) method in it
The solution is to stop using primitive types or types provided by the JVM (String, Integer, java.util.Date, java.w3c.Document) and wrap them in your own project-specific classes. Then your XmlDocument class can provide a convenient toString method and other utility methods. Your own ProjectFooDate can contain the parsing and formatting methods that would otherwise end up in various DateUtils classes, etc.
This way, the IDE will prompt you with your utility methods whenever you try to do something with an object.
Your problem is a very common one. And a real problem too, because there is no good solution.
We are in the same situation here, well I'd say worse, with 13 millions line of code, turnover and more than 800 developers working on the code. We often discuss about the very same problem that you describe.
The first idea - that your developers have already used - is to refactor common code in some utility classes. Our problem with that solution, even with pair programming, mentoring and discussion, is that we are simply too many for this to be effective. In fact we grow in subteams, with people sharing knowledge in their subteam, but the knowledge doesn't transit between subteams. Maybe we are wrong but I think that even pair programming and talks can't help in this case.
We also have an architecture team. This team is responsible to deal with design and architecture concerns and to make common utilities that we might need. This team in fact produces something we could call a corporate framework. Yes, it is a framework, and sometimes it works well. This team is also responsible to push best practices and to raise awareness of what should be done or not, what is available or what is not.
Good core Java API design is one of the reason for Java success. Good third party open sources libraries count a lot too. Even a small well crafted API allows to offer a really useful abstraction and can help reduce code size a lot. But you know, making framework and public API is not the same thing at all as just coding an utility class in 2 hours. It has a really high cost. An utility class costs 2 hours for the initial coding, maybe 2 days with debugging and unit tests. When you start sharing common code on big projects/teams, you really make an API. You must ensure perfect documentation then, really readable and maintainable code. When you release new version of this code, you must stay backward compatible. You have to promote it company wide (or at least team wide). From 2 days for your small utility class you grow to 10 days, 20 days or even 50 days for a full-fledged API.
And your API design may not be so great. Well, it is not that your engineers are not bright - indeed they are. But are you willing to let them work 50 days on a small utility class that just help parsing number in a consistent way for the UI? Are you willing to let them redesign the whole thing when you start using a mobile UI with totally different needs? Also have you noticed how the brightest engineers in the word make APIs that will never be popular or will fade slowly? You see, the first web project we made used only internal frameworks or no framework at all. We then added PHP/JSP/ASP. Then in Java we added Struts. Now JSF is the standard. And we are thinking about using Spring Web Flow, Vaadin or Lift...
All I want to say is that there is no good solution, the overhead grows exponentially with code size and team size. Sharing a big codebase restricts your agility and responsiveness. Any change must be done carefully, you must think of all potential integration problems and everybody must be trained of the new specificities and features.
But the main productivity point in a software company is not to gain 10 or even 50 lines of code when parsing XML. A generic code to do this will grow to a thousand lines of code anyway and recreates a complex API that will be layered by utility classes. When the guy make an utility class for parsing XML, it is good abstraction. He give a name to one dozen or even one hundred lines of specialized code. This code is useful because it is specialized. The common API allows to work on streams, URL, strings, whatever. It has a factory so you can choose you parser implementation. The utility class is good because it work only with this parser and with strings. And because you need one line of code to call it. But of course, this utility code is of limited use. It works well for this mobile application, or for loading XML configuration. And that's why the developer added the utility class for it in the first place.
In conclusion, what I would consider instead of trying to consolidate the code for the whole codebase is to split code responsibility as the teams grow:
transform your big team that work on one big project into small teams that work on several subprojects;
ensure that interfacing is good to minimize integration problems, but let team have their own code;
inside theses teams and corresponding codebases, ensure you have the best practices. No duplicate code, good abstractions. Use existing proven APIs from the community. Use pair programming, strong API documentation, wikis... But you should really let different teams make their choices, build their own code, even if this means duplicate code across teams or different design decisions. You know, if the design decisions are different this may be because the needs are different.
What you are really managing is complexity. In the end if you make one monolithic codebase, a very generic and advanced one, you increase the time for newcomers to ramp up, you increase the risk that developers will not use your common code at all, and you slow down everybody because any change has far greater chances to break existing functionality.
There are several agile/ XP practices you can use to address this, e.g.:
talk with each other (e.g. during daily stand-up meeting)
pair programming/ code review
Then create, document & test one or several utility library projects which can be referenced. I recommend to use Maven to manage dependecies/ versions.
You might consider suggesting that all utility classes be placed in a well organized package structure like com.yourcompany.util.. If people are willing to name sub packages and classes well, then at least if they need to find a utility, they know where to look. I don't think there is any silver bullet answer here though. Communication is important. Maybe if a developer sends a simple email to the rest of the development staff when they write a new utility, that will be enough to get it on people's radar. Or a shared wiki page where people can list/document them.
Team communication (shout out "hey does someone have a Document toString?")
Keep utility classes to an absolute minimum and restrict them to a single namespace
Always think: how can I do this with an object. In your example, I would extend the Document class and add those toString and serialize methods to it.
This problem is helped when combining IDE "code-completion" features with languages which support type extensions (e.g. C# and F#). So that, imagining Java had a such a feature, a programmer could explore all the extension methods on a class easily within the IDE like:
Document doc = ...
doc.to //list pops up with toXmlString, toJsonString, all the "to" series extension methods
Of course, Java doesn't have type extensions. But you could use grep to search your project for "all static public methods which take SomeClass as the first argument" to gain similar insight into what utility methods have already been written for a given class.
Its pretty hard to build a tool that recognizes "same functionality". (In theory this is in fact impossible, and where you can do it in practice you likely need a theorem prover).
But what often happens is people clone clode that is close to what they want, and then customize it. That kind of code you can find, using a clone detector.
Our CloneDR is a tool for detecting exact and near-miss cloned code based on using parameterized syntax trees. It matches parsed versions of the code, so it isn't confused by layout, changed comments, revised variable names, or in many cases, inserted or deleted statements. There are versions for many languages (C++, COBOL, C#, Java, JavaScript, PHP, ...) and you can see examples of clone detection runs at the provided
link. It typically finds 10-20% duplicated code, and if you abstract that code into library methods on a religious base, your code base can actually shrink (that has occurred with one organization using CloneDR).
You are looking for a solution that can you help you manage this inevitable problem, then I can suggest a tool:
TeamCity: an amazing easy to use product that manages all your automated code building from your repository and runs unit tests etc.
It's even a free product for most people.
The even better part: it has built in code duplicate detection across all your code.
More stuff to read up:
Tools to detect duplicated code (Java)
a standard application utility project. build a jar with the restricted extensibility scope and package based on functionality.
use common utilities like apache-commons or google collections and provide an abstraction
maintain knowledge-base and documentation and JIRA tracking for bugs and enhancements
evolutionary refactoring
findbugs and pmd for finding code duplication or bugs
review and test utility tools for performance
util karma! ask team members to contribute to the code base, whenever they find one in the existing jungle code or requiring new ones.

How to determine which source files are required for an Eclipse run configuration

When writing code in an Eclipse project, I'm usually quite messy and undisciplined in how I create and organize my classes, at least in the early hacky and experimental stages. In particular, I create more than one class with a main method for testing different ideas that share most of the same classes.
If I come up with something like a useful app, I can export it to a runnable jar so I can share it with friends. But this simply packs up the whole project, which can become several megabytes big if I'm relying on large library such as httpclient.
Also, if I decide to refactor my lump of code into several projects once I work out what works, and I can't remember which source files are used in a particular run configuration, all I can do it copy the main class to a new project and then keep copying missing types till the new project compiles.
Is there a way in Eclipse to determine which classes are actually used in a particular run configuration?
EDIT: Here's an example. Say I'm experimenting with web scraping, and so far I've tried to scrape the search-result pages of both youtube.com and wrzuta.pl. I have a bunch of classes that implement scraping in general, a few that are specific to each of youtube and wrzuta. On top of this I have a basic gui common to both scrapers, but a few wrzuta- and youtube-specific buttons and options.
The WrzutaGuiMain and YoutubeGuiMain classes each contain a main method to configure and show the gui for each respective website. Can Eclipse look at each of these to determine which types are referenced?
Take a look at ProGuard, it is a "java shrinker, optimizer, obfuscator, and preverifier". I think you'll mainly be interested in the first capability for this problem.
Yes it's not technically part of Eclipse, as you requested, but it can be run from an Ant script, which can be pretty easily run in Eclipse.
I create more than one class with a main method for testing different ideas that share most of the same classes.
It's better to be pedantic than lazy, it saves you time when coding :-)
You can have one class with a main method that accepts a command-line argument and calls a certain branch of functionality based on its value.

Categories