Ribbon is a Inter Process Communication (remote procedure calls) library with built in software load balancers. The primary usage model involves REST calls with various serialization scheme support.

Overview

Ribbon

Ribbon is a client side IPC library that is battle-tested in cloud. It provides the following features

  • Load balancing
  • Fault tolerance
  • Multiple protocol (HTTP, TCP, UDP) support in an asynchronous and reactive model
  • Caching and batching

To get ribbon binaries, go to maven central. Here is an example to add dependency in Maven:

<dependency>
    <groupId>com.netflix.ribbon</groupId>
    <artifactId>ribbon</artifactId>
    <version>2.2.2</version>
</dependency>

Modules

  • ribbon: APIs that integrate load balancing, fault tolerance, caching/batching on top of other ribbon modules and Hystrix
  • ribbon-loadbalancer: Load balancer APIs that can be used independently or with other modules
  • ribbon-eureka: APIs using Eureka client to provide dynamic server list for cloud
  • ribbon-transport: Transport clients that support HTTP, TCP and UDP protocols using RxNetty with load balancing capability
  • ribbon-httpclient: REST client built on top of Apache HttpClient integrated with load balancers (deprecated and being replaced by ribbon module)
  • ribbon-example: Examples
  • ribbon-core: Client configuration APIs and other shared APIs

Project Status: On Maintenance

Ribbon comprises of multiple components some of which are used in production internally and some of which were replaced by non-OSS solutions over time. This is because Netflix started moving into a more componentized architecture for RPC with a focus on single-responsibility modules. So each Ribbon component gets a different level of attention at this moment.

More specifically, here are the components of Ribbon and their level of attention by our teams:

  • ribbon-core: deployed at scale in production
  • ribbon-eureka: deployed at scale in production
  • ribbon-evcache: not used
  • ribbon-guice: not used
  • ribbon-httpclient: we use everything not under com.netflix.http4.ssl. Instead, we use an internal solution developed by our cloud security team
  • ribbon-loadbalancer: deployed at scale in production
  • ribbon-test: this is just an internal integration test suite
  • ribbon-transport: not used
  • ribbon: not used

Even for the components deployed in production we have wrapped them in a Netflix internal http client and we are not adding new functionality since they’ve been stable for a while. Any new functionality has been added to internal wrappers on top of Ribbon (such as request tracing and metrics). We have not made an effort to make those components Netflix-agnostic under Ribbon.

Recognizing these realities and deficiencies, we are placing Ribbon in maintenance mode. This means that if an external user submits a large feature request, internally we wouldn’t prioritize it highly. However, if someone were to do work on their own and submit complete pull requests, we’d be happy to review and accept. Our team has instead started building an RPC solution on top of gRPC. We are doing this transition for two main reasons: multi-language support and better extensibility/composability through request interceptors. That’s our current plan moving forward.

We currently contribute to the gRPC code base regularly. To help our teams migrate to a gRPC-based solution in production (and battle-test it), we are also adding load-balancing and discovery interceptors to achieve feature parity with the functionality Ribbon and Eureka provide. The interceptors are Netflix-internal at the moment. When we reach that level of confidence we hope to open-source this new approach. We don’t expect this to happen before Q3 of 2016.

Release notes

See https://github.com/Netflix/ribbon/releases

Code example

Access HTTP resource using template (full example)

HttpResourceGroup httpResourceGroup = Ribbon.createHttpResourceGroup("movieServiceClient",
            ClientOptions.create()
                    .withMaxAutoRetriesNextServer(3)
                    .withConfigurationBasedServerList("localhost:8080,localhost:8088"));
HttpRequestTemplate<ByteBuf> recommendationsByUserIdTemplate = httpResourceGroup.newTemplateBuilder("recommendationsByUserId", ByteBuf.class)
            .withMethod("GET")
            .withUriTemplate("/users/{userId}/recommendations")
            .withFallbackProvider(new RecommendationServiceFallbackHandler())
            .withResponseValidator(new RecommendationServiceResponseValidator())
            .build();
Observable<ByteBuf> result = recommendationsByUserIdTemplate.requestBuilder()
                        .withRequestProperty("userId", "user1")
                        .build()
                        .observe();

Access HTTP resource using annotations (full example)

public interface MovieService {
    @Http(
            method = HttpMethod.GET,
            uri = "/users/{userId}/recommendations",
            )
    RibbonRequest<ByteBuf> recommendationsByUserId(@Var("userId") String userId);
}

MovieService movieService = Ribbon.from(MovieService.class);
Observable<ByteBuf> result = movieService.recommendationsByUserId("user1").observe();

Create an AWS-ready load balancer with Eureka dynamic server list and zone affinity enabled

        IRule rule = new AvailabilityFilteringRule();
        ServerList<DiscoveryEnabledServer> list = new DiscoveryEnabledNIWSServerList("MyVIP:7001");
        ServerListFilter<DiscoveryEnabledServer> filter = new ZoneAffinityServerListFilter<DiscoveryEnabledServer>();
        ZoneAwareLoadBalancer<DiscoveryEnabledServer> lb = LoadBalancerBuilder.<DiscoveryEnabledServer>newBuilder()
                .withDynamicServerList(list)
                .withRule(rule)
                .withServerListFilter(filter)
                .buildDynamicServerListLoadBalancer();   
        DiscoveryEnabledServer server = lb.chooseServer();         

Use LoadBalancerCommand to load balancing IPC calls made by HttpURLConnection (full example)

CommandBuilder.<String>newBuilder()
        .withLoadBalancer(LoadBalancerBuilder.newBuilder().buildFixedServerListLoadBalancer(serverList))
        .build(new LoadBalancerExecutable<String>() {
            @Override
            public String run(Server server) throws Exception {
                URL url = new URL("http://" + server.getHost() + ":" + server.getPort() + path);
                HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                return conn.getResponseMessage();
            }
        }).execute();

License

Copyright 2014 Netflix, Inc.

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Questions?

Email [email protected] or join us

Comments
  • Proposal for high level client APIs for best practices

    Proposal for high level client APIs for best practices

    Note: the latest design is here

    Goals

    In the past two years, Ribbon has been used as an inter-processing communication client with load balancing capabilities. Some best practices have been observed when using Ribbon together with other open source libraries. We feel it is best to offer such best practices in a form of a set of APIs in a new Ribbon module.

    Here is that we want to achieve:

    • Use annotation/template to drive the process of a request creation as opposed to hand-craft the request
    • Use Hystrix for fault tolerance, fallback and call collapsing and make Ribbon client properties visible to Hystrix to close the gap of the two layers
    • Use cache, (e.g. EVCache) for low latency data access before reaching out to the actual resource
    • Built on top of reactive and non-blocking networking layer RxNetty
    • Protocol agnostic

    The ultimate goal is that the clients created with this set of API should be more consistent, agile, reliable, efficient, and resilient.

    Design proposal

    The center pieces of the new API are AsyncRequest and RibbonRequest

    public interface AsyncRequest<T> {
        public T execute();
    
        public Future<T> queue();
    
        public Observable<T> observe();
    
        public Observable<T> toObservable();
    }
    
    public interface RibbonRequest<T> extends AsyncRequest<T> {
        public RibbonRequest<HystrixResponse<T>> withHystrixInfo();
    }
    

    RequestTemplate is used to represent all the information, including cache providers, Hystrix fallback and any protocol specific information (e.g. URI for HTTP) required to create RibbonRequest. Information supplied to create the RequestTemplate may include variables which should be substituted with real values at the time of request creation.

    /**
     * @param <I> request input entity type
     * @param <O> response entity type
     * @param <R> response meta data, e.g. HttpClientResponse
     */
    public interface RequestTemplate<I, O, R> {
    
        RequestBuilder<O> requestBuilder();
    
        RequestTemplate<I, O, R> withFallbackProvider(FallbackProvider<O> fallbackProvider);
    
        RequestTemplate<I, O, R> withFallbackDeterminator(FallbackDeterminator<R> fallbackDeterminator);
    
        RequestTemplate<I, O, R> addCacheProvider(CacheProvider<O> cacheProvider, String cacheKeyTemplate);
    
        RequestTemplate<I, O, R> withHystrixCommandPropertiesDefaults(HystrixCommandProperties.Setter setter);
    
        RequestTemplate<I, O, R> withHystrixThreadPoolPropertiesDefaults(HystrixThreadPoolProperties.Setter setter);
    
        RequestTemplate<I, O, R> withHystrixCollapserPropertiesDefaults(HystrixCollapserProperties.Setter setter);
    
        public abstract class RequestBuilder<O> {
            public abstract RequestBuilder<O> withValue(String key, Object value);
    
            public abstract RibbonRequest<O> build();
        }
    }
    

    FallbackDeterminator is used to determine whether a response with protocol specific meta data should cause throw an error during Hystrix command execution and cause a fallback:

    public interface FallbackDeterminator<T> {
        public boolean shouldTriggerFallback(T responseMetaData);
    }
    

    For example:

    Ribbon.from(httpClient)
            .newRequestTemplate()
            .withFallbackDeterminator(new FallbackDeterminator<HttpClientResponse<ByteBuf>>() {
                @Override
                public boolean shouldTriggerFallback(
                        HttpClientResponse<ByteBuf> response) {
                    return response.getStatus().code() >= 500;
                }
            })   
    

    Once FallbackDeterminator determines that a protocol specific response should trigger Hystrix fallback, HystrixFallbackProvider is used to get the actual fallback:

    public interface FallbackProvider<T> extends Func1<HystrixCommand<T>, Observable<T>> {
    }
    

    CacheProvider is the interface to provide access to cache of the resource

    public interface CacheProvider<T> {
        Observable<T> get(String key);
    }
    

    Ribbon is the factory that creates

    • clients whose responsibility is to create protocol specific template
    • service object from the interface definition of a service contract defined by annotations
    public final class Ribbon {
    
        private Ribbon() {
        }
    
        public static <I, O> RibbonHttpClient<I, O> from(HttpClient<I, O> transportClient) {
            // ...
        }
    
        public static <I, O, T> T create(Class<T> contract, HttpClient<I, O> transportClient) {
            // ...
        }
    }
    
    /**
     * @param <I> Request input entity type
     * @param <O> Response entity type
     * @param <T> Type of RequestTemplate
     */
    public interface RibbonClient<I, O, T extends RequestTemplate<I, O, ?>> {
        public T newRequestTemplate();
    }
    

    The ribbon-transport module in Ribbon will provide clients used by Ribbon for different protocol with load balancing capabilities. You can also use any client created directly RxNetty if load balancing is not required.

    The RibbonTransport in ribbon-transport module is the factory to create load balancing clients:

    public final class RibbonTransport {
    
        private RibbonTransport() {
        }
    
        public static RxClient<ByteBuf, ByteBuf> newTcpClient(ILoadBalancer loadBalancer, IClientConfig config) {
            // ...
        }
    
        public static <I, O> RxClient<I, O> newTcpClient(ILoadBalancer loadBalancer, PipelineConfigurator<O, I> pipelineConfigurator, 
                IClientConfig config) {
            // ...
        }
    
        public static <I, O> RxClient<I, O> newTcpClient(PipelineConfigurator<O, I> pipelineConfigurator, 
                IClientConfig config) {
            // ...
        }
    
        // ...
    
        public static HttpClient<ByteBuf, ByteBuf> newHttpClient(IClientConfig config) {
            // ...
        }
    
        public static <I, O> HttpClient<I, O> newHttpClient(PipelineConfigurator<HttpClientResponse<O>, HttpClientRequest<I>> pipelineConfigurator, 
                ILoadBalancer loadBalancer, IClientConfig config) {
           // ...
        }
    
        public static <I, O> HttpClient<I, O> newHttpClient(PipelineConfigurator<HttpClientResponse<O>, HttpClientRequest<I>> pipelineConfigurator, 
                IClientConfig config) {
            // ...
        }
    }
    
    opened by allenxwang 104
  • Add async HTTP support based on Apache's HttpAsyncClient

    Add async HTTP support based on Apache's HttpAsyncClient

    Compared with Netty, Apache's HttpAsyncClient seems to be easier to integrate into Ribbon's higher level async interface design. Another significant advantage is that it has built-in connection pool support.

    So the plan is to merge this first and continue working on Netty's integration with Ribbon.

    Here are the new features provided:

    • Execute simple async request/response with response buffering
    • Support streaming with customized stream decoder
    • Use a wrapper to provide RxJava's Observable APIs, while providing the simple callback based APIs at the same time
    • Async execution with load balancers
    • Customizable serialization
    • Async execution with cancelable back up requests

    The new HttpRequest and HttpResponse will be used by both RestClient and AsyncHttpClient while RestClient's specific request/response classes are hidden or deprecated.

    Some APIs in AbstractLoadBalancerAwareClient is factored out to LoadBalancerContext to be used by AsyncLoadBalancingClient.

    Examples are provided in ribbon-examples sub project.

    opened by allenxwang 21
  • Modify HttpRequestTemplate and HttpResourceGroup to be DI friendly

    Modify HttpRequestTemplate and HttpResourceGroup to be DI friendly

    To enable ribbon in Guice just add RibbonModule() when creating the injector (either via Guice or Governator). Alternatively one can override the bindings for HttpResourceGroupFactory and HttpRequestTemplateFactory to override HttpResourceGroup and HttpRequestTemplate.

    opened by elandau 14
  • Add atomic cyclic counting to RoundRobinRule.

    Add atomic cyclic counting to RoundRobinRule.

    Replaced the AtomicLong implementation of our cyclic counting code with an AtomicInteger that rotates back to 0 if it hits its max value so we do the "right thing".

    Also did a bit of clean-up and fixed one of the unit tests that was unstable.

    opened by drtechniko 12
  • add ability for ribbon/eureka to use ipAddr instead of hostName configed...

    add ability for ribbon/eureka to use ipAddr instead of hostName configed...

    add ability for ribbon/eureka to use ipAddr instead of hostName configed via Archaius

    this relates to the discussion on the mailing list here:

    https://groups.google.com/forum/#!topic/eureka_netflix/7M28bK-SCZU

    opened by aspyker 10
  • add loadBalancerKey when building a LoadBalancerCommand

    add loadBalancerKey when building a LoadBalancerCommand

    I want to write a class implemented IRule to choose a service instance based on the loadBalancerKey, the 'IRule' implementation just like this:

    public class MyLoadBalancerRule extends AbstractLoadBalancerRule {
        @Override
        public void initWithNiwsConfig(IClientConfig clientConfig) {
        }
    
        @Override
        public Server choose(Object key) {
            List<Server> servers = getLoadBalancer().getReachableServers();
            // choose and return a server from servers based on the key
        }
    }
    

    but the key is always null.

    LoadBalancerCommand passes its attribute loadBalancerKey as parameter to the choose method. And LoadBalancerCommand object is constructed in AbstractLoadBalancerAwareClient#executeWithLoadBalancer without setting the attribute loadBalancerKey.

    So I report this pr to add the loadBalancerKey when building a LoadBalancerCommand object.

    opened by lowzj 9
  • SSL via IClientConfig attributes and RibbonTranport.newHttpClient

    SSL via IClientConfig attributes and RibbonTranport.newHttpClient

    We have encountered difficulty in getting SSL communication to work with the NettyHttpClient. I am instantiating this via the RibbonTransport.newHttpClient(lb,config) static constructor. I am populating the keystore and keystore password in the client config, as well as the withSecure() attribute. The server is jetty.

    With SSL debug turned on, we are essentially getting no handshake activity to occur. There is no exception or timeout, just multiple attempts and eventual failure. I have tested the key and trust stores with success using other clients, browsers and openssl with success, so the certs seem good.

    During research into how to get this to work, I came across this issue in RxNetty, which has a similar feel to it: https://github.com/ReactiveX/RxNetty/issues/213

    I then switched to the RxNetty client, which provides a hook to the SSLEngineFactory. By creating my own ssl engine factory and overriding the createSSLEngine method to set use client mode to true, I was able to get the following to work:

    SslContextFactory sslContextFactory = new SslContextFactory(); sslContextFactory.setKeyStorePath(myKeystore); sslContextFactory.setKeyStorePassword(myKeystorePassword);
       try {
            sslContextFactory.start();
        }
        catch (Exception e) { ;  }
    
        SSLEngineFactory myFactory = new DefaultFactories.SSLContextBasedFactory(sslContextFactory.getSslContext()) {
            @Override
            public SSLEngine createSSLEngine(ByteBufAllocator allocator) {
                SSLEngine myEngine = super.createSSLEngine(allocator);
                myEngine.setUseClientMode(true);
                return myEngine;
            };
        }
        HttpClient<ByteBuf, ByteBuf> rxClient = RxNetty.<ByteBuf, ByteBuf>newHttpClientBuilder("localhost", 8443)
                .withSslEngineFactory(myFactory)
                .build();
    

    However, now we have lost the load balancing internal to the Ribbon client, so I couldn't use it for anything other than proving out the theory. Following the theory further, I was able to get the NettyHttpClient working by following a similar SSLEngineFactory creation path and adding a new PipelineConfigurator onto the newHttpClient constructor in RibbonTransport:

    PipelineConfigurator, HttpClientRequest> sslPipelineConfigurator = new SslPipelineConfigurator,HttpClientRequest>(myFactory);
            PipelineConfigurator<HttpClientResponse<ByteBuf>, HttpClientRequest<ByteBuf>> configurators =
                    new PipelineConfiguratorComposite<HttpClientResponse<ByteBuf>, HttpClientRequest<ByteBuf>>(PipelineConfigurators.httpClientConfigurator(),sslPipelineConfigurator);
    
            wrappedClient = RibbonTransport.newHttpClient(configurators, loadBalancer, clientConfig);
    

    This also works, but I feel it isn't ideal. It seems like somewhere along the line, the underlying SSL implementations have possibly changed to require the setUseClientMode() call and we're not doing it now. Is that possible?

    My belief is that changing the LoadBalancingHttpClient to do a similar overriding on the SslEngineFactory it uses in the clientBuilder in protected HttpClient<I, O> cacheLoadRxClient(Server server) might solve the issue, assuming its something that is an issue and not something I have messed up. I am planning on forking and testing this out and will respond to this issue with those results, but I thought it might be useful for others to weigh in or as help for others experiencing the same issue.

    opened by dhawken 8
  • NettyHttpClient created from RibbonTransport does not honor NIWSServerListClassName in IClientConfig

    NettyHttpClient created from RibbonTransport does not honor NIWSServerListClassName in IClientConfig

    The constructor calls the LoadBalancerBuilder API which always return a load balancer with a ConfigurationBasedServerList, regardless whether NIWSServerListClassName is set in the config.

    bug 
    opened by allenxwang 8
  • AbstractLoadBalancerAwareClient is not handling query param encoding correctly

    AbstractLoadBalancerAwareClient is not handling query param encoding correctly

    AbstractLoadBalancerAwareClient.computeFinalUriWithLoadBalancer() rebuilds the URI but corrupts query parameters. Line 672 is:

    newURI = new URI(scheme, theUrl.getUserInfo(), host, port, urlPath, theUrl.getQuery(), theUrl.getFragment());
    

    It should be:

    newURI = new URI(scheme, theUrl.getUserInfo(), host, port, urlPath, theUrl.getRawQuery(), theUrl.getFragment());
    

    Here's a test that shows the problem:

    import com.netflix.client.ClientException;
    import com.netflix.niws.client.http.HttpClientRequest;
    import com.netflix.niws.client.http.RestClient;
    import org.junit.Assert;
    import org.junit.Test;
    
    import java.net.URI;
    import java.net.URLEncoder;
    import java.util.concurrent.atomic.AtomicReference;
    
    public class RibbonTest {
        @Test
        public void showBadEncodingInRibbon() throws Exception {
            final String lotsOfToughChars = "éƎ&=*%!@#$%^&*()";
    
            final AtomicReference<URI> computedUri = new AtomicReference<>();
            RestClient restClient = new RestClient() {
                @Override
                protected HttpClientRequest computeFinalUriWithLoadBalancer(HttpClientRequest original) throws ClientException {
                    HttpClientRequest httpClientRequest = super.computeFinalUriWithLoadBalancer(original);
                    computedUri.set(httpClientRequest.getUri());
                    return httpClientRequest;
                }
            };
    
            URI uri = new URI("http://foo.com:8080/bar?test=" + URLEncoder.encode(lotsOfToughChars, "UTF-8"));
            HttpClientRequest request = HttpClientRequest.newBuilder().setUri(uri).build();
            try {
                restClient.executeWithLoadBalancer(request);
            } catch (ClientException e) {
                // ignore
            }
    
            Assert.assertEquals(uri, computedUri.get());
        }
    }
    
    opened by Randgalt 8
  • Added listener notification on server status changes to BaseLoadBalancer

    Added listener notification on server status changes to BaseLoadBalancer

    Fix for issue #218: Taking the cue from the existing ServerListChangeListener I have added a ServerStatusChangeListener that may be registered with BaseLoadBalancer to receive notifications on server status changes (server down/up).

    We have had this code in production for some time now and would like to see it included in Ribbon.

    opened by lasselasse 7
  • Updates for 1.x

    Updates for 1.x

    First batch of update for ribbon 1.x branch.

    • Added ribbon-rxnetty module for asynchronous HTTP communication based on Netty and RxJava
    • IClientConfig and IClientConfigKey supports typed property
    • Updates to serialization factory and serializer interfaces (replaced Guava TypeToken with TypeDef in the interfaces)
    • Updates to HttpRequest and HttpResponse interfaces with addition of HttpHeaders
    opened by allenxwang 7
Releases(v2.4.8)
Owner
Netflix, Inc.
Netflix Open Source Platform
Netflix, Inc.
Netflix, Inc. 23.1k Jan 5, 2023
a reverse proxy load balancer using Java. Inspired by Nginx.

Project Outline: Project Main coding reverse proxy support configuration adding unit test works on Websocket Stress Test compared to Nginx load balanc

Feng 12 Aug 5, 2022
Java software that notifies by voice when a new Vaccine is available in your specified district/pincode

CowinVaccineAvailabilitySpeaker is a Java software that notifies user by voice when a new vaccine is available in the specified pin-code/district. It

Abhishek Chawla 10 May 24, 2021
Abstract the use of amazon lex / google dialog flow, while also support complex conditional flows

amazon-lex-gcp-diaglogflow-abstraction on simply put: ALGDA :) In this project I try to abstract the use of amazon lex first, but then also google's d

Shimon Magal 10 Apr 19, 2021
Resilience4j is a fault tolerance library designed for Java8 and functional programming

Fault tolerance library designed for functional programming Table of Contents 1. Introduction 2. Documentation 3. Overview 4. Resilience patterns 5. S

Resilience4j 8.5k Jan 2, 2023
BitTorrent library and client with DHT, magnet links, encryption and more

Bt A full-featured BitTorrent implementation in Java 8 peer exchange | magnet links | DHT | encryption | LSD | private trackers | extended protocol |

Andrei Tomashpolskiy 2.1k Jan 2, 2023
Ribbon is a Inter Process Communication (remote procedure calls) library with built in software load balancers. The primary usage model involves REST calls with various serialization scheme support.

Ribbon Ribbon is a client side IPC library that is battle-tested in cloud. It provides the following features Load balancing Fault tolerance Multiple

Netflix, Inc. 4.4k Jan 4, 2023
Welcome to the EHS robotics club's GitHub repository, this will also be used as our primary community center and means of communication. Also be sure to join our remind for on the go updates @EHSFTC21

NOTICE This repository contains the public FTC SDK for the Ultimate Goal (2020-2021) competition season. Formerly this software project was hosted her

null 5 Feb 25, 2022
Remote Support Tool is an easy single click solution for remote maintenance.

Remote Support Tool is an easy single click solution for remote maintenance.

OpenIndex.de 74 Jun 13, 2022
Firestorm is a Remote Shuffle Service, and provides the capability for Apache Spark applications to store shuffle data on remote servers

What is Firestorm Firestorm is a Remote Shuffle Service, and provides the capability for Apache Spark applications to store shuffle data on remote ser

Tencent 246 Nov 29, 2022
High Performance Inter-Thread Messaging Library

LMAX Disruptor A High Performance Inter-Thread Messaging Library Maintainer LMAX Development Team Support Open a ticket in GitHub issue tracker Google

LMAX Group 15.5k Dec 31, 2022
High Performance Inter-Thread Messaging Library

LMAX Disruptor A High Performance Inter-Thread Messaging Library Maintainer LMAX Development Team Support Open a ticket in GitHub issue tracker Google

LMAX Group 15.5k Jan 9, 2023
Ribbon control for Java, created in JavaFX

FXRibbon Ribbon control for Java, using JavaFX framework, based on Microsoft Ribbon. If you want to support the development of this library consider a

Pedro Duque Vieira 224 Dec 27, 2022
Gleam is a simple Scheme language interpreter written in Java.

Gleam Scheme Interpreter (c) 2001-2020 Guglielmo Nigri (guglielmonigri at yahoo.it, googlielmo at gmail.com) Gleam comes with ABSOLUTELY NO WARRANTY.

Guglielmo Nigri 2 Jun 6, 2022
A neo4j procedure for tabby (dev)

tabby-path-finder #0 简介 A neo4j procedure for tabby tabby污点分析扩展,用于根据tabby生成的代码属性图做动态剪枝+深度搜索符合条件的利用链/漏洞链路。 #1 用法 生成jar文件 mvn clean package -DskipTests

wh1t3P1g 47 Dec 11, 2022
This is an automated library software built in Java Netbeans to reduce manual efforts of the librarian, students to ensure smooth functioning of library by involving RFIDs.

Advanced-Library-Automation-System This is an advanced automated library software built in Java Netbeans to reduce manual efforts of the librarian, st

DEV_FINWIZ 14 Dec 6, 2022
ActiveJ is an alternative Java platform built from the ground up. ActiveJ redefines web, high load, and cloud programming in Java, featuring ultimate performance and scalability!

Introduction ActiveJ is a full-featured modern Java platform, created from the ground up as an alternative to Spring/Micronauts/Netty/Jetty. It is des

ActiveJ LLC 579 Jan 7, 2023