Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
What are the options to define the public interface to a library in Java.
For example I often find that things are public because another package in the library needs them (although still with a common base package, e.g. com.stackoverflow.mylib.), so they can't have the package access level, and generally people don't want massive packages (it also seems that people using Spring insist on having the separate controller/service/model/impl/etc. packages, resulting in a single "feature" being forced to span many packages, when say a given service might be a completely internal implementation detail not for external use...).
So the ideal goal is to make the Jar I provided to 3rd parties to make it clear that these things are not to be used, ideally by not having them available at all (not present in the API jar), so that it is not possible for them to use and compile with those internal objects/methods.
Even more ideally for objects there only supposed to obtain from some kind of factory (e.g. a provided Spring Bean), a way to prevent direct instantiation from their code or custom bean (which may leave some future, not yet present property uninitialised after upgrade).
The two formal ways I know of currently are:
In some projects I have worked on, there is an api package (e.g. com.stackoverflow.mylib.api), and the rule is only the contents of this package may be directly accessed by outside users.
In some other projects I have worked on, there have been some custom attributes, e.g. #PublicSDK to mark objects and methods for use by the public (and I think some extra stuff to ensure only things marked as such are in the publicly distributed javadoc and api jar).
The first thing to ask yourself is - do you really need to hide the implementation details?
The reason I say this is that there's going to be an expense involved in doing so, which depending on your circumstances may or may not be worth paying.
For example, if your API is being used by developers outside of your immediate team then it's probably worth the expense; however if it's just to hide the implementation details within you team I think it's overkill.
If the API is for use within your project then a standard where by you try to depend only on abstract types or interfaces is, imho, sufficient (and already the standard).
However, assuming you do need to hide the implementation and expose only the public API, the best way I know to do it is to produce two jars - one containing the public API and another that is the implementation of that API.
If you're using Maven or Gradle to build the project that is using your API you simply declare a compile time dependency on the API jar (artifact) and a runtime dependency on the implementation jar (artifact).
This pattern can be seen throughout the common Java APIs, the latest example being the JSON API that is implemented separately as part of Glassfish.
Related
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I know that in Java dependency injection makes life better. There are a lot of annotation processor frameworks that map beans to objects and conveniently inject them into a right place.
But I never heard about dependency injection in Python or Ruby, for example. Do this languages have build-in support for it? Or they don't need it? Why?
In short, In Python, dependency injection is less important than it is in Java because of the stateful nature of modules and the role of metaprogramming.
In languages like Java, classes typically define blueprints for objects, which must be instantiated at runtime by whatever imports them. When you import a class, you only get the recipe for the class.
Conversely, in Python importing a module can do a lot more. During an import, you are essentially running a module's code within a namespace - meaning that the module can not only construct singletons referenced by the module itself, but can even perform complex tasks like connecting to databases during execution of the import. When two modules import the same referenced module, the second module inherits Python's evaluated concept of the module from when it was first imported, preserving and changes the first importer may have made. Furthermore, its much less painful to scan for submodules in Python and Ruby than it is in Java, which more frameworks use module placement to indicate function (such as models.py in Django) than you see in Java (which generally favors annotations).
TLDR: modules and classes in Python (and Ruby) are stateful in ways that are painful or impossible to replicate in Java, and the mechanics of the import statement provide most of the interesting parts of dependency injection (although not IoC). It doesn't not-exist, its just not as necessary.
See also: Why is IoC / DI not common in Python?
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 9 years ago.
Improve this question
How can I publish an API with Java? In languages like C or C++ it is really quite easy because you can simply divide headers from code, but in Java this is a complete different story. So I know that there is no real way in Java you can obfuscate your code, even if you "obsfuscate" it, because it can be easily decompiled and analyzed. But if I don't simply can distribute headers to someone, what is the preferred way to publish a API in Java? I don't have special needs because I am in the beginning of the designing process so I am really dynamic and I would like to know all alternatives I have.
A clean way is to define your API purely in Java interfaces, include those into a separate API module and make implementation module depend on the API module. This does not provide the same functionality as separating C++ header files, but it is a good idea to program to interfaces anyway completely separating those from a particular implementation.
You don't need to publish your API as header files. Everything the developer needs is already in the JAR. If you want to publish documentation publish the java docs of the code.
You can obfuscate your code using a professional java obfuscator. Then it is not easily decompiled and readable. You can then publish your jars and javadocs like others have mentioned.
You could split your library into multiple jars and provide one with the classes and interfaces that form the api and another one that contains the implementations of those interfaces.
However, note that the hastle might not be worth it. Why exactly would you try and obfuscate code the users of that api would need anyways? What I mean is, that whoever would use your api would also need the implementations of the interfaces to run the application, so they'd still be able to decompile your code.
Generating an api-only jar would help with separating api and implementation though (which means you could replace the implementation or prevent accidential direct access to the implementation).
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I'm documenting my project which is a really simple Android application and I'm getting rather confused about the three.
Is what you import on Java the library? Is an API a library? If so, does that mean that Android is a library?
library : A collection of one or more packages will be called library.
package : A group of classes will contribute a package.
class : A compiled java which accomplish an atomic functionality of its own. A class is a construct that is used to create instances of itself
In java, you could either import a package or class itself. Yes, API could be called library using which we could built our own system/application. Android is a platform and not library. But android SDK could be called library instead which has API for talking to device.
A Class is the code construct that allows to create instances of itself or perform operations with the methods it includes. It's the basic unit of your programm.
A package if a collection of Classes that interact and offer some special functionality/help to accomplish a specific task.
A Library is a compound of Classes and Documentation that help in the development of software, often including several packages.
A library is a software that contains implementations of any kind of thing software can do '.dll' files in windows, '.jar' files in java. Libraries usually provide one or more APIs (Application Programming Interface), that allow you to use the application. To an API belong the public Classes and Interfaces in the Library (or the functions in C).
Android is an operating system. It provides libraries. These provide APIs.
EDIT: forgot packages:
packages are java's way of grouping classes and interfaces.
Another EDIT: classes are part of Object Oriented Languages. They define what Object's have (properties) and do (methods).
.class files are compiled java code.
class: A byte-code file produced by compiling the .java file using javac (Java compiler).Further read by JIT to convert it into runtime machine level executable code.
package: Collection of classes, In java mainly all the packages are according to their functionality.
library: Consider its a a collection of packages, documentation etc.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
My system is connecting to Oracle through Hibernate/JDBC. I want to restructure it using abstraction to decouple its implementation from Hibernate library. That's a backup for someday the team can switch to another JPA implementation without painful to change core business logic to adapter with new JPA implementation. What are advices in doing this?
By the way, I want some advice from gurus what are common practices/tactics to decouple existing projects from external open source jars?
Direct dependence on standard and popular open source libraries is OK. You shouldn't consider it as a problem. For e.g I have a large code base and it depends upon joda-time, google-guava etc. Now, coming to your situation, following is my view point
There is very less chance that you move from one JPA implementation to another because by the time you get familiar with a particular implementation (yes implementation because you might want to optimize something or you are looking for some feature that is missing from standard JPA api) it would take some time and you really doesn't want to spend the same effort learning other implementation (business doesn't let you even if you want to ;-)).
Spring already abstracts most of the regularly used API's like JPA, JMS etc. so I suggest you look at that option.
You should program against interfaces to reduce dependencies. Your service classes -the ones that contain Business Logic- should depend on Data Access Object Interfaces instead of an specific DAO implementation. Something like this:
public class ImAServiceBean {
private EntityDAO entityDAO;
private void someBusinessLogic(){
entityDAO.createInstance(...);
Were the DAO interface goes this way:
public interface EntityDAO {
void createInstance (...);
void updateInstance(...);
Now you're using something like EntityHibernateDaoImpl, but if you want to change your persistence framework to MyBatis you can build an EntityMyBatisDaoImpl (which implements EntityDAO) and use that class in your Services classes with no change at all (asumming you're using some kind of dependency injection). The same thing if you use JPA, JDO or any persistance technology: your Business Logic only depends on a plain interface, and that interface can be implemented but any persistence technology, even JDBC
JPA already is a separate API. if your team uses JPA, then you should already have the ability to switch from hibernate with zero effort.
Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 11 years ago.
Improve this question
How do you decide what a package name should be and what class should go into what package ?
I'm working on a project where I am constantly adding/removing classes and not really sure if I need a new package, or should add it to an existing one that im not currently aware of.
Do you follow a set of rules when creating a new package ?
How do you know if you are not duplicating package functionality ? Is this just down to familiarity with the project.
Any pointers appreciated.
I strongly discourage from organizing packages from an implementational point of view, like controllers, data, etc. I prefer grouping them by functionality, that is, feature1, feature2, etc. If a feature is reasonably complex and requires a large number of classes, then (and only then) I create subpackages like above, that is, feature1.controllers, feature1.data, etc.
Classes should do one thing (Single Responsibility Principle).
Classes that do related things should go in the same package. If you find you can more closely relate some of the classes in a package, make them a subpackage!
For example, if I had a project with these classes:
GreetingInputWindow
GreetingDatabaseObject
GreetingDatabaseConnector
I might just put them all in the greeting package. If I wanted to, I might put GreetingInputWindow in the greeting.ui package, and the other 2 into the greeting.db package.
I don't believe there are any hard and fast rules on packaging convention (though I could be wrong). Normally I break it up into
com.mycompanyname and then:
api
controllers
data (for models)
jobs (for cron jobs)
reporting
servlet
utils
If I find I have a class which does not fit into any of those, then I create a new package.