5

I have a Spring Framework project which uses Maven for resolving dependencies. The project has a dependency to another Spring project (Spring Social Facebook), which is used for Facebook login. Suddenly, I started to get a lot of errors because the Facebook login functionality broke due to changes in the Facebook API. The solution is extremely simple but requires a minor change within the external library's files - changing a variable from the type integer to long.

Now I know the solution, but I don't have control over this library. I would like to fix this problem myself until the library is updated with the fix, rather than waiting around for days with a broken system.

My question is: is there any easy way in which I can make a change to the source code of this library until a fix is available in the library itself? What is the recommended way of doing this? Two things currently come to mind: forking the library, make the change, and create a private Maven repository and replace the dependency with one that uses the private repository. If I can, I'd like to avoid that. The other way I can think of, would be to fork the library, make the change, compile the updated library into a jar file and replace the Maven dependency to use the jar file.

Is there a better way? What would you recommend in a (temporary) scenario like this? Thanks!

kamwo
  • 1,980
  • 1
  • 23
  • 32
ba0708
  • 10,180
  • 13
  • 67
  • 99
  • I find your option 1 the best way to do that. I don't think changing the already downloaded jar is a good idea: using a new jar with new coordinates sounds better. It also gives a clearer intent: you can name it `this-library-is-broken-I-fixed-it` and everyone will understand right there why you did it ;). – Tunaki Dec 06 '15 at 19:36
  • 2
    Not an answer, and perhaps obvious, but: don't forget to contribute your patch back to the original project! – Jeen Broekstra Dec 06 '15 at 20:03
  • I posted a workaround on another thread: http://stackoverflow.com/a/34133450/1943228. The workaround allows you to use the facebook library as it is, but it changes some parts of the `Spring Social Facebook`API by the use of reflections. You do not need to compile your own version of the library. For the time beeing there is no new release. – kamwo Dec 09 '15 at 11:35
  • 1
    @kamwo Actually, that's the solution I ended up using (found it on GitHub) because it was the fastest one for me, but I'm happy to still have received answers that I can use in the future for other problems. Thanks for your solution, it worked smoothly for me! :-) – ba0708 Dec 09 '15 at 16:36

2 Answers2

4

From working experience, in more than one company I have seen the following approach:

  • Fix the issue in the source code
  • Package it again with the same Maven coordinates
  • Add a classifier, which was usually companyname-patch(ed)
  • Put it in the enterprise Maven repository (i.e. Artifactory or Nexus)

As such, you would move from

<dependency>
  <groupId>junit</groupId>
  <artifactId>junit</artifactId>
  <version>4.7</version>
</dependency>

To

<dependency>
  <groupId>junit</groupId>
  <artifactId>junit</artifactId>
  <version>4.7</version>
  <classifier>company-patch</classifier>
</dependency>

This would help you to keep more traceability:

  • The classifier makes it clear to internal developers and also to contractors that this is a company patch
  • You know exactly to which library and which version the patch was applied (hence, partially self-documenting)

Furthermore, it is actually a legal and good usage of the Maven classifier feature.

Reusing the same Maven coordinates may affect portability (I have a different behavior on my local machine, why?) and maintainability (let's update this library, ops.. it was the patched one, I didn't know), while creating new Maven coordinates may create misunderstanding (what's this library?) and errors (I will replace by this official one, ops.. It doesn't work anymore).

A_Di-Matteo
  • 26,902
  • 7
  • 94
  • 128
  • Thank you for your answer! That makes sense. However, could you please elaborate on the part with putting it in an "enterprise repository"? I actually haven't heard of that/those, so I am not familiar with that. My thought would be to add it to a private repository, but that was mostly because I was unsure if it was okay to publish it to a repository that was publicly available. Is the part about "enterprise repositories" basically just a recommendation so that others can benefit from the fix as well (in that case, I agree), or is there something that I am missing? Thanks a lot! – ba0708 Dec 07 '15 at 16:22
  • An enterprise Maven repository is well explained on the official Maven page, https://maven.apache.org/repository-management.html (I updated the answer with this link). It's actually a good practice in big companies to use it as a proxy for public repositories (saving bandwidth, adding a layer of centralization, governance) and also the best place where to put company's private libraries and/or a company common parent POM. Hence, yes, as you guessed, it's to make it available to your colleagues. If instead it's about a private project, then local cache or public repository may be an option. – A_Di-Matteo Dec 07 '15 at 20:00
  • How to use same maven coordinates to package the source code with the change? Thanks – Diego Ramos Aug 19 '22 at 23:25
0

The latest Spring Facebook integration lib was released in August:

<dependency>
  <groupId>org.springframework.social</groupId>
  <artifactId>spring-social-facebook</artifactId>
  <version>2.0.2.RELEASE</version>
</dependency>

Since August there were only some minor changes introduced in their API, and it is highly unlikely that this would have broken their API compatibility with thousands of existing applications.

There are literally thousands of applications connected to Facebook, so Facebook would not (cannot really) allow itself to introduce breaking changes in their API. They have an elaborate versioning system with fallbacks and backwards compatibility etc. in order to protect existing integrations.

I understand that you believe you have found a possible fix for the library. What I suggest doing instead is looking into the code which leads to that specific scenario. It is much more likely that some subtle change in the way your code uses the lib leads to this "bug", rather than Facebook making such a mistake.

Heinrich Filter
  • 5,760
  • 1
  • 33
  • 34
Gergely Bacso
  • 14,243
  • 2
  • 44
  • 64
  • I haven't looked deeply into what changed, but have focused on finding a solution for now. However, I have not changed the version of this library, and this error began to appear by itself. The specific issue is discussed here: https://github.com/spring-projects/spring-social-facebook/issues/181 – ba0708 Dec 06 '15 at 23:29
  • The problem is, that the Jackson mapper tries to map a `long` value into an `integer` field and fails. This was caused, because facebook increased the `video_upload_limit`, which surpasses the range of an ìnteger`. For more info: http://stackoverflow.com/a/34131434/1943228 – kamwo Dec 09 '15 at 11:43