Java - modular library project - how to? - java

I am supposed to deliver a SDK in Java for the company I work for.
I have a few years of Java EE experience but not so much when it comes to develop API and SDK.
The problem here, is that the SDK is already available in .NET C# and working just fine. I made it myself.
Switching to Java is a nightmare. I tried several solutions. All failed, some were inconclusive due to the fact I could not progress.
As the title says, I a need to develop a Java Library that has modules. Internal modules. Modules the world out there is NOT supposed to see / use / modify.
In C#, it's easy as pie : create your modules respective namespace, make their classes and methods privates, expose one or more wrappers (bridges) to the entire assembly (project) with internal so that the "main module", through it's own public wrapper accessible by the world, can use the tools provided within these internals modules.
The keyword, here, is INTERNAL. I think it's pretty easy to understand. So let's take an example.
Let's say the SDK is consisting of 4 modules.
The 1st module, is the main module, the one that is public and
exposed to the whole world. In other words, the unique entry point
of the SDK. It's like a master of its own universe. It can use the
internal modules at will, but will never show them to the world.
Never.
The 2nd module is network-related. As in, it deals with network to manage connexions to remote services, read and write data from and to a stream. It offers its own little wrapper so that the main module does not need to use the 2nd module internal tools. Like a universe inside a universe.
The 3rd module is a data processing module. It receives packets (hand-made by the 2nd module) so that it can be processed and relevant information dealt with.
So here we are. How can I do that in Java using NetBeans ?
I tried Maven with POM Project, and Netbeans modules. A nightmare.
I tried creating multiple libraries (one per module), tweaked the Main Module library to include its (modules) dependancies but it does not work.
In a standard Java EE console application, as soon as I attempt to instanciate my SDK Manager (ergo the main wrapper from the main module), it fails because Class Not Found exception : could not find classes related to the internal sub-modules.
If I add all modules respective Jar into this Java Console app, it can access all wrappers. Where is the fun in that ?
Thanks for the help !

Project Jigsaw will eventually give you what you want when java 9 comes out.
See this article about how jigsaw works, in particular,
An exports clause in a module declaration makes the public types in
the package it names available to other modules, so we can with Jigsaw
defines boundaries, and not all public types could be used from other
modules, we must explicitly specify which types are visible.

Related

How to create a class in one module(A) that implements an abstract class from another module(B)

I use Microservices architecture with Spring-cloud stack.
For communication between services I decided to use gRPC.
I had an service named Accounting and today I implemented a gRPC-interface project and added it to Git repository.
I added gRPC-interface to the Accounting service using Git-submodules using following commands:
git submodule add -b master <Git-Repo-URL>
git submodule init
Now I want to create a service class in Accounting that implements one class from gRPC-interface but it doesn't recognize any class from gRPC-interface module!!
I think I need to make some changes in setting.gradle and build.gradle files in Accounting module, but I don't know what changes should I do and even don't know what topic to look for on the internet.
Any help or clue would be appreciated!!
It sounds like you're in over your head on microservices here, but, in the interests of answering the question as stated:
Think 'twitter API'. Twitter has 2 'projects' (not in the git submodule sense, in the english word sense). There's twitter-the-website, which is non-public code that runs it all, notably including the code that answers when you connect to api.twitter.com. But there's also an open source (or at least, publicly available) library that you can include in your java projects that lets you talk to the twitter API. This public API includes model classes that match concepts in the twitterverse (such as 'a tweet', 'a user', 'a direct message', 'the concept of one user deciding to follow another', etc), as well as functions (presumably on an 'api' object) that you call with parameters and which returns instances of these model classes.
You need to do the same thing. A microservice consists of two projects: Its API which another microservice includes in itself, which is analogous to the public 'java API' library that twitter offers, and the actual code. Which could be one project or a million, a significant part of the point of microservices is: From the point of view of microservice A that depends on microservice B, you don't need to know anything about B at all except the part that describes its public API. Everything else is an implementation detail that just doesn't matter, as far as service A is concerned.
If you included all the code of a microservice in another, then you end up with every 'microservice' including all code of all others, and there's nothing micro about your services anymore.
Yes, this is annoying. You don't exactly need to duplicate code (the 'public API' part that defines the models can also be a dependency of the microservice itself), but every microservice turns into maintaining 2 separate ones, and you need to find a way for the 'public API' part to be distributable as if it was the twitter API. You probably don't want to put it on maven central, but that's why maven (sonatype, really), gradle, etc all offer the notion of a company-wide intermediate dependency server - that one can host your 'public API' projects. As well as local dependencies - read the docs of your build system on how to deal with non-open-source-publicized (I.e. not on maven central) dependencies.

Maven: difference module - java package

Recently I started to use Maven for managing my project's structure more efficiently. However, since i'm at the same time learning JAVA, i've come to a dead-end, What is the difference between a module in MAVEN and a JAVA package ?
Since packages are used to group classes/interfaces that share common purpose:
(source: docs.oracle)
Definition A package is a grouping of related types providing access protection and name space management.
And i couldn't find a clear definition of a module, better stated than the vague:
(source: http://docs.jboss.org/tools/latest/en/maven_reference/html/creating_a_maven_application.html)
A Maven module is a sub-project
From what i read, we should create modules in order to separate logic in the project, business, domains, basically anything considered a s a separate entity.
Hence, why can't we do the same with usage of packages? Isn't the purpose the same?
I'm also negelecting all build-configurations here. If it's the only difference, then please provide argumentation when which one should be used.
Maven is a bundling tool, it assembles reusable parts of software together to an application, no matter if it is Java code, image resources or HTML templates. It builds your application so it can be run or deployed in a certain environment (local, testing, production etc.) All of this has nothing to do with Java packages.
You should care about Maven Modules if you (or others) want to reuse code that you have written. For instance, you wrote a web application that converts currencies and now you'd like to use the conversion logic (but not the web frontend) in another application. In that case you'd create one module for the web frontend and one module for the business logic.
A package is a collection of classes. A module is a collection of packages with build configuration.
If it was your own project you can organize them however you want with packages and/or modules. If you want to create a re-usable component (e.g. library) for multiple project you should use a module.
If you only have packages a project would have to include all of the packages (i.e. source files) directly for every library that it needed. Instead with module (remeber it also has build configuration) you can take the compiled output (e.g. .jar, .aar, etc) and include that in your project.

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

Adding Common class for different blackberry application

I have written a common class which I want to use in separate Blackberry applications. This class is not in a separate project but just at a common location and I have linked the path of the common class in Java Build Path. I have added same common path to both of my BB applications and they builds and installs without any problem. When I run one application, it start running but when I run the other application, it gives error message "class xxx multiply defined" error and exits.
Any idea what is going wrong here. Thanks in advance
Regards,
Braj
BlackBerry doesn't work as other Java platforms. In BB Java, you can't have two classes with the same full qualified name, even if they live in different projects.
You'll have to rename one of them (either change the class name or the package name) for it to work.
In fact, the only platform where I have seen this restriction is BB. It is a real pain in the ass since you can't reuse a jar library in different projects without renaming it.
UPDATE:
This is the official article on the topic:
http://supportforums.blackberry.com/t5/Java-Development/Application-throws-quot-multiply-defined-quot-error-at-start-up/ta-p/501498
All applications in RIM OS run under one instance of Java Virtual Machine. And therefore it is allowed only one class with particular full qualified name. Adding another class with the same name will lead to failure upon running both of these classes.
There is a library thing, supported in RIM OS, but I do not recommend to use libraries in your project, unless it is very necessary.
It is because if you have several apps with the same library, but with different versions of libraries you may get the same error you reported in your question. And it is hard to manage libraries when you have many applications which use these libraries.
I recommend to copy source code of your library to the project you are working on. Copy via refactoring, to change all full qualified names of classes included in that library.
Thanks guys for replying. I have created a common library and put common code in that. Now I can use this library in different applications without any problem.
However, when I install my applications using BB desktop Manager, the library appears as part of first application but not in second application. I assume it is because, second application realizes that the library is already been included so doesn't need to include it again.

Creating Android Modular Applications on Eclipse

I am currently porting a framework for building applications on J2ME to Android. This framework consists of several projects that compile to libraries (jars). Each individual JAR can contain graphical data (resources, J4ME screens, etc.). Every project generally has a well defined entry point (module). When someone wants to build an application using the framework he must only create a Midlet project and add library dependencies and use the imported classes.
We have been using the same approach to develop the Android framework. In this case we have only used normal Java Projects inside Eclipse that compile to jar libraries. These projects have dependencies with the Android Framework (android.jar). When building a new application we create an Android Project inside Eclipse and add the dependencies.
Our next step is to build more advanced modules for Android that can also contain graphical information (Activities, Dialogs, Literals, Drawables, etc.). So far only an Android Eclipse project was needed (the end application), that contained all the graphical-related classes and resources. It seems that when using resources (literals, drawables, etc.) the only approach is to create an Android Application, since the resources are only referenceable by means of an integer handler automatically created by ADT plugin (R.XXX). So building graphical modules may not be built by means of plain Java jar projects.
Android developer information explains that modular applications are feasible, but I have not found a concise tutorial explaining the process, but some tips such as how to prevent an error to ocurr when an application invokes an intent made available by other application. This is valid when building applications that use resources from other applications. I do not need several installed applications on the system, but one built from several components.
Has anyone experience developing with similar requierements? Any good tutorial or tips to start out?
It seems that the only available way is described here as hinted by the accepted answer of this other question.
The solution however is rather new (it only works with latest Android SDK tooks R6 and SDKs 2.0.X are left out of support). It has some major caveats on which I hope Google is already working:
No binary library linking. This means that the main application needs access to sources (in Eclipse implies having all the linked library projects open).
The names of resources (layouts, drawables, etc) are treated globally. This means that if you have two "main.xml" layouts, only the most relevant (uppermost in library list) will be used.
Missing funcionalities/BUGs. The documentation states that exported activities of a library project must only be declared in AndroidManifest.xml of library project. This does not work in current version. Comments inside TicTacToe example hints that this is the desired working, but for current release of Android Tools used activities from library projects must be explicitly defined in AndroidManifest.xml of main application project.

Categories