在Java v3 Bloomberg API中启动bbcomm

6

当我使用Java Bloomber V3 API时,通常可以正常工作。然而,有时在重新启动后,特别是在bbcomm.exe未在后台运行时,就会出现问题。我可以通过运行blp.exe手动启动它,但我想知道是否有一种通过API来完成这个操作的方法?

4个回答

4
与帮助台交谈后,发现在64位Windows下,运行64位JVM时bbcomm不会自动启动。而在32位Java下,bbcomm会自动运行。
因此,我的解决方案是等待彭博公司解决这个问题(我现在明白了),或者检查这个特定的情况。
要检查特定的情况:
- 如果在64位Windows下运行(系统属性os.arch) - 并且在64位JVM下运行(系统属性java.vm.name) - 然后尝试启动一个会话 - 如果失败,则假设bbcomm.exe未运行。尝试使用Runtime.exec()运行bbcomm.exe 我还没有测试上述内容。它可能与彭博公司在64位VM上遇到的问题完全相同。

3
在与Help Help交流后,发现bbcomm在使用Excel API或运行API演示时会启动。但是从Java API中调用时不会自动启动。可能的启动方式如下:
  • 在注册表中添加条目以在启动时自动启动bbcomm:在 HKEY_LOCAL_MACHINE \ Software \ Microsoft \ Windows \ CurrentVersion \ Run 中添加一个名为 bbcomm 的字符串值,其值为 C:\ blp \ API \ bbcomm.exe -但是这会打开一个命令窗口,该窗口保持可见状态,因此并不是一个好的选择(如果您关闭该窗口,则会终止bbcomm进程)
  • 创建批处理文件 START / MIN C:\ blp \ API \ bbcomm.exe 并用它替换注册表中的条目(未经测试),以静默方式调用bbcomm
  • 像已经建议的那样从Java代码中手动启动bbcomm。作为参考,我在下面发布了我正在使用的代码。
private final static Logger logger = LoggerFactory.getLogger(BloombergUtils.class);
private final static String BBCOMM_PROCESS  = "bbcomm.exe";
private final static String BBCOMM_FOLDER  = "C:/blp/API";

/**
 * 
 * @return true if the bbcomm process is running
 */
public static boolean isBloombergProcessRunning() {
    return ShellUtils.isProcessRunning(BBCOMM_PROCESS);
}

/**
 * Starts the bbcomm process, which is required to connect to the Bloomberg data feed
 * @return true if bbcomm was started successfully, false otherwise
 */
public static boolean startBloombergProcessIfNecessary() {
    if (isBloombergProcessRunning()) {
        logger.info(BBCOMM_PROCESS + " is started");
        return true;
    }

    Callable<Boolean> startBloombergProcess = getStartingCallable();
    return getResultWithTimeout(startBloombergProcess, 1, TimeUnit.SECONDS);
}

private static Callable<Boolean> getStartingCallable() {
    return new Callable<Boolean>() {
        @Override
        public Boolean call() throws Exception {
            logger.info("Starting " + BBCOMM_PROCESS + " manually");
            ProcessBuilder pb = new ProcessBuilder(BBCOMM_PROCESS);
            pb.directory(new File(BBCOMM_FOLDER));
            pb.redirectErrorStream(true);
            Process p = pb.start();
            BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
            String line;
            while ((line = reader.readLine()) != null) {
                if (line.toLowerCase().contains("started")) {
                    logger.info(BBCOMM_PROCESS + " is started");
                    return true;
                }
            }
            return false;
        }
    };

}

private static boolean getResultWithTimeout(Callable<Boolean> startBloombergProcess, int timeout, TimeUnit timeUnit) {
    ExecutorService executor = Executors.newSingleThreadExecutor(new ThreadFactory() {

        @Override
        public Thread newThread(Runnable r) {
            Thread t = new Thread(r, "Bloomberg - bbcomm starter thread");
            t.setDaemon(true);
            return t;
        }
    });
    Future<Boolean> future = executor.submit(startBloombergProcess);

    try {
        return future.get(timeout, timeUnit);
    } catch (InterruptedException ignore) {
        Thread.currentThread().interrupt();
        return false;
    } catch (ExecutionException | TimeoutException e) {
        logger.error("Could not start bbcomm", e);
        return false;
    } finally {
        executor.shutdownNow();
        try {
            if (!executor.awaitTermination(100, TimeUnit.MILLISECONDS)) {
                logger.warn("bbcomm starter thread still running");
            }
        } catch (InterruptedException ex) {
            Thread.currentThread().interrupt();
        }
    }
}

ShellUtils.java

public class ShellUtils {

    private final static Logger logger = LoggerFactory.getLogger(ShellUtils.class);

    /**
     * @return a list of processes currently running
     * @throws RuntimeException if the request sent to the OS to get the list of running processes fails
     */
    public static List<String> getRunningProcesses() {
        List<String> processes = new ArrayList<>();

        try {
            Process p = Runtime.getRuntime().exec(System.getenv("windir") + "\\system32\\" + "tasklist.exe");
            BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));
            String line;
            int i = 0;
            while ((line = input.readLine()) != null) {
                if (!line.isEmpty()) {
                    String process = line.split(" ")[0];
                    if (process.contains("exe")) {
                        processes.add(process);
                    }
                }
            }
        } catch (IOException e) {
            throw new RuntimeException("Could not retrieve the list of running processes from the OS");
        }

        return processes;
    }

    /**
     * 
     * @param processName the name of the process, for example "explorer.exe"
     * @return true if the process is currently running
     * @throws RuntimeException if the request sent to the OS to get the list of running processes fails
     */
    public static boolean isProcessRunning(String processName) {
        List<String> processes = getRunningProcesses();
        return processes.contains(processName);
    }
}

0
在某种情况下,如果有人需要帮助检查/启动从代码隐藏的控制台窗口中的 bbcomm.exe 进程,这段代码用 C# 编写;希望你可以轻松地将其翻译成 Java。
void Main()
{
    var processes = Process.GetProcessesByName("bbcomm");
    if (processes.Any())
    {
        Console.WriteLine(processes.First().ProcessName + " already running");
        return;
    }

    var exePath = @"C:\blp\DAPI\bbcomm.exe";
    var processStart = new ProcessStartInfo(exePath);
    processStart.UseShellExecute = false;
    processStart.CreateNoWindow = true;
    processStart.RedirectStandardError = true;
    processStart.RedirectStandardOutput = true;
    processStart.RedirectStandardInput = true;  
    var process = Process.Start(processStart);
    Console.WriteLine(process.ProcessName + " started");
}

-2

bbcomm.exe 是由 V3 API 自动启动的。


实际上,有时候是这样的,但有时候又不是。我会添加一个答案来说明我的最终决定。 - Nick Fortescue
你应该报告这个问题。API客户端库已经完全实现了你所尝试做的事情。如果它无法连接到bbcomm,它会尝试启动它。如果在某些情况下这不起作用,你应该向彭博公司报告此问题(如果你还没有这样做的话)。 - G Sousa
2
我最终做了我在答案中建议的事情。我不想经历通过BB帮助台找到知道他们在说什么的人的痛苦。如果你在彭博工作,请随意举报或私信我。 - Nick Fortescue

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接