Baruch Sadogursky's complete blog can be found at: blog.sadogursky.com

Items:   1 to 5 of 15   Next »

Wednesday, June 5, 2013

Reblogged from Blog @Bintray:

Click to visit the original post
  • Click to visit the original post
  • Click to visit the original post
  • Click to visit the original post
  • Click to visit the original post
  • Click to visit the original post
  • Click to visit the original post
  • Click to visit the original post

First things first - Bintray is not a competitor of GitHub. They complete each other, not compete. Here's how (I love vienn diagrams):

Bintray is an organic next step for developing software at GitHub - once your sources are built - distribute them from Bintray.
Our job is to make it as easy as possible for you, our fellow GitHubber. Here's what you get:

Read more… 327 more words


Thursday, May 31, 2012

During the last couple of years, continuous integration (CI) and automated release management methodologies have become much stronger in non-Java builds.

Number of familiar tools are used for these methodologies, like the version control system to manages your sources, your build tool to actually build your software from sources and  your build server, which builds your software continuously using the build tool. But is there something else missing? Let’s look at a simple diagram, which describes your CI process:

  1. Developers fetch needed dependencies (3rd party libraries, other modules).
  2. Developers write new code.
  3. Code is committed to VCS.
  4. Build server polls VCS for changes.
  5. Once discovered, the build server builds the software: compiles it, runs tests, and assembles artifacts.
  6. Built artifacts are published to QA, staging, or even directly to the end users.

As you can see, everything except stages 1 and 6 is well known and familiar. But what about those two stages? You need a dependency management mechanism for them.

In this post, we’ll illustrate the options for automated builds with dependency management in non-Java builds or when not using .NET with NuGet (use it, if you can! Here’s our take about it). The proposed solution works for any kind of build, be it C, C++, C#, iOS and Objective C, Python, or whatever.

So, let’s see how you can implement CI with dependency management for non-Java projects. Here are the options with their pros and cons:

# Solution Pros Cons
1 Dependencies in VCS
  • Use proven build tools
  • Simple setup – you use VCS anyhow
  • VCS won’t fit for binary dependencies. You can read why here.
2 Build tools with built-in dependency management like Maven and Gradle
  • Build tool with dependency management
  • New tool to learn. Both Maven 2 and Gradle have a pretty steep learning curve.
  • “Adapted” from Java. While there are ways to build “native” applications with them (easier with Gradle, harder with Maven) it still feels, let’s say, artificial, imposing their new conventions.
3
Declare dependencies on builds in your build server
  • Use proven build tools
  • Only works for inter-project dependencies (which were built by the same build server)
  • Not flexible enough
    • Includes/excludes
    • Layout changes
4
Use shared dependencies storage, a.k.a. “repository” (FTP, file server, etc.)
  • Use proven build tools
  • Manual repository populating
  • Managing the repository

As you can see, none of the solutions are without the cons.

Here comes Artifactory

Artifactory is  a binary repository – built with binaries management in mind in terms of versioning, management, security, and build servers integration.
As such, using Artifactory completely eliminates the cons of the fourth solution. Your build can populate the repository using powerful REST API. Management is easy and streamlined.
But there’s more. By using Artifactory CI integration (for Jenkins, TeamCity and Bamboo), you can also avoid the cons of the third solution listed above. First, you can specify which artifacts you are willing to publish. They will be uploaded to Artifactory in the end of the build. Second, you can specify which dependencies your build needs. They will be downloaded from Artifactory during the run. All this simply by using build server UI.
The Artifactory Jenkins plugin, for example, defines as part of the Generic build support, a simple pattern-based language that allows you to express what artifacts from the build are going to be deployed to the repository. This includes attaching dynamic searchable properties to these artifacts upon deployment.
First, enable Generic-Artifactory Integration in the Build Environment:

Next, configure your custom deployment and resolution rules. Let’s start with deployment (publishing):

In the above example, we configured the following rules for deployment. All the artifacts will be deployed from the working directory into the ‘libs-release-local’ repository (configured above), maintaining the path for each file:

Pattern Meaning
**/x64/*.dll=>x64Win Deploys all DLLs to the ‘x64Win’ directory
**/*.zip=>winFiles Deploys all zip files to the winFiles directory
unix/*.tgz Deploys all tgz files under the unix directory to the root directory of the target repository

The plugin also controls which artifacts to resolve from the repository before the build starts. The resolution allows you to specify smart search patterns:

In the above example, we configured the following rules for dependencies resolution

Pattern Meaning
libs-release-local:x64Wi/*;compatibilityLevel =medium,high Resolves the files from the x64Wi directory of the libs-release-local repository to the root of the workspace, but only if the ‘compatibilityLevel’ property is set to be above medium
libs-snapshot-local:*.zip=>winFiles Resolves all zip files from libs-snapshot-local repository to winFiles directory under the root of the workspace
libs-snapshot-local:unix/distro.tgz=>linuxFiles Resolves the distro.tgz file from unix directory in libs-snapshot-local to linuxFiles directory under the root of the workspace
libs-release-local:**/*@winx64_build#released This example shows dependency to artifacts produced during an earlier build that has been marked with a “released” status

From a configuration standpoint, this support for automatic dependency declaration and publishing makes it very easy to support a release flow where multiple artifacts are collected towards building the final release
.
You are more than welcome to give it a try. The publishing functionality described above is available in the free open source version of Artifactory. If you want to configure dependencies resolution, go ahead and download the Pro version evaluation.
Dependency management is critical for continuous integration and rapid release. By adding Artifactory to your CI stack, you can easily overcome the lack of such functionality in your build tool, leaving the dependency resolution and artifacts deployment to the binary repository and your build server.

Resolves the distro.tgz file from unix directory in libs-snapshot-local to linuxFiles directory under the root of the workspace


Filed under: Artifactory, JFrog Tagged: .net, artifactory, best practices, build, c, continuous integration, iOS, jenkins, native, objective C, Pyhton

Monday, May 21, 2012

Disclaimer: The code samples in the post below are for brain teasing only. Do not, I repeat, do not ever do such things for any other purpose!

A friend of mine is a big fan of puzzlers. Any puzzlers, including programming ones. Here’s his latest and greatest:

Write some code in the static initializer to make the assert pass:

public class Test {
 static {
//Write some code here
 }

public static void main(String[] args) {
 Integer a = 20;
 Integer b = 20;
 assert (a + b == 60);
 }
}

Don’t forget to enable assertions if you want to solve this one (-ea as VM parameter).

If you solved it, or don’t feel like puzzlers, read on for the solution and the punchline.

First, the solution: You need to know refection and two facts about Integers to solve this one:

  1. Integers have cache for all values in range -128 to 127.
  2. Integers use that cache during auto-boxing (as opposite to using Integer’s constructor, for example).

Well, you also need to know the exact implementation of the Integer class to figure out where the cache is and what’s the name, but rt.jar sources are here for the rescue. Guess what? the cache is a private variable inside a private inner class. Joy-joy.

Here’s the plan:

  1. Get Integer’s class object.
  2. Get the list of its inner classes.
  3. Find the right one (what a relief, it only has one. Or not – it is subject to change in future versions since we are digging in highly encapsulated stuff . Duh.)
  4. Get the cache field from it.
  5. It’s private, set it to accessible in order to get the value of the field.
  6. Change the value of “20″ to be “30″

Here’s the code of the static initializer:

 static {
try {
 Class<?>[] declaredClasses = Integer.class.getDeclaredClasses();
 Field cacheField = declaredClasses[0].getDeclaredField("cache");
 cacheField.setAccessible(true);
 ((Integer[]) cacheField.get(null))[20 + 128] = 30;
 } catch (Exception e) { e.printStackTrace(); }
 }

Personally, I hate it. It’s ugly, it messes with very low-level encapuslated stuff that one even doesn’t suppose to know, and it is fragile (e.g. it won’t work if Integer is created with constructor).

And fairly, we just got lucky. If Integers did not have the cache then we would not  have any way to change what “+” does!

So, why this simple trick is so difficult to impossible to implement? Simple – Java is not intended for those tricks. Java is static, and it is good! It means that you can rely on it. 20+20 will (almost always) be 40. That is Good.

If you want to do dynamic stuff, like changing the behavior of  a “+” operator, you’d better use the right tool for the job. E.g. – Groovy.

Here’s the Groovy version of the puzzler:

//Write some code here
Integer a = 20
Integer b = 20
assert 60 == a + b

Looks almost the same (without the main() mess, some ridiculous semicolons and the need to include -ea in VM parameters), but the difference in the way to achieve the desired is huge. Since Groovy is dynamic it is intended to do stuff like changing the behavior of the plus sign. Here’s the facts about Groovy that you need to know to solve this one:

  1. Groovy operates with wrappers, always.
  2. Groovy implements operators though methods. “+” is implemented in plus() method.
  3. Using Groovy’s MetaClasses you can easily replace method with any closure.

Here’s the plan:

  1. Get Integer’s MetaClass.
  2. Replace plus() method with implementation that returns 60.

That’s all. Really. Here’s the code:

Integer.metaClass.plus = {int i -> 60 }

Nuff said. Now you only have 2 options. Stop doing those ugly tricks, or at least do it with the right tools for the job.


Filed under: Development Tagged: groovy, java, metaClass, reflection

Friday, March 16, 2012

This post was originally posted on ‘From the Frog’s Mouth‘.
You’re welcome to comment here or there.

It was JFrog‘s second QCon London, and it just gets better. Imagine: even the London weather was perfect, not to mention the sessions, booth traffic, show organization and food (what, you say, good English food? Well, great IndoPak food, at least). Due to high demand by sponsors, the exhibition took place on two floors (as opposed to one floor last year). Our JFrog booth was located in the same place as in 2011. We’re getting used to the place and are looking forward to returning next March!

The speaker panel was extremely impressive, featuring gurus like Martin Fowler, Adrian Cockcroft (the man behind Netflix’ cloud), Dwight Merriman (co-creator of MongoDB), Damien Katz (creator of CouchDB) and Rich Hickey (creator of Clojure).

The conference started with two training days – six full-day tutorials each. From my perspective, the most interesting two tutorials were “Cloud Architecture” by Adrian Cockcroft, where he shared the architecture, best practices and decisions behind Netflix’ cloud (which Artifactory is proud to be a part of) and “Continuous Delivery” by ThoughtWorks’ Tom Sulston (that’s as close to the roots of the famous “Continuous Delivery” book as you can get). For me, the most fascinating thing in the Continuous Delivery process as ThoughtWorks sees it, is that its virtues are exactly the same as we based our Artifactory upon back in 2006: DevOps automation and rapid release cycle. We appreciated the validation of our concept.

The remaining three days of the week were all-day sessions. It’s impossible to review such a significant number of talks in one blog post, so I’ll concentrate only on the excellent keynote addresses (with one exception).

Martin’s conference-opening keynote speech was about data. The main feature of modern data is that it is bigger than you think. Polyglot storage in general and various kinds of NoSQL look like the right solution.

My favorite keynotes are usually the evening ones. A beer in your hand makes any amusing talk even more enjoyable. One named “Developers Have a Mental Disorder” I couldn’t miss! Greg Young gave a great show, funny and entertaining, about serious dilemmas in software development that we, the developers, prefer to ignore. The brightest example, of course is the downside of DRY (did you ever think about one?). By removing duplication, we increase coupling, which can be much worse.

Thursday morning’s keynote address was delivered by Rich Hickey. He spoke about the differences between “Simple” and “Easy”. Sounds pretty similar, but in fact they are very far from being the same. Antonyms to the rescue: simple vs. complex, while easy vs. hard. Now it’s clear – we need to strive to prevent and remove complexity (go simple) without being afraid of the hard. Choosing easiness may end up creating complexity. Things which are easy, but complex, include OOP, mutable state, imperative loops and frameworks (especially ORM). Things which are simple, but not necessarily easy (at least not until you get them), are LISP-ish languages, like Clojure.

My session also took place on Thursday, in relatively small room, about 70 people. I was more than happy to see that it was almost packed. I spoke about building trust in your build process by selecting the right tools for the job (of course, we consider Artifactory as one). I also spoke about the problems of DevOps in the word of Continuous Delivery in the cloud and the rapid release cycle of SaaS applications. I stressed the huge timeshare of binaries in ALM process and the importance of using a tool that really understands binaries to deal with them. That’s exactly the reason why we developed Artifactory.

Half of my session was dedicated to live demos, which went smoothly, incredible as it may sound. According to the feedback received, my talk was well accepted, and hopefully will be useful to some of the attendants for building easier and more reliable release processes. The Q&A session continued at our booth, where we repeatedly did live demonstrations and received excellent feedback each time. If you want to get a feeling of my talk, here’s the slide-deck.

Friday was the last day of the conference. It started hard with a highly technical keynote address by John Allspaw with a scary name: “Resilient Response In Complex Systems”. For someone like me, who doesn’t deal on a daily basis with Disaster Recovery, the session was astonishing. Looking behind the curtain of that kitchen reveals a totally different way of thinking and planning. It may be how individuals and teams have to perform during a disaster (e.g. personal heroism is bad even if successful; it sends the wrong message to the team), or simulating disasters on live production systems (I never could even dare to think about that). The most obvious, but still eye-opening advice that John gave is to learn from successes, not only from failures. It can give us a lot of information and happens much more frequently, no? The only organization with which I am familiar that embraces that technique is the Israeli Air Force.

To sum up, the conference was great by every measure: technical sessions, attendance, networking, Artifactory exposure, and after-show quality time. Thank you, InfoQ, for this wonderful event in London. QCon was a great starting shot for JFrog’s “Busy March”. You still can catch Fredric and Yoav giving talks on various events in US and Europe.


Filed under: Artifactory, Confereneces, JFrog Tagged: artifactory, Conferences, jfrog, QCon

Monday, February 6, 2012

This post was originally posted on ‘From the Frog’s Mouth‘.
You’re welcome to comment here or there.

The problem of dependency management is neither new nor original, it exists in all development platforms, and .NET is no different.

Let’s go through different solutions and see how they perform. I’ll list them here in no particular order.

Keeping dependencies in your source control

That’s a very popular solution, and for a reason. The benefits are obvious. Here are some of them:

  • No setup. You already have your source control in place (hm, I hope you do!). Add \bin directory, and you are fine.
  • No learning curve. Developers are used to work with source control.
  • Shared. The whole team gets changes and updates from the server as they occur.
  • Enterprisy (in a good way). The software is proven, backed up, DRP is done.

Sounds good, doesn’t it? So, what’s wrong with it? Only one thing – source control systems are designed to control, well, sources. As such they aren’t so great in controlling binaries. These are the shortcomings we all encountered during the years of Version Control System usage for dependencies:

  • It isn’t a proxy. VCS can’t download the dependency you need from a central repository when you need one. You need to manually download it and add it to VCS. The history starts from there – you just lost the  link to the original file. So, you work hard, and on top of it lost information; this repeat itself for each new dependency.
  • Versioning mismatch. Source files are versioned by their content. VCSs know how to diff them and understand what changed. Binaries, on the other side, usually versioned by their name. From VCS point of view they are different entries, each one without any version history.
  • Some very popular VCSs (like Subversion) can’t obliterate files. That means – once a file was added, it stay in the repository forever. That’s not a big issue for small source files, but can become quite a pain when it comes to obsolete large binaries.
  • Source control knows how to search sources. And, of course, the most important type of search is by content. Searching for binaries is different: what matters there is the location, structure of the file name and, in case of archived artifact, the contents of archive.
  • The permissions scheme of VCSs is tailored for versioning sources (again!). For example, there is no override permission. That’s because overriding sources is something we do all the time (that’s what diff is for in VCS) – it’s the same security level as, let’s say, adding a new source file. With binaries the situation is very different. While adding new binaries is fine, overriding released binary is something that shouldn’t be done, one should have a special permission for it.
  • Distributed VCSs, awesome by themselves, are particularly unsuited for handling big binary files. When cloning a remote repository to your machine you are bringing all the history of all the files in it. Now just think about all the huge binaries sitting there…

As you see, the conclusion is simple – we can do better. Let’s try something specialized for binaries.

GAC and WebGAC

Global Assembly Cache is, on contradictory to VCS ,tailored for storing binaries. It understands versions, prevents conflicts, and generally does a good job being your local dependencies storage. The main problem with GAC is being local, which means – each and every developer should take the binaries from somewhere and install them in their local GAC. You see the troubles coming in that setup, don’t you? WebGAC to the rescue here. It’s essentially GAC shared by WebDAV and enables clients to fetch dependencies from the server, simplifying dependencies management for a team. Let’s do our pros/cons math. The benefits:

  • GAC is good, standard and proven solution for binaries management. It deals well with versions.
  • WebGAC is a central binaries repository for a team. Every team member synchronizes with it.
  • WebDAV is popular well-known HTTP extension with locking, security management, etc. Working with the Apache WebDAV module is generally straightforward.

Let’s see what won’t work so great with that solution:

  • It isn’t a proxy. WebGAC can’t download the dependency you need from a central repository when you need one. You need to manually download it, add it to WebGAC and only then it becomes available to the team. Not only must you work for every version of every dependency needed, the link to the original file is lost.
  • No notion of packages. GAC contains single dlls. You install them one by one. But think about NUnit, as an example. It contains about dozen of dlls along with various xml and configuration files. How can you install it to GAC?
  • Security is cumbersome. You’ll need to configure Apache Server’s security, and even then it won’t be flexible enough to determine between deployer (a user that can publish private dependencies) and promoter (a user that can move dependencies from a private repository to a public one).
  • Search is basic. WebDAV by itself only knows about files. It doesn’t care about the structure of the filename, or about the presence of Strong Names.

Looks like we still didn’t find what we are looking for, and then…

Here comes NuGet

This is something else. NuGet designed to be “a developer focused package management system for the .NET platform intent on simplifying the process of incorporating third-party libraries into a .NET application during development”. That’s exactly what we need. Let’s look how great it is:

  • Manages packages, not dlls.
  • Provides NuGet Gallery – almost 4.5K (at the time of writing) packages are at your disposal for all your development needs.
  • Supports binary versioning.
  • Integrates with Visual Studio.
  • Integrates with your build.
  • Integrates with your build server (only TeamCity at the moment of writing).

This tool’s like a dream come true. So, what can I mention as downsides? Most of them are downsides of the NuGet Gallery, not NuGet itself. The Gallery is a young and relatively small project (just for the sake of comparison, Maven Central is 6 years old and contains more than 290K artifacts) and, as such, it has its downsides:

  • The content of submissions to the Gallery is (almost) unverified. Everyone can register, get the API key and start uploading whatever they like. Scary, isn’t it? (yes, very scary).
  • Being public, NuGet Gallery can’t be used for inter-team packages exchange. Private Remote Feeds are the recommended solution. Next we’ll see if it is good enough.

Working with NuGet Remote Feeds

Remote Feeds, introduced in NuGet 1.4 are crucial need for any development team. It serves a dual purpose: it allows sharing 3rd party packages that aren’t available on Gallery (or even replaces the Gallery for those who can’t trust it) and it serves as a target for internal deployments – both for team collaboration and for other usages, as making packages available to QA, or even serving them to the customers from the outside world (by using Chocolatey, for example). If that’s so right, what’s wrong? Here’s what:

  • You saw it coming: It isn’t a proxy. You know the score by now.
  • It can’t aggregate. The NuGet Remote Feed exposing one monolithic repository: the one you have on your machine. It can’t aggregate NuGet packages from remote repositories, or expose number of local repositories (separated for security reasons, for example).
  • You can’t attach your own metadata. Let’s say you want to annotate some package with compatibility information (e.g. works with certain browsers). No, can’t do.
  • The repository is very simplistic. It doesn’t provide any web interface; it browsable and searchable only from a client – be it Visual Studio or the command line interface (pretty basic by itself).
  • Even the VS search interface is very basic (all you have is arbitrary sorting and free text search). It should be enough for starters but lack of searching inside the packages or by properties (from the previous bullet) will bite you eventually.
  • The security scheme is even less than simplistic. All that’s required to authenticate a deployment/delete of all the users at once is an API key. What about separation of duties? Some users should only be able to read, others only to annotate with metadata (QA team that tests compatibility in my previous example), and only small subgroup – to deploy.  The all-or-nothing scheme is definitely insufficient.
  • Storage format is suboptimal:
    • The packages are stored on the filesystem in a naive simple format. That fine for small repository,but as you grow, you’d expect storage which more optimized for binaries.
    • The metadata is not indexed. Again, fine for small repo, troubles are foreseen when it comes to scaling.

So, is there a good alternative to NuGet Remote Feed to be your in-house Gallery for NuGet packages? We, the proud makers of Artifactory,  believe there is.

Meet Artifactory

Artifactory is an enterprise-grade Binary Repository that centralizes all aspects of managing software binaries. That means that we tackle all the problems mentioned above. We are developing Artifactory since 2006. Being used by millions of users for storing, sharing and managing binaries, we have gathered great feedback from our users.

That’s what we’ve learned:

  • Binary packages are different from sources (by being big and binary) and deserve smart storage.
  • Binary packages are usually archives (be it jars, zips, rpms or nupkgs). They should be browsable and searchable without the need to download them locally to developer’s machine.
  • Big public repositories exist on the net, they need to be proxied smartly (variations, auditing, managing)
  • Users come in different flavors. Their permissions should match possible responsibilities (and in the case of binary packages they are different from other cases).
  • A binary repository holds critical information, it should be rock-solid, backed up, and DRP ready.
  • Your software ends up being a package. We know how to help you…
    • build it in a reproducible manner, integrating with your build tools and your build server.
    • stage it to ensure the best quality.
    • distribute it to your customers.

You get the gist behind Artifactory by watching this 2.5 minutes video:
If you’re not in the mood for movies (or ran out of popcorn), here’s quick recap:
As you see, instead of working with a number of NuGet Feeds (NuGet Gallery, Orchard Gallery,  Remote Feeds from co-workers and from different teams) developers work with exactly one repository. It simplifies setup and daily work and centralizes management and maintenance.
The work is bi-directional, the users resolve their 3rd party dependencies from Artifactory and deploy their created packaged into it.

Now let’s add a build server to the picture (literally):
Yup, with numbers this time. So, here we go:

  1. Developers find and  fetch new 3rd party packages from Artifactory in Visual Studio. The packages are downloaded from Artifactory to the developer’s machine. If the packages aren’t present in Artifactory it will look for them in remote galleries/feeds. On developer machines packages.config is updated with the list of used packages.
  2. Developers commit their code and packages.config (but not the binaries) to VCS.
  3. The Build server (as I already mentioned, TeamCity now supports NuGet) takes the changes from the VCS.
  4. It builds the solution and packs the produced artifacts as NuGet packages.
  5. During the build it fetches the needed packages from Artifactory. If the packages aren’t present in Artifactory it will look for them in remote galleries/feeds.
  6. Once the packages are built they are deployed to Artifactory.

Built packages in Artifactory can be used by other teams (as their 3rd party dependencies), by QA for running tests and even by the end users (Chocolatey FTW), all this with fine-grained permissions and robust promotion procedures (moving a package between repositories with different visibility rules).
You know what? It deserves dedicated how-to blog post. I’ll link it here once published.

Assuming you’ve read up to this point, you’ve gathered that starting from Artifactory version 2.5.0 we are proud to serve the .NET world with full NuGet support. We can proxy any remote NuGet feed (starting with NuGet Gallery, of course), we can host the packages that aren’t found on any remote NuGet feed, we can host the packages you produce and we can aggregate any number of repositories of any kind under single a URL. We provide you with an awesome UI for configuring your repositories, browsing and searching for your packages. We also feature smart storage that enables attaching searchable metadata on top of your binaries. We can do it all on the cloud with our SAAS version.

Hopefully , you’re convinced by now and probably looking for the download link on our site (here’s it, BTW, click on “Evalution”). If not, give it a try by playing with our live demo. Look at the nuget-gallery cache: that’s how we proxy the NuGet Gallery. You’ll find some of the packages saved locally; once you’ve selected a package, you’ll see all kinds of information about it: its name and size, who deployed it to Artifactory, where it came from (from NuGet Gallery, naturally for this is the NuGet Gallery cache) and the operations you can perform on this package (as anonymous the selection is naturally limited). Clicking on the triangle in the tree will open the package and let you dive into its content, including downloading specific files from the archive (click for full-size image):Browse Artifactory

We, at JFrog, believe that Artifactory is the missing piece of the puzzle for a robust, agile .NET dependency management, which can make the development process easier compared to other alternatives.
We’ll be happy to receive any insights, thoughts and comments on the ideas presented in this blog and/or your experience using Artifactory together with NuGet.


Filed under: Artifactory, JFrog Tagged: artifactory, jfrog, nuget, teamcity

Items:   1 to 5 of 15   Next »