Is it a good idea to have a public inner class as a runner for a service?
I'm a bit confused by your code -- RecipeServiceImpl.buildInternalRunner has a return type of RecipeServiceImpl.Runner, and it's an Override?  Really?

Runner seems to be badly named, as it is easily confused with Runnable, which means something very different.  Is this really a RecipeServiceClient?

It's additionally confusing because you seem to be suggesting that RecipeService declares searchRecipes, but your runner doesn't implement that interface....

Given what you have shown thus far, I would have expected to see a single class, call it PiquetteRecipeService, that extends RecipeService but otherwise looks like the Runner you implemented.

class PiquetteRecipeService implements RecipeService {
    private final PiquetteClient piquetteClient;

    PiquetteRecipeService(PiquetteClient piquetteClient) {
        this.piquetteClient = piquetteClient;
    }

    public List&lt;Recipe&gt; searchRecipes(String query, int limit, int offset) {
        ...
    }

    // And so on....
}


This implementation does require that a PiquetteClient be created before the Service is created, but if the service can't do anything without the client, then that's the Right Thing[tm].

If that's not the right answer, then I think you haven't provided a clear description of the constraints you are trying to satisfy.

public interface RecipeService extends Serializable {
    RecipeServiceImpl.Runner buildInternalRunner(PiquetteClient piquetteClient);
}


OK, this is beyond broken.  You've got an interface, that declares a function which returns a type defined by a specific implementation of that interface.  Help, help, I'm being recursed!

BUT...

The good news is that you are clearly groping toward a Factory pattern.  If we change the spelling of a few things...

public interface RecipeServiceFactory {
    RecipeService createService(PiquetteClient piquetteClient);
}


In other words, instead of expecting Spring to create the service for you, you tell it to create an instance of the service factory for you, and then use that factory to create instances of the service when necessary.

public class DefaultRecipeServiceFactory {
    RecipeService createService(PiquetteClient piquetteClient) {
        return new PiquetteRecipeService(piquetteClient);
    }
}


Meanwhile, you would have a new interface declaration, using the old name...

public interface RecipeService {
    List&lt;Recipe&gt; searchRecipes(String query, int limit, int offet);
    Future&lt;Integer&gt; runRecipe(String recipeName, String asset);
    // ...
}


and the PiquetteRecipeService would implement this interface, delegating calls to the client.

Going back to your original question; with this design, yes it does it make sense to combine the service implementation and the factory that is coupled to it in a single class file.  I'd be more likely to nest the factory inside the service implementation, rather than the other way around:

public class PiquetteRecipeService implements RecipeService {
    public static class Factory implements RecipeServiceFactory {
        // ...
    }
}


If the service implementation isn't supposed to be public, then I would nest them the other direction (or keep them completely separate).

I still wouldn't quite be happy with this design, because arranging for the Factory to accept a PiquetteClient argument rather gives away the fact that the you are using Piquette under the covers.

Spring basically is a giant factory, so why do we need to roll our own?  If you were to let Spring create the PiquetteClient, for instance, then it could inject that client into the RecipeService it creates too.  If the problem there is that you need credentials, or a configuration or something to create the PiquetteClient, then maybe that's the argument that should be passed to the Factory.  Unclear -- just noting that as it stands, it is a bit odd.