Which is the best way you think to use Guava? Since, in the web site, the guys say that the interfaces are subject to change till they release 1.0. Taking this into account, the code you write shouldn't depend directly on those interfaces, so, are you wrapping all the Guava code you call into some kind of layer or facade in our projects in order to, if those interfaces change, then you at least have those changes centralized in one place?
Which is the best way to go? I am really interested in starting using it but I have that question hitting my mind hahah :)
I'm not sure where you're getting that about the interfaces being subject to change until version 1.0. That was true with Google Collections, Guava's predecessor, but that has had its 1.0 release and is now a part of Guava. Additionally, nothing that was part of Google Collections will be changed in a way that could break code.
Guava itself doesn't even use a release system with a concept of "1.0". It just does releases, labeled "r05", "r06" and so on. All APIs in Guava are effectively frozen unless they are marked with the #Beta annotation. If #Beta is on a class or interface, anything in that class is subject to change. If a class isn't annotated with it, but some methods in the class are, those specific methods are subject to change.
Note that even with the #Beta APIs, the functionality they provide will very likely not be removed completely... at most they'll probably just change how that functionality is provided. Additionally, I believe they're deprecating the original form of any #Beta API they change for 1 release before removing it completely, giving you time to see that it's changed and update to the new form of that API. #Beta also doesn't mean that a class or method isn't well-tested or suitable for production use.
Finally, this shouldn't be much of an issue if you're working on an application that uses Guava. It should be easy enough to update to a new version whenever, just making changes here and there if any #Beta APIs you were using changed. It's people writing libraries that use Guava who really need to avoid using #Beta APIs, as using one could create a situation where you're unable to switch to a newer version of Guava in your application OR use another library that uses a newer version because it would break code in the older library that depends on a changed/removed beta API.
Related
I have stumbled upon Hashing class from com.google.common.hash package.
Intellij IDEA shows following warning if I am using functions of that class:
The class itself is annotated with #Beta annotation:
The description of #Beta annotation says:
Signifies that a public API (public class, method or field) is subject to incompatible changes, or even removal, in a future release. An API bearing this annotation is exempt from any compatibility guarantees made by its containing library. Note that the presence of this annotation implies nothing about the quality or performance of the API ...
So the implementation of the API is fine and stable?
... in question, only the fact that it is not "API-frozen."
It is generally safe for applications to depend on beta APIs, at the cost of some extra work ...
Which kind of extra work?
... during upgrades. However it is generally inadvisable for libraries (which get included on users' CLASSPATHs, outside the library developers' control) to do so.
The question is whether it is safe / stable to use mentioned class and its functionality? What is the tradeoff while using a beta API?
The implementaion of the API is fine, you can rely on that since it is an extensively used library from google.
As for stability - you can do a little research here and compare a couple of versions of this API a year apart. Let's say, 23.0 versus 27.0-jre
https://google.github.io/guava/releases/23.0/api/docs/com/google/common/hash/Hashing.html
https://google.github.io/guava/releases/27.0-jre/api/docs/com/google/common/hash/Hashing.html
If you do a diff, the API's from different years (2017 versus 2018) are exactly the same.
Therefore, I would interpret the #Beta here as a heads-up that "be aware, this API may change in future", but in practise the API is both stable, reliable and heavily used.
Maybe at some point, the google developers may choose to remove the #Beta annotation. Or maybe they intend to, or have forgotten (speculative...)
The "extra work" referred to means that, if you build an application using this API, you may need to refactor your application slightly (imagine that a method signiture changes, or a method becomes deprecated and replaced) if you need to upgrade to the newest version of this API.
The degree of work there depends on how heavily and how often you use the API, and how deep the dependency on that API is (transitively, through other libraries, for example - those would also need to be rebuilt).
In summary, in this case - "dont worry, move along" :)
So the implementation of the API is fine and stable?
No way to know from this annotation.
To answer that you need to know how widely used it is, and for how long.
Which kind of extra work?
The kind of extra work that you have to do when a method that required only 1 parameter and returned String now requires 3 parameters, and returns a List<String>.
i.e.: Code that uses this API might need to change due to API change.
So the implementation of the API is fine and stable?
The quoted text says that the API is "subject to incompatible changes". That means that it (the API) is not stable.
Note also that the quoted text explicitly states that the annotation is saying nothing about whether or not the API's implementation works.
But also note that this is not a yes / no issue. It is actually a yes / no / maybe issue. Some questions don't have answers.
Which kind of extra work?
Rewriting some of your code ... if the API changes.
The question is whether it is safe / stable to use mentioned class and its functionality?
This requires the ability to predict the future. It is unanswerable. (Unless you ask the people who put that annotation on that API. They may be able to make a reliable prediction ...)
It is also unanswerable because it depends on what you mean by safe, and what context you intend to use the Hashing class in.
What is the tradeoff while using a beta API?
The tradeoff is self evident:
On the plus side, you get to use new API functionality that may be beneficial to your application in the long run. (And if there is no evidence that it may be beneficial, this whole discussion is moot!)
On the minus side, you may have to rewrite some of your code if the authors modify the API ... as they say they might do.
I am working with Java 8 mainly, but meanwhile also creating a library that uses Java 6, such that other people can use it as well in the future, as it is quite interesting.
The problem I have now is that I could very easily solve some issue by using Java 8's Predicate<T>, however I am unsure how to backport it.
I see the following options available, but they either have issues or I'm unsure how to use them:
Use Google Guava's Predicate<T>, this however introduces a relatively big dependency where I do not really need it, also when a Java 8 user wants to use Predicate, then Google Guava's import for the Predicate class shows up.
Use my own Predicate<T>, no big dependency, still the same issues as mentioned above.
Use a custom name like TessPredicate<T>, as Tess will be relevant name in my project, does not feel that nice either.
Use a name that makes sense in the project setting, such as (tentative) RegexVerficationPredicate, as it is a predicate in addition to using a regular expression, such that you can also do calculations on the elements. Bank codes, etc. usually have some checksum that you need to compute. Implemented as functional interface, this might be most feasible?
Backport java.util.function from Java 8 to Java 6, is this even possible?
How can I solve this?
You can’t backport the java.util.function package due to the heavy use of default and static methods within these interfaces. Such a backport would look quite different.
I recommend creating your own Predicate<T> interface being as minimal as possible, i.e. having that single abstract method with the same signature as the Java 8 Predicate<T>. Having the same interface name and method signature like the well-known acts like a self-documentation.
This implies that programmers using Java 8 can still implement your predicate using a lambda expression or method reference (without even importing your interface). And using a Java 8 predicate is as easy as passing predicate::test to your method.
Adding a dependency to an entire 3rd party library just for one interface looks nasty to me.
I'd recommend use of Guava. When I first used it, I was thinking the same way (too big dependency) then over time I started to use other features provided by guava and now I dont understand how do I do without them (those are my must have tools right now), code is clearer, faster and easily maintainable.
The fact that java SDK (especially java 8) is taking lot of features from Guava tells a lot... thus even tough you can write your own implementation, in a long term use of the library is more preferable...
since version 10 guava offers com.google.common.eventbus.EventBus - a generic pub-sub facility. It is not marked as GWT-compatible in the source. I wonder whether it's possible to plug some custom code pre-processing into gwt compiler to map this (partially annotation/reflection-based) API into javascript.
AFAIK there're some other custom extensions added into GWT java-to-js compiler, like com.google.gwt.i18n.client.ConstantsWithLookup and quite likely some others. I'd seen some experimental compiler extensions to add partial support for reflection/annotations, but not sure they're required in case we handle a specific set of annotations and simple class->methods->annotation listing is required (not a complete reflection API).
Maybe someone knows whether GWT-enabling this component is planned by guava dev team?
Thanks,
Anton
This is probably more appropriate for guava-discuss than for StackOverflow, but Guava team member here: no, we're not planning on it.
simply already working (GWT server+client compatible) with this one: http://www.gwtproject.org/javadoc/latest/com/google/gwt/event/shared/EventBus.html
and here (Tutorial): http://www.gwtproject.org/articles/mvp-architecture.html#events
(answered also here: https://stackoverflow.com/a/28082823/1915920)
I have the following scenario: I am using a very big external library in my Eclipse RCP application for a specific purpose.
At this point in time I am not sure if I may not have to replace this library in the future to another one (because it does not provide the necessary functionality or something like that). Also I have users using this library from day one so I would like to encapsulate the library, giving me at least a chance of changing the library in the future without the user noticing or having to change anything in their code.
Is there a simple way to encapsulate a whole library in some automated fashion?
Unless the part of the library's interface you are actually using is completely trivial, or standardized the way JSF or JAX-B are (in which case you don't need encapsulation) this is a completely wasted effort.
I can guarantee that if you have to switch to a different library, the encapsulation would prove worthless because the other library has different underlying concepts and usage patters that cannot be made to fit the existing ones.
I don't think that's possible, since the syntax and semantics of the library might be unique to some extent.
Sure, you could create proxies for all the classes and provide those, but that might require quite some work (writing a framework that scans the library) and that wouldn't guarantee you that exchanging the library would be easy.
Imagine the replacement would provide different methods and even use different semantics (to some extent). What if methods/fields etc. were missing in the replacement?
The best way to handle that would be to write an explicit wrapper and make the users use only that wrapper. This way you could restrict the API to the core concepts that are really needed. This still might not provide a good enough encapsulation however, based on what the library actually does.
Example:
For 3D programming you could use OpenGL or Direct3D. Both have somewhat different APIs but use the same core concepts. Thus you could create a wrapper for them that provides a unified API. That wrapper might then have to convert some data etc. (like making column-oriented matrics row-oriented and vice versa) but since the core concepts are the same, that should be doable.
However, you'd need to stick to the core concepts and couldn't use additional features. For example, Direct3D would also provide some more highlevel API (Direct3DX) which isn't provided by OpenGL.
Do any problems arise because of using deprecated functions in Java?? If so, why do they keep this function?? Is it a bad habit if you use a deprecated method in Java like
java.sql.Date.getMonth or getYear or getDate???
Some potential problems are:
Methods may cease to exist (this has never been the case in practice, but by the official definition, deprecated methods may be eliminated from future Java)
Serious programming errors may occur due to fatal flaws in deprecated methods (e.g. System.runFinalizersOnExit and its evil twin Runtime.runFinalizersOnExit)
Data corruption can occur due to inherently unsafe deprecated methods (e.g. Thread.stop)
References
java.sun.com Glossary
deprecation: Refers to a class, interface, constructor, method or field that is no longer recommended, and may cease to exist in a future version.
Language guide/How and When to Deprecate APIs
Annotation Type Deprecated API
Related questions
Is it wrong to use Deprecated methods or classes in Java?
Difference between a Deprecated and Legacy API?
No methods have actually been removed yet so existing code will keep running. Sun has been very focused on backward compatability.
The primary benefit is to move away from code that for some reason has been found to work suboptimallly, and usually there is a replacement elsewhere in the runtime library. Hence it is a bad habit to use them, and you should take heed and use the recommended replacements whenever the compiler flags a deprecation. It is generally a good idea to aim to eliminate compiler warnings.
You can see a list of what is deprecated in the Javadocs. The Java 5 list is at http://download.oracle.com/javase/1.5.0/docs/api/deprecated-list.html
Deprecated methods are kept so that code written for a previous version of Java still functions. If they just removed the code then previously functioning code would stop working when you updated Java to a new release.
Using deprecated functions will not cause you any problems beyond that which caused the method to be deprecated. However, it is best to find out what has replaced the deprecated method. The deprecated functionality will have been replaced with new functionality possibly found in a new class. Much of the deprecated Date functionality has been moved to Calendar. Check the Javadoc for the to see the recommended replacement.
The code may break in the future...
deprecated functions are a warning that this function will go away.
Look for alternative ways to fix the problem now, or you will
have the code break in the future.
A deprecated class or method might get removed in a future version. Sun had the habit of deprecating stuff and never actually removing it which in my opinion is not so good because it makes it seem Ok to use deprecated methods. Still you should not use deprecated methods where possible (and it should always be possible). This goes especially for external libraries which imho generally are not as afraid as Sun to remove deprecated code.
As others have pointed out, Sun has never removed any deprecated methods from the JDK, but the same is not true with deprecated methods in third-party libraries. Those do disappear sometimes (the Lucene project for example has a rather "fluid" API here, doing major cleanups with major versionups).
Even in the JDK, the method being deprecated means that "there is a better way to do this now", and you should probably update your code to use the new version.
It is very rare that the deprecated method does not work correctly for what it was originally intended to do, but the replacement will usually work more reliable, or in more circumstances, or in a more general way. Good examples here are the Date functions that you mention (deprecated because they do not work well with different locales/calendars), or String-to-byte conversions that only work with 7-bit-ASCII. These caveats/restrictions cannot be fixed without a new interface, or because someone may depend on the "broken" implementation, so instead of updating the method, they deprecate it and provide an alternative one.