For jstl tags, an API javax.servlet.jsp.jstl-api-1.2.1.jar & implementation javax.servlet.jsp.jstl-1.2.1.jar are provided.
For servlets, an API in servlet-api.jar & implementation jar from tomcat or GlassFish are provided.
For collections, API like java.util.List & corresponding implementations like java.util.ArrayList & java.util.LinkedList are provided.
IDE Netbeans is another example.
Implementation jar includes both the API(mostly interfaces) and its implementation, What are the advantages in providing a solution with an API JAR and their corresponding implementations(a separate JAR), for programmers/developers to use?
For developing enterprise applications using java, Is providing an API the standard approach for stable contract between developers?
I have advocated separating the API from its implementation in my Practical API Design book. At that time I valued the simple library as well as modular library approaches. We used them both successfully when designing NetBeans Platform APIs. I usually felt uneasy when it came to vendor library style - a common approach used in Java EE world.
Later I realized the optimal solution depends on the desired degree of proximity (see my detailed explanation). In short, it depends how closely the API author is related to the one who implements the API. Is it the same person? Is it a group that sit down and agreed on a specification? Are they different, but we expect way more users of the library than those who implement it? Or do we expect almost every user to implement (something in) the library? The answer to this question then leads to:
None to many
One to many
Few to many
Many to many
Proximity classification. Each of them can be handy in some situations. However, my all time favorite is many to many approach with full featured modular library design.
1) If you put the API in a different jar, then you can let it be used by clients that can't access the implementation. For example:
You can exclude the implementation from the compile-time classpath of clients, to ensure that clients of the API don't require any particular implementation.
You can exclude the implementation from the run-time classpath of API clients (either via ClassLoaders like servlets do or separate JVMs), so that clients can't depend on any particular implementation, and so that they can use libraries that would conflict with the ones that the implementation uses.
2) Not really individual developers, but it's common to use a strategy like that to avoid conflicts and unwanted dependencies between different development teams.
This is because only the API is standardised, and multiple implementations are possible, and the API is an incomplete specification. In the case of servlets, in addition to the servlets API, which your Web App uses, there is the web application server (Tomcat or Glassfish). The application server is a large program, with many other features and APIs. For a Web Application, your servlets are not "the program"; the application server is. It is not that your servlets delegate to the server, the server delegates to your code (in a WAR).
In programming using an implementation, you might need the API specification (interfaces, abstract classes etc) too.
Interface obj = new ClassImpletingInterface();
which could also be done as
ClassImpletingInterface obj = new ClassImpletingInterface();
If your program used only the latter, you might get away having just the implementation jar that didn't include the API package. As far as possible, one should use the former for better maintainability etc. Now the question of why can't the API package just be bundled into the implementation jar - one API one jar. Might sound simple, but may not be desirable. You might prefer to use the javax.servelet.jsp.jstl-api package obtained from the authentic source; not bundled in com.newbie.servlet-0.0.1.jar. There can be legal aspects that prevent such bundling. Further, an implementation not necessarily provide functionality for the complete specification. Your imports for an API could come from two different implementations as different parts, and they could be for different release levels of the specification. In that case, perhaps rare, each bundling a different release level of API may cause trouble because jar search within a directory is not completely defined. So, bundling of API and implementation into separate jars is cleaner.
Related
I have zero experience with Java, but when trying to understand a certain "apocalyptic" vulnerability, I ended up with a fundamental question about imports in Java, so please bear with me.
My question is, as given in the title, why a Java package can not be updated with a single central patch.
For comparison, two hypothetical diametric cases that I think I understand reasonably well:
If, say, a python library had some vulnerability, then it should suffice (on well-maintained systems that use centralized libraries located on PYTHONPATH) to update that single library and any code that imports it should, in general, be fixed.
On the other hand, if a C library had a vulnerability, then it would be necessary to replace every single binary whose source includes the vulnerable library with a patched binary.
Now, as far as I could tell, Java is actually closer to the former category of languages, where external imports are not included in compiled sources.
If this is the case, then why can't a single patch be applied to fix an entire system (au contraire, our IT department forwarded a gigantic list of software for us to check individually)? Is it because of multiple decentralized copies of identical libraries being installed, or is there some other reason? Or am I misunderstanding the issue?
Java applications themselves are separate processes. In principle, all these processes can use different VM's. This is often the case for larger applications, which are tested against a specific VM. In principle, Java runtimes (J2SE implementations) should remain as compatible as possible with each other, but it is certainly possible for developers or libraries to muck this up, e.g. by using "Sun" inner classes or by assuming things not specified for the API calls. Personally hate these kind of J2SE inclusions; I'd rather have applications that are created to remain compatible.
Smaller applications usually just run on one of the installed JRE's. However, they usually still need additional libraries or components - say, for instance, Log4J from Apache. These are often offered as separate .jar files (or "artifacts" in Maven speak). These libraries may also get updates; there is however not a common way of updating these on most systems; there is no single "application" set of shared libraries although it is certainly possible to create one. On Linux for instance there may be a set of libraries in /usr/share/java (by version, with generic names pointing to the latest one).
Many web applications - I those running on a specific application server such as Tomcat, Glassfish etc. do share a common "classpath", where application specific .jar files are put in specific folder. In that case an update of a library in the shared folder will affect all applications.
Java has had a framework for specific class-loaders, and in principle any framework can define their own set, so where the libraries are stored can depend on the framework. Java is very flexible and doesn't really have one single way of handling applications.
All this has previous little to do with import statements. These are just use as a shorthand notation, basically. You might as well use java.util.List as import java.util.List followed by List further in the code. Class files contain references to other classes (etc.), and those are resolved (found and loaded) at runtime; see the description from Oracle here.
I'm trying to send logs to Stackdriver and am a little confounded by the option of two dependencies I could use —
The Google Cloud Client Library recommends google-cloud version 0.35.0-alpha
The logging docs recommend I install google-cloud-logging version 1.14.0
Googling around for the LogEntryOperation I would like to use yields a google-api-services-logging version v2-rev577-1.23.0.
Are the underlying communications mechanisms to Google's API different between these?
Which of these is most feature-full, least likely to be deprecated, and maintained going forward? Why are there so many?
Google Cloud ships two kinds of client libraries:
Auto generated libraries that just export the REST API directly. These are called the "Google API Client Libraries". These have the advantage that they cover every API in every language in complete detail.
For Java, these are in com.google.apis. This is what you found searching for LogEntryOperation.
Hand-crafted libraries that aim to be more "natural". These are called the "Google Cloud APIs". These are easier to use and fit in better with how the language is used. However they are available for fewer API/language combinations, and don't always cover 100% of the API.
For Java, these are in com.google.cloud. This is what our docs recommend. google-cloud is simply a convenience package for all of the available libraries, including the logging-specific google-cloud-logging package.
The logging library is a good example of the difference. As the actual REST API exposes a LogEntryOperation resource, the auto-generated API just creates a LogEntryOperation class that blindly copies this.
By contrast, the manually created API has a more concisely named Operation class. In addition, the manually created API provides a better static constructor, a Builder, and names the first() and last() methods more sensibly.
I'm a beginner in Java EE technologies. I wonder what the difference is between the jstl-api jar and the jstl-impl jar.
Why are the API and implementation separated? Does it mean there are other implementations available?
The API and implementation are separated, because Java EE works with a standardized specification.
The API is part of that specification, and contains a set of mostly interfaces to which everybody that participated in creating said specification agreed. In theory everyone can make an implementation that implements the published standardized API and behaves as described in the associated specification document. You are allowed to call your implementation "certified" when it passes the so-called TCK (Technical Compliance Kit).
It's a stated goal of this specification system to encourage competition, while at the same protected users form being locked-in to any specific implementation.
JSTL in particular is part of the JSP spec, which has been developed under JSR 245. If you would like to make your own implementation, you'd begin with reading the spec document.
Could you point me to any tutorials that explain how to write our own impl for jstl?
There are as far as I know no specific tutorials for creating your own implementation of whatever Java EE specification. It's in nearly all cases pretty much an expert job, and a job which is typically only carried out by a select few organizations or individuals. This kind of material doesn't really lend itself to tutorial-like write ups, although David Blevins (of TomEE fame) has given us the occasional glimpse in the work that is approximately involved with this.
jstl-api contains the interfaces that need to be implemented. The jstl-impl contains the standard or default implementation of those implementations. Why do you need both? because if you want the standard or default functionality you use the jstl-impl, but if you want to implement your own behaviour, you can override the methods of the interfaces in jstl-api. That's what a API means: Application Programming Interface. Best regards.
What is the proper way to make java reusable components that is capable of used in various applications. I mean for example I'm doing a application that has its own user interface and database and etc. If I want to make this app reusable for many other applications as a component of other applications. For example one feature of my first app may needed by other app. So how to make it possible for other apps to use this feature of my app without changing my original code. What are the proper ways to achieve this re usability.
Write something simple which does what it does very well. Document it and unit test it and make it open source.
Have the the reusable components in another project (e.g. "common") and package them as .jar. Then include that jar in the projects where it's needed.
Extracting a separate project might be tricky though. You should observer the following:
the common components should not be dependent on anything in the higher level of abstraction (i.e. you services must not have any UI-related dependencies)
the internals of the components must not be visible to the application using them. I.e. your jar should expose a minimum API.
You have a couple of options for the mechanics of packaging:
simple IDE-dependant packaging - declare a inter-project dependency. On build export the jar and put on the classpath of the client application
Maven/Ivy - install the dependency in a repository (local or remote) and use the dependency resolution mechanisms of maven/ivy
This is a rather broad question. As such, I am offering broad suggestions:
Know your OO basics. Inheritance, encapsulation, polymorphism. It gets crazier from there on out.
Learn about design patterns, start observing them in applications you already use.
Look at popular open libraries to see how they implement patterns and modules.
Try things in sandbox projects. Grow your knowledge in clean environments.
Since you mention Java, check out the Spring Framework.
Hope that helps.
You need code in such a way that your components are loosely coupled. Then the re-usability is very much high. Take a look at this and this.
Sun Microsystems, the creators of the Java language, have at last recognized this need, and have released the Java Beans Component Architecture. Java Beans are, quite simply, reusable controls written in Java, for Java application development.
Beans are "capsules" of code, each designed for a specific purpose. The advantage of Java Beans over standard programming controls is that Beans are independent. They are not specific to operating systems or development environments. A Bean created in one development environment can be easily copied and modified by another. This allows Java Beans greater flexibility in enterprise computing, as components are easily shared between developers.
It looks like GAE has chosen a subset of JDK 1.6 classes, as per:
Google App Engine JDK white list
which is very unfortunate as one gets class linkage errors all over the place with most common java libraries that deal with data binding, reflection, class loading and annotations. Although some omissions may be for deprecated or legacy things, there are others that are not. My specific concern is with streaming pull parsers (javax.xml.stream.*) which was just added to JDK 1.6 after a long delay (API was finalized at about same time as JDK 1.4). Omitting this makes it harder to do scalable high-performance xml processing.
Problem as I understand is that not only are classes missing, but they can not even be added because of security constraints.
So: this is an open-ended philosophical question that probably just GAE devs could answer for sure but... why are some APIs dropped from standard JDK 1.6, seemingly arbitrarily?
UPDATE:
Quick note: thanks for answers. For what it's worth I really do not see how security would have anything to do with not including javax.xml.stream.
Security aspects are relevant for great many other things (and I don't need threads, for example, and can see why they are out), so it's understandable boilerplate answer; just not applicable for this one.
Stax API is just a set of interfaces and abstract for crying out loud. But more importantly, it has exactly the same ramifications as including SAX, DOM and JAXP interfaces -- which are included already!
But it looks like this issue has been brought to attention of google devs:
discussion on whitelisting Stax API
so here's hoping that this and similar issues can be resolved swiftly.
GAE is run in a hosted environment with untrusted (and potentially malicious) clients, who often are given access for free.
In that type of environment, security is a very high concern, and APIs which have filesystem access get very heavy scrutiny. I think thats why they've chosen to start pretty conservatively in terms of what they allow.
It wouldn't surprise me at all if more classes find their way into the whitelist as security issues are addressed (and based on demand), though.
But I wouldn't even expect to get threading tools available, eg.
It's extremely doubtful that these things were dropped arbitrarily. GAE runs in an extremely security-sensitive environment, and the chances are good that an internal audit of the class libraries found some risks that Google was not willing to take.
As for your high-performance streaming XML parsers, you could try to find an appropriate library (jar file). Unless it relies on threads or file access (or black-listed API), it should work just as well as the one in the JDK.
There are a lot of (rather complex) libraries that work on GAE.