精华内容
下载资源
问答
  • > Manifest merger failed with multiple errors, see logs 原因: AS的Gradle插件默认会启用Manifest Merger Tool,若Library项目中也定义了与主项目相同的属性(例如默认生成的android:icon和android:theme),则...
  • 合并和拆分文档的Java库 允许开发人员加入多个文档,并跨多种操纵文档结构。... 目录 描述 产品文档,其中包含《开发人员指南》,《发行说明》等。 Java示例和示例文档,可帮助您快速...Java的GroupDocs.Merger需要J2SE
  • java -jar target/manifest-merger-jar-with-dependencies.jar --main mainAndroidManifest.xml --log [VERBOSE, INFO, WARNING, ERROR] --libs [path separated list of lib's manifests] --overlays [path ...
  • Subtitle Merger-开源

    2021-06-27 20:43:08
    目标是缩短翻译中“附加短序列”所需的时间。 它使翻译人员更容易完成。
  • ┌─┐┬ ┬┌─┐┌─┐┌─┐┌─┐┬─┐ ┌┬┐┌─┐┬─┐┌─┐┌─┐┬─┐ └─┐│││├─┤│ ┬│ ┬├┤ ├┬┘───│││├┤ ├┬┘│ ┬├┤ ├┬┘ └─┘└┴┘┴ ┴└─┘└─┘└─┘┴└─ ...
  • nginx-lua-static-merger About 详细教程请看: nginx-lua-static-merger是一个基于openresty的模块,主要用于合并静态文件,减少http请求,加快静态文件访问速度的模块。 使用nginx-lua-static-merger 需要在编译...
  • 根据在另一个表中找到的差异在一个表中插入、更新或删除行,可以对两个表进行同步。
  • file-merger-maven-plugin 是一个(非常)简单的 maven 插件,用于(有序)合并文件。 您定义一组要合并的文件和(可选)一个文件目的地,瞧。 默认情况下,插件绑定到 generate-resources 阶段。 用法: 1. 合并 ...
  • Laravel开发-lara-pdf-merger 暂无描述
  • 电影文件合并(MFM)可帮助您选择性地组合视频收藏集,例如家庭视频,电影,系列或纪录片。 它也可以用于其他类型的收藏,例如音乐或基本上任何文件,但MFM已针对视频进行了优化。 MFM不是像Personal Video Database...
  • PDF_合并 Python脚本将pdf页面合并在一起 确保已安装python并运行pip install PyPDF2来安装使用的pdf库。
  • manifest-merger-22.1.1.zip

    2019-10-15 03:35:29
    Bukkit-Plugin-Simple.zip,maven原型创建一个简单的bukkit插件maven原型创建一个简单的bukkit插件
  • 用SQL Server的Merger实现数据的同步与合并,非常方便
  • 合并 将保存csv文件的许多相同类型的数据合并到一个csv文件中。 所有输入的csv文件应具有相同的列数,否则将出现异常。 输入应该给定java Main outputFilePath inputFilePath_1 inputFilePath_2 inputFilePath_3 .....
  • NULL 博文链接:https://dmwdmc.iteye.com/blog/1931199
  • 如果您在同一模块名称空间中有多个类,但在不同的文件(甚至只是不同的module块)中定义了这些类,那么TypeScript的tsc会将它们中的每一个都包装到其自己的IIFE嵌套中; 一个用于命名空间嵌套的每个级别。...
  • Texture Merger v1.6.3

    2017-07-10 20:52:36
    Texture Merger是一款纹理集打包和动画转换工具,软件能够帮助用户对纹理集进行打包,从而提高资源加载速度和游戏性能。
  • Dubbo——Merger的实现

    2020-07-02 14:50:19
    Merger的实现 当一个接口有多种实现,消费者又需要同时引用不同的实现时,可以用group 来区分不同的实现,如下所示。 <dubbo:service group=" group1" interface=" com.xxx.testService" /> <dubbo:service...

    Merger的实现

    当一个接口有多种实现,消费者又需要同时引用不同的实现时,可以用group 来区分不同的实现,如下所示。

    <dubbo:service group=" group1" interface=" com.xxx.testService" />
    <dubbo:service group="group2" interface=" com.xxx.testService" />
    

    如果我们需要并行调用不同group 的服务,并且要把结果集合并起来,则需要用到Merger特性。Merger实现了多个服务调用后结果合并的逻辑。虽然业务层可以自行实现这个能力,但Dubo直接封装到框架中,作为一种扩展点能力,简化了业务开发的复杂度。Merger 的工作方式如图所示:

    在这里插入图片描述

    框架中会有一些默认的合并实现。Merger接口上有@SPI注解,没有默认值,属于SPI扩展点。用户可以基于Merger扩展点接口实现自己的自定义类型合并器。

    总体结构

    MergerCluster也是Cluster接口的一种实现,因此也遵循Cluter的设计模式,在invoker方法中完成具体逻辑。整个过程会使用merger接口的具体实现来合并结果集。在使用的时候,通过MergerFactory获得各种具体的Merger实现。

    Merger的12中默认实现的关系:
    在这里插入图片描述
    如果开启了Merger特性,并且未指定合并器(Merger 的具体实现),则框架会根据接口的返回类型自动匹配合并器。我们可以扩展属于自己的合并器,MergerFactory 在加载具体实现的时候,会用ExtensionLoader把所有SPI的实现都加载到缓存中。后续使用时直接从缓存中读取,如果读不到则会重新全量加载一次SPI.。内置的合并我们可以分为四类: Array、Set、List、Map,实现都比较简单,我们只列举MapMerger的实现,如代码所示:

    在这里插入图片描述
    整体思路就是,在Merger中新建一个Map,把返回的多个Map合并成一个。其他类型的合并器实现都是类似,因此不再赘述。

    MergeableClusterInvoker机制

    MergeableClusterInvoker串起了整个合并器逻辑。在了解MergeableClusterInvoker的机制之前,先回顾一下整个调用的过程:MergeableCuster#joion方法中直接生成并返回了MergeableCusterInvoker,MergeableClusterInvoker#invke方法又通过MergerFactory工厂获取不同的Merger接口实现,完成了合并的具体逻辑。

    MergeableCluster并没有继承抽象的Cluster实现,而是独立完成了自己的逻辑。因此,它的整个逻辑和之前的Failover等机制不同,其步骤如下:

    1. 前置准备。通过directory获取所有Invoker列表。

    2. 集群器初步判断某个方法是否有合并器,如果没有,则不会并行调用多个group,找到第一个可以调用的Invoker直接调用就返回了。如果有合井器,则进入第3步。

    3. 获取接口的返回类型。通过反射获得返回类型,后续要根据这个返回值查找不同的合并器。

    4. 并行调用。把Invoker的调用封装成一个个 Callable对象,放到线程池中执行,保存线程池返回的future对象到HashMap中,用于等待后续结果返回。

    5. 等待future 对象的返回结果。获取配置的超时参数,遍历(4)中得到的future对象,设置Future#get的超时时间,同步等待得到并行调用的结果。异常的结果会被忽略,正常的结果会被保存到list 中。如果最终没有返回结果,则直接返回一个空的RpcResult:如果只有一个结果,那么也直接返回,不需要再做合并;如果返回类型是void,则说明没有返回值,也直接返回。

    6. 合并结果集。如果配置的是merger=".addAll",则直接通过反射调用返回类型中的addAll方法合并结果集。例如:返回类型是Set,则调用Set.addAll来合并结果,如代码所示:

    7. 在这里插入图片描述
      调用合并器源码:
      在这里插入图片描述

    展开全文
  • activiti_merger-源码

    2021-06-28 01:13:59
    从根文件夹 ( activiti_merger ) 运行: mvn clean install 。 解压工件( activiti_merger/com.mana.activiti.merger.assembly/target/com.mana.activiti.merger.assembly-0.0.1-SNAPSHOT.tar.gz )。 运
  • metadata-merger-源码

    2021-06-22 18:12:27
    Salesforce 元数据合并 跨组织区分和合并 Salesforce 元数据的工具。 为了您的健康和安全,您应该将其部署在您自己的 Heroku ... 现在 Salesforce Metadata Merger 仅支持 Apex 类。 如果您需要其他元数据类型,请。
  • ts-merger-源码

    2021-04-01 09:07:35
    let tsm = require ( '@devonfw/ts-merger' ) ; let mergedCode : string = tsm . merge ( baseContents , pathContents , patchOverrides ) ; 存在: baseContents:字符串中基数的内容 patchContents:字符串中...
  • Csv / Txt文件合并 一个简单的工具,可以加载多个csv和/或txt文件,通过一次从每个源文件中选择一行来将它们合并为一个文件,然后将合并的文件导出到txt文件中。 ###屏幕截图 目标用户 那些拥有一些模拟文件供的的...
  • 漫画传播合并扩展 一种浏览器扩展程序,可帮助漫画阅读器将两页的跨页合并/合并到不这样做的网站(如mangaplus)中。 特征 易于使用; 一键合并图像,然后单击合并。 支持的漫画网站: Mangaplus(垂直阅读模式)。...
  • 这个库的目的 用于合并文件的库。目标是将代码生成生成的文件与手工编辑的文件成功合并,以支持涉及代码生成的开发。 如何使用 保持合并 这是一种在保留保留标记内容的同时合并文件的方法。...val merger
  • 通过从所有XML报告中收集所有元素并将它们放在一起, junit-report-merger可以创建JUnit XML格式的新测试结果报告。 命令行界面 程序包提供了一个jrm二进制文件,您可以使用该二进制文件将多个xml报告合并为一个。 ...
  • 集群——merger 目标:介绍dubbo中集群的分组聚合,介绍dubbo-cluster下merger包的源码。 前言 按组合并返回结果 ,比如菜单服务,接口一样,但有多种实现,用group区分,现在消费方需从每种group中调用一次返回结果...

    集群——merger

    目标:介绍dubbo中集群的分组聚合,介绍dubbo-cluster下merger包的源码。

    前言

    按组合并返回结果 ,比如菜单服务,接口一样,但有多种实现,用group区分,现在消费方需从每种group中调用一次返回结果,合并结果返回,这样就可以实现聚合菜单项。这个时候就要用到分组聚合。

    源码分析

    (一)MergeableCluster

    public class MergeableCluster implements Cluster {
    
        public static final String NAME = "mergeable";
    
        @Override
        public <T> Invoker<T> join(Directory<T> directory) throws RpcException {
            // 创建MergeableClusterInvoker
            return new MergeableClusterInvoker<T>(directory);
        }
    
    }

    该类实现了Cluster接口,是分组集合的集群实现。

    (二)MergeableClusterInvoker

    该类是分组聚合的实现类,其中最关机的就是invoke方法。

    @Override
    @SuppressWarnings("rawtypes")
    public Result invoke(final Invocation invocation) throws RpcException {
        // 获得invoker集合
        List<Invoker<T>> invokers = directory.list(invocation);
    
        /**
         * 获得是否merger
         */
        String merger = getUrl().getMethodParameter(invocation.getMethodName(), Constants.MERGER_KEY);
        // 如果没有设置需要聚合,则只调用一个invoker的
        if (ConfigUtils.isEmpty(merger)) { // If a method doesn't have a merger, only invoke one Group
            // 只要有一个可用就返回
            for (final Invoker<T> invoker : invokers) {
                if (invoker.isAvailable()) {
                    return invoker.invoke(invocation);
                }
            }
            return invokers.iterator().next().invoke(invocation);
        }
    
        // 返回类型
        Class<?> returnType;
        try {
            // 获得返回类型
            returnType = getInterface().getMethod(
                    invocation.getMethodName(), invocation.getParameterTypes()).getReturnType();
        } catch (NoSuchMethodException e) {
            returnType = null;
        }
    
        // 结果集合
        Map<String, Future<Result>> results = new HashMap<String, Future<Result>>();
        // 循环invokers
        for (final Invoker<T> invoker : invokers) {
            // 获得每次调用的future
            Future<Result> future = executor.submit(new Callable<Result>() {
                @Override
                public Result call() throws Exception {
                    // 回调,把返回结果放入future
                    return invoker.invoke(new RpcInvocation(invocation, invoker));
                }
            });
            // 加入集合
            results.put(invoker.getUrl().getServiceKey(), future);
        }
    
        Object result = null;
    
        List<Result> resultList = new ArrayList<Result>(results.size());
    
        // 获得超时时间
        int timeout = getUrl().getMethodParameter(invocation.getMethodName(), Constants.TIMEOUT_KEY, Constants.DEFAULT_TIMEOUT);
        // 遍历每一个结果
        for (Map.Entry<String, Future<Result>> entry : results.entrySet()) {
            Future<Result> future = entry.getValue();
            try {
                // 获得调用返回的结果
                Result r = future.get(timeout, TimeUnit.MILLISECONDS);
                if (r.hasException()) {
                    log.error("Invoke " + getGroupDescFromServiceKey(entry.getKey()) + 
                                    " failed: " + r.getException().getMessage(), 
                            r.getException());
                } else {
                    // 加入集合
                    resultList.add(r);
                }
            } catch (Exception e) {
                throw new RpcException("Failed to invoke service " + entry.getKey() + ": " + e.getMessage(), e);
            }
        }
    
        // 如果为空,则返回空的结果
        if (resultList.isEmpty()) {
            return new RpcResult((Object) null);
        } else if (resultList.size() == 1) {
            // 如果只有一个结果,则返回该结果
            return resultList.iterator().next();
        }
    
        // 如果返回类型是void,也就是没有返回值,那么返回空结果
        if (returnType == void.class) {
            return new RpcResult((Object) null);
        }
    
        // 根据方法来合并,将调用返回结果的指定方法进行合并
        if (merger.startsWith(".")) {
            merger = merger.substring(1);
            Method method;
            try {
                // 获得方法
                method = returnType.getMethod(merger, returnType);
            } catch (NoSuchMethodException e) {
                throw new RpcException("Can not merge result because missing method [ " + merger + " ] in class [ " + 
                        returnType.getClass().getName() + " ]");
            }
    
            // 有 Method ,进行合并
            if (!Modifier.isPublic(method.getModifiers())) {
                method.setAccessible(true);
            }
            // 从集合中移除
            result = resultList.remove(0).getValue();
            try {
                // 方法返回类型匹配,合并时,修改 result
                if (method.getReturnType() != void.class
                        && method.getReturnType().isAssignableFrom(result.getClass())) {
                    for (Result r : resultList) {
                        result = method.invoke(result, r.getValue());
                    }
                } else {
                    // 方法返回类型不匹配,合并时,不修改 result
                    for (Result r : resultList) {
                        method.invoke(result, r.getValue());
                    }
                }
            } catch (Exception e) {
                throw new RpcException("Can not merge result: " + e.getMessage(), e);
            }
        } else {
            // 基于 Merger
            Merger resultMerger;
            // 如果是默认的方式
            if (ConfigUtils.isDefault(merger)) {
                // 获得该类型的合并方式
                resultMerger = MergerFactory.getMerger(returnType);
            } else {
                // 如果不是默认的,则配置中指定获得Merger的实现类
                resultMerger = ExtensionLoader.getExtensionLoader(Merger.class).getExtension(merger);
            }
            if (resultMerger != null) {
                List<Object> rets = new ArrayList<Object>(resultList.size());
                // 遍历返回结果
                for (Result r : resultList) {
                    // 加入到rets
                    rets.add(r.getValue());
                }
                // 合并
                result = resultMerger.merge(
                        rets.toArray((Object[]) Array.newInstance(returnType, 0)));
            } else {
                throw new RpcException("There is no merger to merge result.");
            }
        }
        // 返回结果
        return new RpcResult(result);
    }

    前面部分在讲获得调用的结果,后面部分是对结果的合并,合并有两种方式,根据配置不同可用分为基于方法的合并和基于merger的合并。

    (三)MergerFactory

    Merger 工厂类,获得指定类型的Merger 对象。

    public class MergerFactory {
    
        /**
         * Merger 对象缓存
         */
        private static final ConcurrentMap<Class<?>, Merger<?>> mergerCache =
                new ConcurrentHashMap<Class<?>, Merger<?>>();
    
        /**
         * 获得指定类型的Merger对象
         * @param returnType
         * @param <T>
         * @return
         */
        public static <T> Merger<T> getMerger(Class<T> returnType) {
            Merger result;
            // 如果类型是集合
            if (returnType.isArray()) {
                // 获得类型
                Class type = returnType.getComponentType();
                // 从缓存中获得该类型的Merger对象
                result = mergerCache.get(type);
                // 如果为空,则
                if (result == null) {
                    // 初始化所有的 Merger 扩展对象,到 mergerCache 缓存中。
                    loadMergers();
                    // 从集合中取出对应的Merger对象
                    result = mergerCache.get(type);
                }
                // 如果结果为空,则直接返回ArrayMerger的单例
                if (result == null && !type.isPrimitive()) {
                    result = ArrayMerger.INSTANCE;
                }
            } else {
                // 否则直接从mergerCache中取出
                result = mergerCache.get(returnType);
                // 如果为空
                if (result == null) {
                    // 初始化所有的 Merger 扩展对象,到 mergerCache 缓存中。
                    loadMergers();
                    // 从集合中取出
                    result = mergerCache.get(returnType);
                }
            }
            return result;
        }
    
        /**
         * 初始化所有的 Merger 扩展对象,到 mergerCache 缓存中。
         */
        static void loadMergers() {
            // 获得Merger所有的扩展对象名
            Set<String> names = ExtensionLoader.getExtensionLoader(Merger.class)
                    .getSupportedExtensions();
            // 遍历
            for (String name : names) {
                // 加载每一个扩展实现,然后放入缓存。
                Merger m = ExtensionLoader.getExtensionLoader(Merger.class).getExtension(name);
                mergerCache.putIfAbsent(ReflectUtils.getGenericClass(m.getClass()), m);
            }
        }
    
    }

    逻辑比较简单。

    (四)ArrayMerger

    因为不同的类型有不同的Merger实现,我们可以来看看这个图片:

    merger

    可以看到有好多好多,我就讲解其中的一种,偷懒一下,其他的麻烦有兴趣的去看看源码了。

    public class ArrayMerger implements Merger<Object[]> {
    
        /**
         * 单例
         */
        public static final ArrayMerger INSTANCE = new ArrayMerger();
    
        @Override
        public Object[] merge(Object[]... others) {
            // 如果长度为0  则直接返回
            if (others.length == 0) {
                return null;
            }
            // 总长
            int totalLen = 0;
            // 遍历所有需要合并的对象
            for (int i = 0; i < others.length; i++) {
                Object item = others[i];
                // 如果为数组
                if (item != null && item.getClass().isArray()) {
                    // 累加数组长度
                    totalLen += Array.getLength(item);
                } else {
                    throw new IllegalArgumentException((i + 1) + "th argument is not an array");
                }
            }
    
            if (totalLen == 0) {
                return null;
            }
    
            // 获得数组类型
            Class<?> type = others[0].getClass().getComponentType();
    
            // 创建长度
            Object result = Array.newInstance(type, totalLen);
            int index = 0;
            // 遍历需要合并的对象
            for (Object array : others) {
                // 遍历每个数组中的数据
                for (int i = 0; i < Array.getLength(array); i++) {
                    // 加入到最终结果中
                    Array.set(result, index++, Array.get(array, i));
                }
            }
            return (Object[]) result;
        }
    
    }

    是不是很简单,就是循环合并就可以了。

    后记

    该部分相关的源码解析地址: https://github.com/CrazyHZM/i...

    该文章讲解了集群中关于分组聚合实现的部分。接下来我将开始对集群模块关于路由部分进行讲解。

    展开全文
  • PDF Merger Mac是一款Mac OS X系统下的应用程序,可以让您把多个PDF文件合并成一个PDF文件。合并后的PDF文件会保持原有的排版、格式、页面大小以及页面方向。PDF Merger Mac也允许您调整PDF合
  • merger-源码

    2021-03-19 21:04:25
    合并 关于 merge是一个开源Web应用程序,其(1)组织和合并在安全评估或渗透测试期间生成的所有中间数据,以及(2)基于此类数据和预定义的模板生成报告。 该Web应用程序使用不同的对象(系统,端口,Web应用程序,...
  • Manifest merger failed with multiple errors, see logs Build:failed The 'kotlin-android-extensions' Gradle plugin is deprecated. Please use this migration guide ...

    android studio的报错提示:

    ......
    :app:processDebugMainManifest
    Manifest merger failed with multiple errors, see logs
    

    :app:processDebugMainManifest对应:
    在这里插入图片描述

    > Task :app:processDebugMainManifest FAILED
    D:\Android2\CityList1\app\src\main\AndroidManifest.xml:20:5-81 Warning:
    	Element uses-permission#android.permission.WRITE_EXTERNAL_STORAGE at AndroidManifest.xml:20:5-81 duplicated with element declared at AndroidManifest.xml:11:5-81
    D:\Android2\CityList1\app\src\main\AndroidManifest.xml:8:5-10:41 Error:
    	uses-sdk:minSdkVersion 8 cannot be smaller than version 9 declared in library [com.android.support:appcompat-v7:25.0.1] C:\Users\Administrator\.gradle\wrapper\dists\gradle-6.7.1-all\caches\transforms-2\files-2.1\c7595eb13b704f08e6092b7e9dcde643\appcompat-v7-25.0.1\AndroidManifest.xml as the library might be using APIs not available in 8
    	Suggestion: use a compatible library with a minSdk of at most 8,
    		or increase this project's minSdk version to at least 9,
    		or use tools:overrideLibrary="android.support.v7.appcompat" to force usage (may lead to runtime failures)
    
    See http://g.co/androidstudio/manifest-merger for more information about the manifest merger.
    
    
    Execution failed for task ':app:processDebugMainManifest'.
    > Manifest merger failed with multiple errors, see logs
    
    * Try:
    Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
    

    错误到底在哪,可以发现:
    :app:processDebugMainManifest对应的中一句:

    D:\Android2\CityList1\app\src\main\AndroidManifest.xml:8:5-10:41 Error:
    	uses-sdk:minSdkVersion 8 cannot be smaller than version 9 declared in library 
    

    这报错信息中AndroidManifest.xml,只记得要在AndroidManifest点击“Merged Manifest”
    在这里插入图片描述
    Merged Manifest中发现一个小问题,报错信息如下图:
    在这里插入图片描述
    问题我容易找到了,按照这种方法就可以很轻松的找到冲突的错误所在

    Error: uses-sdk:minSdkVersion 8 cannot be smaller than version 9 declared in library怎么解决:
    1.直接删除(不一定)如下图:
    在这里插入图片描述
    看一下:
    uses-sdk:minSdkVersion 8 cannot be smaller than version 9 declared in library [com.android.support:appcompat-v7:25.0.1] C:\Users\Administrator.gradle\wrapper\dists\gradle-6.7.1-all\caches\transforms-2\files-2.1\c7595eb13b704f08e6092b7e9dcde643\appcompat-v7-25.0.1\AndroidManifest.xml as the library might be using APIs not available in 8
    可能app的build.gradle中的minSdkVersion有问题:

    minSdkVersion 8
    

    minSdkVersion 8的8好像不存在
    解决:
    改minSdkVersion多少(多少必须有存在)

    展开全文

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 10,899
精华内容 4,359
关键字:

merger