Search code examples
javaspring-bootsolrbroadleaf-commerce

Broadleaf Commerce Embedded Solr cannot run with root user


I download a fresh 6.1 broadleaf-commerce and run my local machine via java -javaagent:./admin/target/agents/spring-instrument.jar -jar admin/target/admin.jar successfully on mine macbook. But in my centos 7 I run sudo java -javaagent:./admin/target/agents/spring-instrument.jar -jar admin/target/admin.jar with following error

2020-10-12 13:20:10.838  INFO 2481 --- [           main] c.b.solr.autoconfigure.SolrServer        : Syncing solr config file: jar:file:/home/mynewuser/seafood-broadleaf/admin/target/admin.jar!/BOOT-INF/lib/broadleaf-boot-starter-solr-2.2.1-GA.jar!/solr/standalone/solrhome/configsets/fulfillment_order/conf/solrconfig.xml to: /tmp/solr-7.7.2/solr-7.7.2/server/solr/configsets/fulfillment_order/conf/solrconfig.xml
*** [WARN] ***  Your Max Processes Limit is currently 62383.
 It should be set to 65000 to avoid operational disruption.
 If you no longer wish to see this warning, set SOLR_ULIMIT_CHECKS to false in your profile or solr.in.sh
WARNING: Starting Solr as the root user is a security risk and not considered best practice. Exiting.
         Please consult the Reference Guide. To override this check, start with argument '-force'
2020-10-12 13:20:11.021 ERROR 2481 --- [           main] c.b.solr.autoconfigure.SolrServer        : Problem starting Solr

Here is the source code of solr configuration, I believe it is the place to change the configuration to run with the argument -force in programming way.

package com.community.core.config;

import org.apache.solr.client.solrj.SolrClient;
import org.apache.solr.client.solrj.impl.HttpSolrClient;
import org.broadleafcommerce.core.search.service.SearchService;
import org.broadleafcommerce.core.search.service.solr.SolrConfiguration;
import org.broadleafcommerce.core.search.service.solr.SolrSearchServiceImpl;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

/**
 * 
 * 
 * @author Phillip Verheyden (phillipuniverse)
 */
@Component
public class ApplicationSolrConfiguration {

    @Value("${solr.url.primary}")
    protected String primaryCatalogSolrUrl;
    
    @Value("${solr.url.reindex}")
    protected String reindexCatalogSolrUrl;
    
    @Value("${solr.url.admin}")
    protected String adminCatalogSolrUrl;

    @Bean
    public SolrClient primaryCatalogSolrClient() {
        return new HttpSolrClient.Builder(primaryCatalogSolrUrl).build();
    }
    
    @Bean
    public SolrClient reindexCatalogSolrClient() {
        return new HttpSolrClient.Builder(reindexCatalogSolrUrl).build();
    }
    
    @Bean
    public SolrClient adminCatalogSolrClient() {
        return new HttpSolrClient.Builder(adminCatalogSolrUrl).build();
    }

    @Bean
    public SolrConfiguration blCatalogSolrConfiguration() throws IllegalStateException {
        return new SolrConfiguration(primaryCatalogSolrClient(), reindexCatalogSolrClient(), adminCatalogSolrClient());
    }

    @Bean
    protected SearchService blSearchService() {
        return new SolrSearchServiceImpl();
    }
    
}

Solution

  • Let me preface this by saying you would be better off simply not starting the application as root. If you are in Docker, you can use the USER command to switch to a non-root user.

    The Solr server startup in Broadleaf Community is done programmatically via the broadleaf-boot-starter-solr dependency. This is the wrapper around Solr that ties it to the Spring lifecycle. All of the real magic happens in the com.broadleafcommerce.solr.autoconfigure.SolrServer class.

    In that class, you will see a startSolr() method. This method is what adds startup arguments to Solr.

    In your case, you will need to mostly copy this method wholesale and use cmdLine.addArgument(...) to add additional arguments. Example:

    class ForceStartupSolrServer extends SolrServer {
    
        public ForceStartupSolrServer(SolrProperties props) {
            super(props);
        }
    
        protected void startSolr() {
            if (!isRunning()) {
                if (!downloadSolrIfApplicable()) {
                    throw new IllegalStateException("Could not download or expand Solr, see previous logs for more information");
                }
                stopSolr();
                synchConfig();
                {
                    CommandLine cmdLine = new CommandLine(getSolrCommand());
                    cmdLine.addArgument("start");
                    cmdLine.addArgument("-p");
                    cmdLine.addArgument(Integer.toString(props.getPort()));
    
                    // START MODIFICATION
                    cmdLine.addArgument("-force");
                    // END MODIFICATION
    
                    Executor executor = new DefaultExecutor();
                    PumpStreamHandler streamHandler = new PumpStreamHandler(System.out);
                    streamHandler.setStopTimeout(1000);
                    executor.setStreamHandler(streamHandler);
                    try {
                        executor.execute(cmdLine);
                        created = true;
                        checkCoreStatus();
                    } catch (IOException e) {
                        LOG.error("Problem starting Solr", e);
                    }
                }
            }
        }
    }
    

    Then create an @Configuration class to override the blAutoSolrServer bean created by SolrAutoConfiguration (note the specific package requirement for org.broadleafoverrides.config):

    package org.broadleafoverrides.config;
    
    public class OverrideConfiguration {
        
        @Bean
        public ForceStartupSolrServer blAutoSolrServer(SolrProperties props) {
            return new ForceStartupSolrServer(props);
        }
    }