Elasticsearch High Level REST Client
Compatibility
The Java High Level REST Client requires Java 1.8 and depends on the Elasticsearch core project. The client version is the same as the Elasticsearch version that the client was developed for. It accepts the same request arguments as the TransportClient
and returns the same response objects. See the Migration Guide if you need to migrate an application from TransportClient
to the new REST client.
The High Level Client is guaranteed to be able to communicate with any Elasticsearch node running on the same major version and greater or equal minor version. It doesn’t need to be in the same minor version as the Elasticsearch nodes it communicates with, as it is forward compatible meaning that it supports communicating with later versions of Elasticsearch than the one it was developed for.
The 6.0 client is able to communicate with any 6.x Elasticsearch node, while the 6.1 client is for sure able to communicate with 6.1, 6.2 and any later 6.x version, but there may be incompatibility issues when communicating with a previous Elasticsearch node version, for instance between 6.1 and 6.0, in case the 6.1 client supports new request body fields for some APIs that are not known by the 6.0 node(s).
It is recommended to upgrade the High Level Client when upgrading the Elasticsearch cluster to a new major version, as REST API breaking changes may cause unexpected results depending on the node that is hit by the request, and newly added APIs will only be supported by the newer version of the client. The client should always be updated last, once all of the nodes in the cluster have been upgraded to the new major version.
Test Case
ES:5.2.2
POM:
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>6.2.4</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-client</artifactId>
<version>6.2.4</version>
</dependency>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>6.2.4</version>
</dependency>
A RestHighLevelClient
instance needs a REST low-level client builder to be built as follows:
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(
new HttpHost("localhost", 9200, "http"),
new HttpHost("localhost", 9201, "http")));
The high-level client will internally create the low-level client used to perform requests based on the provided builder. That low-level client maintains a pool of connections and starts some threads so you should close the high-level client when you are well and truly done with it and it will in turn close the internal low-level client to free those resources. This can be done through the close
:
client.close();
In the rest of this documentation about the Java High Level Client, the RestHighLevelClient
instance will be referenced as client
.
The Java High Level REST Client supports the following APIs:
- Indices APIs
- Single document APIs
- Multi document APIs
- Search APIs
- Miscellaneous APIs
package com.ftofs.esclient.service; import com.ftofs.esclient.dao.ImMessageLogRepository; import com.ftofs.esclient.dao.WantCommentImageRepository; import com.ftofs.esclient.dao.WantCommentRepository; import com.ftofs.esclient.dao.WantPostImageRepository; import com.ftofs.esclient.dao.WantPostRepository; import com.ftofs.esclient.domain.ImMessageLog; import com.ftofs.esclient.domain.WantComment; import com.ftofs.esclient.domain.WantPost; import com.ftofs.esclient.vo.CommentImageResultVo; import com.ftofs.esclient.vo.CommentResultVo; import com.ftofs.esclient.vo.ImResultVo; import com.ftofs.esclient.vo.PostImageResultVo; import com.ftofs.esclient.vo.PostResultVo; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.List; @Component public class ReindexService { @Autowired private WantPostRepository wantPostRepository; @Autowired private WantCommentRepository wantCommentRepository; @Autowired private WantPostImageRepository wantPostImageRepository; @Autowired private WantCommentImageRepository wantCommentImageRepository; @Autowired private ImMessageLogRepository imMessageLogRepository; private <T> String emptyToNull(T value) { if (value == null) { return null; } else { return String.valueOf(value); } } /** * 重置所有IM消息記錄 * @return */ public List<ImResultVo> getImMessageResultVoList() { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); List<ImResultVo> imResultVoList = new ArrayList<>(); List<ImMessageLog> imMessageLogList = imMessageLogRepository.findAll(); imMessageLogList.forEach(x -> { ImResultVo imResultVo = new ImResultVo(); imResultVo.setGroupName(x.getGroupName()); imResultVo.setId(String.valueOf(x.getId())); imResultVo.setMessageContent(x.getMessageContent()); imResultVo.setMessageType(x.getMessageType()); imResultVo.setSendFrom(x.getSendFrom()); imResultVo.setSendTime(sdf.format(x.getSendTime())); imResultVo.setTarget(x.getTarget()); imResultVo.setTargetType(x.getTargetType()); imResultVoList.add(imResultVo); }); return imResultVoList; } /** * 重置所有評論記錄 * @return */ public List<CommentResultVo> getCommentResultVoList() { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); List<CommentResultVo> commentResultVoList = new ArrayList<>(); List<WantComment> wantCommentList = wantCommentRepository.findAll(); wantCommentList.forEach(x -> { CommentResultVo commentResultVo = new CommentResultVo(); commentResultVo.setReplyCommentId(emptyToNull(x.getReplyCommentId())); commentResultVo.setRelateStoreId(emptyToNull(x.getRelateStoreId())); commentResultVo.setRelatePostId(emptyToNull(x.getRelateStoreId())); commentResultVo.setRelateCommonId(emptyToNull(x.getRelateCommonId())); commentResultVo.setDeep(emptyToNull(x.getDeep())); commentResultVo.setCommentUnlike(emptyToNull(x.getCommentUnlike())); commentResultVo.setCommentType(emptyToNull(x.getCommentType())); commentResultVo.setCommentState(emptyToNull(x.getCommentState())); commentResultVo.setCommentShare(emptyToNull(x.getCommentShare())); commentResultVo.setCommentReply(emptyToNull(x.getCommentReply())); commentResultVo.setCommentLike(emptyToNull(x.getCommentLike())); commentResultVo.setCommentId(emptyToNull(x.getCommentId())); commentResultVo.setCommentFavor(emptyToNull(x.getCommentFavor())); commentResultVo.setCommentChannel(emptyToNull(x.getCommentChannel())); commentResultVo.setCreateTime(sdf.format(x.getCreateTime())); commentResultVo.setCreateBy(x.getCreateBy()); commentResultVo.setContent(x.getContent()); List<CommentImageResultVo> commentImages = new ArrayList<>(); List<String> imageUrlList = wantCommentImageRepository.findWantCommentImagesByCommentId(x.getCommentId()); imageUrlList.forEach(url -> { CommentImageResultVo commentImageResultVo = new CommentImageResultVo(); commentImageResultVo.setImageUrl(url); commentImages.add(commentImageResultVo); }); commentResultVo.setImages(commentImages); commentResultVoList.add(commentResultVo); }); return commentResultVoList; } /** * 重置所有貼文記錄 * @return */ public List<PostResultVo> getPostResultVoList() { SimpleDateFormat sdfDateTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); SimpleDateFormat sdfDate = new SimpleDateFormat("yyyy-MM-dd"); List<PostResultVo> postResultVoList = new ArrayList<>(); List<WantPost> wantPostList = wantPostRepository.findAll(); wantPostList.forEach(x -> { PostResultVo postResultVo = new PostResultVo(); postResultVo.setBudgetPrice(emptyToNull(x.getBudgetPrice())); postResultVo.setContent(x.getContent()); postResultVo.setCreateBy(x.getCreateBy()); postResultVo.setCreateTime(sdfDateTime.format(x.getCreateTime())); postResultVo.setExpiresDate(sdfDate.format(x.getExpiresDate())); postResultVo.setIsDelete(emptyToNull(x.getIsDelete())); postResultVo.setIsPublish(emptyToNull(x.getIsPublish())); postResultVo.setKeyword(x.getKeyword()); postResultVo.setPostCategory(x.getPostCategory()); postResultVo.setPostId(emptyToNull(x.getPostId())); postResultVo.setPostTag(x.getPostTag()); postResultVo.setPostType(emptyToNull(x.getPostType())); postResultVo.setPostFavor(emptyToNull(x.getPostFavor())); postResultVo.setPostLike(emptyToNull(x.getPostLike())); postResultVo.setPostUnlike(emptyToNull(x.getPostUnlike())); postResultVo.setPostShare(emptyToNull(x.getPostShare())); postResultVo.setPostReply(emptyToNull(x.getPostReply())); postResultVo.setPostView(emptyToNull(x.getPostView())); postResultVo.setTitle(x.getTitle()); postResultVo.setCoverImage(x.getCoverImage()); postResultVo.setApproveReason(x.getApproveReason()); List<CommentResultVo> comments = new ArrayList<>(); List<WantComment> wantCommentList = wantCommentRepository.findWantCommentsByPostId(x.getPostId()); wantCommentList.forEach(y -> { CommentResultVo commentResultVo = new CommentResultVo(); commentResultVo.setContent(y.getContent()); commentResultVo.setCreateBy(y.getCreateBy()); commentResultVo.setCreateTime(sdfDateTime.format(y.getCreateTime())); commentResultVo.setCommentChannel(emptyToNull(y.getCommentChannel())); commentResultVo.setCommentFavor(emptyToNull(y.getCommentFavor())); commentResultVo.setCommentId(emptyToNull(y.getCommentId())); commentResultVo.setCommentLike(emptyToNull(y.getCommentLike())); commentResultVo.setCommentReply(emptyToNull(y.getCommentReply())); commentResultVo.setCommentShare(emptyToNull(y.getCommentShare())); commentResultVo.setCommentState(emptyToNull(y.getCommentState())); commentResultVo.setCommentType(emptyToNull(y.getCommentType())); commentResultVo.setCommentUnlike(emptyToNull(y.getCommentUnlike())); commentResultVo.setDeep(emptyToNull(y.getDeep())); commentResultVo.setRelateCommonId(emptyToNull(y.getRelateCommonId())); commentResultVo.setRelatePostId(emptyToNull(y.getRelatePostId())); commentResultVo.setRelateStoreId(emptyToNull(y.getRelateStoreId())); commentResultVo.setReplyCommentId(emptyToNull(y.getReplyCommentId())); List<CommentImageResultVo> commentImages = new ArrayList<>(); List<String> imageUrlList = wantCommentImageRepository.findWantCommentImagesByCommentId(y.getCommentId()); imageUrlList.forEach(url -> { CommentImageResultVo commentImageResultVo = new CommentImageResultVo(); commentImageResultVo.setImageUrl(url); commentImages.add(commentImageResultVo); }); commentResultVo.setImages(commentImages); comments.add(commentResultVo); }); postResultVo.setComments(comments); List<PostImageResultVo> postImages = new ArrayList<>(); List<String> imageUrlList = wantPostImageRepository.findWantPostImagesByPostId(x.getPostId()); imageUrlList.forEach(url -> { PostImageResultVo postImageResultVo = new PostImageResultVo(); postImageResultVo.setImageUrl(url); postImages.add(postImageResultVo); }); postResultVo.setImages(postImages); postResultVoList.add(postResultVo); }); return postResultVoList; } }
package com.ftofs.esclient.common; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; public class ESAnnotation { @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface IndexAnnotation { String field(); } }
package com.ftofs.esclient.common; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.TimeZone; /** * JSON帮助类 */ public class JsonHelper { private static final Logger log = LoggerFactory.getLogger(JsonHelper.class); final static ObjectMapper objectMapper; static { objectMapper = new ObjectMapper(); objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")); objectMapper.setTimeZone(TimeZone.getTimeZone("GMT+8")); } public static ObjectMapper getObjectMapper() { return objectMapper; } /** * JSON串转换为Java泛型对象 * @param <T> * @param jsonString JSON字符串 * @param tr TypeReference,例如: new TypeReference< List<FamousUser> >(){} * @return List对象列表 */ public static <T> T toGenericObject(String jsonString, TypeReference<T> tr) { if (jsonString == null || "".equals(jsonString)) { return null; } else { try { return (T) objectMapper.readValue(jsonString, tr); } catch (Exception e) { log.warn(jsonString); log.warn("json error:" + e.getMessage()); } } return null; } /** * Json字符串转Java对象 * @param jsonString * @param c * @return */ public static Object toObject(String jsonString, Class<?> c) { if (jsonString == null || "".equals(jsonString)) { return ""; } else { try { return objectMapper.readValue(jsonString, c); } catch (Exception e) { log.warn("json error:" + e.getMessage()); } } return null; } /** * Java对象转Json字符串 * @param object Java对象,可以是对象,数组,List,Map等 * @return json 字符串 */ public static String toJson(Object object) { String jsonString = ""; try { jsonString = objectMapper.writeValueAsString(object); } catch (Exception e) { log.warn("json error:" + e.getMessage()); } return jsonString; } /** * Json字符串转JsonNode * @param jsonString * @return */ public static JsonNode toJsonNode(String jsonString) { try { return objectMapper.readTree(jsonString); } catch (IOException e) { e.printStackTrace(); log.warn("json error:" + e.getMessage()); } return null; } }
package com.ftofs.esclient.controller; import com.ftofs.esclient.ESRestService; import com.ftofs.esclient.service.ReindexService; import com.ftofs.esclient.vo.CommentResultVo; import com.ftofs.esclient.vo.ImResultVo; import com.ftofs.esclient.vo.PostResultVo; import com.ftofs.esclient.vo.SearchCommentResultVo; import com.ftofs.esclient.vo.SearchImResultVo; import com.ftofs.esclient.vo.SearchPostResultVo; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.HashMap; import java.util.List; @RestController @RequestMapping("") @Api(tags="ESRestController") public class ESRestController { @Autowired private ESRestService restService; @Autowired private ReindexService reindexService; @Value("${esIndexImMessage}") private String esIndexImMessage; @Value("${esTypeImMessage}") private String esTypeImMessage; @Value("${esIndexWantPost}") private String esIndexWantPost; @Value("${esTypeWantPost}") private String esTypeWantPost; @Value("${esIndexWantComment}") private String esIndexWantComment; @Value("${esTypeWantComment}") private String esTypeWantComment; @PostMapping("/im/init") @ApiOperation(value = "IM消息索引初始化") public void imMessageInit() { restService.createImMessageIndex(); } @PostMapping("/im/delete/{id}") @ApiOperation(value = "刪除IM消息") public void deleteImMessageDocument(@PathVariable String id) { restService.deleteImMessageDocument(id); } @PostMapping("/post/init") @ApiOperation(value = "貼文索引初始化") public void wantPostInit() { restService.createWantPostIndex(); } @PostMapping("/post/delete/{id}") @ApiOperation(value = "刪除貼文") public void deleteWantPostDocument(@PathVariable String id) { restService.deleteWantPostDocument(id); } @PostMapping("/comment/init") @ApiOperation(value = "評論索引初始化") public void wantCommentInit() { restService.createWantCommentIndex(); } @PostMapping("/comment/delete/{id}") @ApiOperation(value = "刪除評論") public void deleteWantCommentDocument(@PathVariable String id) { restService.deleteWantCommentDocument(id); } @PostMapping("/im/reindexRange") @ApiOperation(value = "批量添加IM消息記錄") public void imReindexRange(@RequestBody List<ImResultVo> imResultVoList) { restService.imReindexRange(imResultVoList); } @PostMapping("/post/reindexRange") @ApiOperation(value = "批量添加貼文") public void postReindexRange(@RequestBody List<PostResultVo> postResultVoList) { restService.postReindexRange(postResultVoList); } @PostMapping("/comment/reindexRange") @ApiOperation(value = "批量添加評論") public void commentReindexRange(@RequestBody List<CommentResultVo> commentResultVoList) { restService.commentReindexRange(commentResultVoList); } @PostMapping("/im/insertOrUpdate") @ApiOperation(value = "添加IM消息") public void imMessageInsertOrUpdate(@RequestBody ImResultVo imResultVo) { restService.insertOrUpdate(esIndexImMessage, esTypeImMessage, imResultVo); } @PostMapping("/post/insertOrUpdate") @ApiOperation(value = "添加貼文") public void wantPostInsertOrUpdate(@RequestBody PostResultVo postResultVo) { restService.insertOrUpdate(esIndexWantPost, esTypeWantPost, postResultVo); } @PostMapping("/comment/insertOrUpdate") @ApiOperation(value = "添加評論") public void wantCommentInsertOrUpdate(@RequestBody CommentResultVo commentResultVo) { restService.insertOrUpdate(esIndexWantComment, esTypeWantComment, commentResultVo); } @GetMapping("/im/search") @ApiOperation(value = "IM消息搜索") public SearchImResultVo imMessageSearch(@RequestBody HashMap<String, Object> queryMap) { return restService.imMessageSearch(queryMap); } @GetMapping("/post/search") @ApiOperation(value = "貼文搜索") public SearchPostResultVo wantPostSearch(@RequestBody HashMap<String, Object> queryMap) { return restService.wantPostSearch(queryMap); } @GetMapping("/comment/search") @ApiOperation(value = "評論搜索") public SearchCommentResultVo wantCommentSearch(@RequestBody HashMap<String, Object> queryMap) { return restService.wantCommentSearch(queryMap); } @PostMapping("/im/reindexAll") @ApiOperation(value = "重置所有IM消息記錄") public void imReindexAll() { restService.imReindexRange(reindexService.getImMessageResultVoList()); } @PostMapping("/post/reindexAll") @ApiOperation(value = "重置所有貼文記錄") public void postReindexAll() { restService.postReindexRange(reindexService.getPostResultVoList()); } @PostMapping("/comment/reindexAll") @ApiOperation(value = "重置所有評論記錄") public void commentReindexAll() { restService.commentReindexRange(reindexService.getCommentResultVoList()); } }
package com.ftofs.esclient; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import springfox.documentation.builders.ApiInfoBuilder; import springfox.documentation.builders.PathSelectors; import springfox.documentation.builders.RequestHandlerSelectors; import springfox.documentation.service.ApiInfo; import springfox.documentation.service.Contact; import springfox.documentation.spi.DocumentationType; import springfox.documentation.spring.web.plugins.Docket; import springfox.documentation.swagger2.annotations.EnableSwagger2; @EnableSwagger2 @Configuration public class Swagger2 { @Bean public Docket createRestApi() { return new Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo()) .select() .apis(RequestHandlerSelectors.basePackage("com.ftofs.esclient.controller")) .paths(PathSelectors.any()) .build(); } private ApiInfo apiInfo() { return new ApiInfoBuilder() .title("Elasticsearch Rest High/Low Level Client 接口文檔說明") .contact(new Contact("Nick.Chung", "http://cnblogs.com/ncore", "46638441@qq.com")) .description("简单优雅的Restful风格") .termsOfServiceUrl("https://github.com/mbhybird") .version("1.0") .build(); } }
package com.ftofs.esclient; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class ESClientApplication { public static void main(String[] args) { SpringApplication.run(ESClientApplication.class, args); } }
server.port=9500 esHost = 127.0.0.1 #dev:192.168.5.30 #train:192.168.5.32 esPort = 9200 esScheme = http esIndexImMessage = index_im_msg esIndexWantPost = index_want_post esIndexWantComment = index_want_comment esTypeImMessage = im_msg esTypeWantPost = want_post esTypeWantComment = want_comment spring.datasource.url = jdbc:mysql://192.168.5.30:3306/twdb?characterEncoding=utf8 spring.datasource.username=root spring.datasource.password=123456 spring.jpa.database=mysql spring.jpa.show-sql=true spring.jpa.hibernate.ddl-auto=none spring.jpa.hibernate.naming-strategy = org.hibernate.cfg.ImprovedNamingStrategy spring.jpa.properties.hibernate.dialect= org.hibernate.dialect.MySQL5Dialect #logging.level.root=WARN ##logging.level.org.springframework.web=INFO ##logging.file=/log/es.log ##logging.pattern.console=%d{yyyy/MM/dd-HH:mm:ss} [%thread] %-5level %logger- %msg%n ##logging.pattern.file=%d{yyyy/MM/dd-HH:mm} [%thread] %-5level %logger- %msg%n
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.3.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.ftofs</groupId> <artifactId>esclient</artifactId> <version>0.0.1-SNAPSHOT</version> <name>esclient</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.elasticsearch.client</groupId> <artifactId>elasticsearch-rest-high-level-client</artifactId> <version>6.2.4</version> </dependency> <dependency> <groupId>org.elasticsearch.client</groupId> <artifactId>elasticsearch-rest-client</artifactId> <version>6.2.4</version> </dependency> <dependency> <groupId>org.elasticsearch</groupId> <artifactId>elasticsearch</artifactId> <version>6.2.4</version> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>2.8.0</version> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>2.8.0</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.16.10</version> <scope>provided</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <executions> <execution> <phase>package</phase> <goals><goal>shade</goal></goals> <configuration> <relocations> <relocation> <pattern>org.apache.http</pattern> <shadedPattern>hidden.org.apache.http</shadedPattern> </relocation> <relocation> <pattern>org.apache.logging</pattern> <shadedPattern>hidden.org.apache.logging</shadedPattern> </relocation> <relocation> <pattern>org.apache.commons.codec</pattern> <shadedPattern>hidden.org.apache.commons.codec</shadedPattern> </relocation> <relocation> <pattern>org.apache.commons.logging</pattern> <shadedPattern>hidden.org.apache.commons.logging</shadedPattern> </relocation> </relocations> </configuration> </execution> </executions> </plugin> </plugins> </build> </project>