移除不适合以javaagent模式启动的插件,避免混合使用造成classloader出现问题。
This commit is contained in:
parent
1c14cfc69e
commit
edd0365fad
|
|
@ -12,9 +12,7 @@
|
|||
<artifactId>skywalking-sdk-plugin</artifactId>
|
||||
<modules>
|
||||
<module>dubbo-plugin</module>
|
||||
<module>spring-plugin</module>
|
||||
<module>jdbc-plugin</module>
|
||||
<module>web-plugin</module>
|
||||
<module>httpClient-4.x-plugin</module>
|
||||
<module>jedis-2.x-plugin</module>
|
||||
<module>tomcat-7.x-8.x-plugin</module>
|
||||
|
|
@ -77,4 +75,4 @@
|
|||
<url>https://api.bintray.com/maven/wu-sheng/skywalking/com.ai.cloud.skywalking-sdk-plugin/;publish=1</url>
|
||||
</repository>
|
||||
</distributionManagement>
|
||||
</project>
|
||||
</project>
|
||||
|
|
|
|||
|
|
@ -1,37 +0,0 @@
|
|||
# 如何追踪注册在Spring中类实例的方法调用?
|
||||
- 引入所需插件
|
||||
```xml
|
||||
<!-- Spring插件,监控所有Spring托管对象的调用-->
|
||||
<dependency>
|
||||
<groupId>com.ai.cloud</groupId>
|
||||
<artifactId>skywalking-spring-plugin</artifactId>
|
||||
<version>{latest_version}</version>
|
||||
</dependency>
|
||||
```
|
||||
- Spring配置文件头部,配置所需的命名空间
|
||||
```xml
|
||||
xmlns:skywalking="http://cloud.asiainfo.com/schema/skywalking"
|
||||
xsi:schemaLocation="http://cloud.asiainfo.com/schema/skywalking
|
||||
http://cloud.asiainfo.com/schema/skywalking/skywalking.xsd"
|
||||
```
|
||||
- 典型Spring配置文件如下
|
||||
```xml
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:context="http://www.springframework.org/schema/context"
|
||||
xmlns:skywalking="http://cloud.asiainfo.com/schema/skywalking"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
|
||||
http://www.springframework.org/schema/context
|
||||
http://www.springframework.org/schema/context/spring-context-3.0.xsd
|
||||
http://cloud.asiainfo.com/schema/skywalking
|
||||
http://cloud.asiainfo.com/schema/skywalking/skywalking.xsd">
|
||||
```
|
||||
- Spring配置文件中,设置需要追踪包名、类名或方法名。可配置多个
|
||||
```xml
|
||||
<skywalking:trace packageExpression="com.ai.app.domain.test.*" classExpression="*"/>
|
||||
<skywalking:trace packageExpression="com.ai.app.domain.test..*" classExpression="className*"/>
|
||||
```
|
||||
- 对于方法的追踪,仅限于实例级的public方法。其他方法由于Java运行时原因,无法追踪。
|
||||
- 部分类由于被Spring代理后,类名发生变化,可能造成无法追踪
|
||||
|
||||
|
|
@ -1,120 +0,0 @@
|
|||
<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">
|
||||
<parent>
|
||||
<artifactId>skywalking-sdk-plugin</artifactId>
|
||||
<groupId>com.ai.cloud</groupId>
|
||||
<version>1.0-Final</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>skywalking-spring-plugin</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>spring-plugin</name>
|
||||
<url>http://maven.apache.org</url>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.aspectj</groupId>
|
||||
<artifactId>aspectjweaver</artifactId>
|
||||
<version>1.8.7</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.ai.cloud</groupId>
|
||||
<artifactId>skywalking-api</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>3.8.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-core</artifactId>
|
||||
<version>2.4.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context</artifactId>
|
||||
<version>3.2.0.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<!--
|
||||
<dependency>
|
||||
<groupId>com.ai.cloud</groupId>
|
||||
<artifactId>skywalking-auth</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
-->
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-tx</artifactId>
|
||||
<version>3.2.0.RELEASE</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-jdbc</artifactId>
|
||||
<version>3.2.9.RELEASE</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-dbcp2</artifactId>
|
||||
<version>2.1.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<version>5.1.38</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-resources-plugin</artifactId>
|
||||
<version>2.4.3</version>
|
||||
<configuration>
|
||||
<encoding>${project.build.sourceEncoding}</encoding>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<!-- 源码插件 -->
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-source-plugin</artifactId>
|
||||
<!-- 发布时自动将源码同时发布的配置 -->
|
||||
<executions>
|
||||
<execution>
|
||||
<id>attach-sources</id>
|
||||
<goals>
|
||||
<goal>jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<distributionManagement>
|
||||
<repository>
|
||||
<id>bintray-wu-sheng-sky-walking-repository</id>
|
||||
<name>wu-sheng-sky-walking-repository</name>
|
||||
<url>https://api.bintray.com/maven/wu-sheng/skywalking/com.ai.cloud.skywalking-spring-plugin/;publish=1</url>
|
||||
</repository>
|
||||
</distributionManagement>
|
||||
</project>
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
package com.ai.cloud.skywalking.plugin.spring;
|
||||
|
||||
import com.ai.cloud.skywalking.api.IBuriedPointType;
|
||||
import com.ai.cloud.skywalking.protocol.common.CallType;
|
||||
|
||||
public class SpringBuriedPointType implements IBuriedPointType {
|
||||
|
||||
private static SpringBuriedPointType springBuriedPointType;
|
||||
|
||||
public static IBuriedPointType instance() {
|
||||
if (springBuriedPointType == null) {
|
||||
springBuriedPointType = new SpringBuriedPointType();
|
||||
}
|
||||
|
||||
return springBuriedPointType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTypeName() {
|
||||
return "M";
|
||||
}
|
||||
|
||||
@Override
|
||||
public CallType getCallType() {
|
||||
return CallType.LOCAL;
|
||||
}
|
||||
|
||||
private SpringBuriedPointType() {
|
||||
// Non
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
package com.ai.cloud.skywalking.plugin.spring;
|
||||
|
||||
import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
|
||||
|
||||
public class SpringTagNamespaceHandler extends NamespaceHandlerSupport {
|
||||
@Override
|
||||
public void init() {
|
||||
registerBeanDefinitionParser("trace", new TracingPatternParser());
|
||||
}
|
||||
}
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
package com.ai.cloud.skywalking.plugin.spring;
|
||||
|
||||
import com.ai.cloud.skywalking.invoke.monitor.LocalMethodInvokeMonitor;
|
||||
import com.ai.cloud.skywalking.model.Identification;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
|
||||
public class TracingAspect {
|
||||
|
||||
public Object doTracing(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
|
||||
LocalMethodInvokeMonitor localMethodInvokeMonitor = new LocalMethodInvokeMonitor();
|
||||
try {
|
||||
localMethodInvokeMonitor.beforeInvoke(Identification.newBuilder().viewPoint(proceedingJoinPoint.getSignature().toString()).spanType(SpringBuriedPointType.instance()).build());
|
||||
return proceedingJoinPoint.proceed();
|
||||
} catch (Throwable e) {
|
||||
localMethodInvokeMonitor.occurException(e);
|
||||
throw e;
|
||||
} finally {
|
||||
localMethodInvokeMonitor.afterInvoke();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,102 +0,0 @@
|
|||
package com.ai.cloud.skywalking.plugin.spring;
|
||||
|
||||
import com.ai.cloud.skywalking.conf.AuthDesc;
|
||||
import com.ai.cloud.skywalking.plugin.spring.util.ConcurrentHashSet;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.springframework.aop.aspectj.AspectInstanceFactory;
|
||||
import org.springframework.aop.aspectj.AspectJAroundAdvice;
|
||||
import org.springframework.aop.aspectj.AspectJExpressionPointcut;
|
||||
import org.springframework.aop.aspectj.SimpleAspectInstanceFactory;
|
||||
import org.springframework.aop.framework.ProxyFactory;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Set;
|
||||
|
||||
public class TracingEnhanceProcessor implements DisposableBean,
|
||||
BeanPostProcessor, BeanFactoryPostProcessor, ApplicationContextAware {
|
||||
private final Set<TracingPattern> beanSet = new ConcurrentHashSet<TracingPattern>();
|
||||
|
||||
@Override
|
||||
public void postProcessBeanFactory(
|
||||
ConfigurableListableBeanFactory beanFactory) throws BeansException {
|
||||
for (TracingPattern tracingPattern : applicationContext.getBeansOfType(TracingPattern.class)
|
||||
.values()) {
|
||||
|
||||
AspectJExpressionPointcut packageMatcher = new AspectJExpressionPointcut();
|
||||
packageMatcher.setExpression("within(" + tracingPattern.getPackageExpression() + ")");
|
||||
tracingPattern.setPackageMatcher(packageMatcher);
|
||||
|
||||
AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
|
||||
pointcut.setExpression("execution(* " + tracingPattern.getPackageExpression().substring(0, tracingPattern.getPackageExpression().length() - 1) + tracingPattern.getClassExpression() + ".*(..))");
|
||||
tracingPattern.setPointcut(pointcut);
|
||||
|
||||
beanSet.add(tracingPattern);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object postProcessBeforeInitialization(Object bean, String beanName)
|
||||
throws BeansException {
|
||||
return bean;
|
||||
}
|
||||
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext)
|
||||
throws BeansException {
|
||||
this.applicationContext = applicationContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object postProcessAfterInitialization(Object bean, String beanName)
|
||||
throws BeansException {
|
||||
if (!AuthDesc.isAuth()) {
|
||||
return bean;
|
||||
}
|
||||
|
||||
for (TracingPattern tracingPattern : beanSet) {
|
||||
if (tracingPattern.getPackageMatcher().matches(bean.getClass()) && matchClassName(tracingPattern.getClassExpression(), bean
|
||||
.getClass().getSimpleName())) {
|
||||
ProxyFactory proxyFactory = new ProxyFactory(bean);
|
||||
proxyFactory.setProxyTargetClass(true);
|
||||
AspectInstanceFactory aspectInstanceFactory = new SimpleAspectInstanceFactory(TracingAspect.class);
|
||||
Method method = null;
|
||||
try {
|
||||
method = TracingAspect.class.getMethod("doTracing", ProceedingJoinPoint.class);
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw new IllegalStateException("Failed to find doTracing method", e);
|
||||
}
|
||||
AspectJAroundAdvice advised = new AspectJAroundAdvice(method,
|
||||
tracingPattern.getPointcut(), aspectInstanceFactory);
|
||||
proxyFactory.addAdvice(advised);
|
||||
|
||||
return proxyFactory.getProxy();
|
||||
}
|
||||
}
|
||||
return bean;
|
||||
}
|
||||
|
||||
private boolean matchClassName(String className, String simpleName) {
|
||||
if ("*".equals(className)) {
|
||||
return true;
|
||||
} else if (className.endsWith("*")) {
|
||||
return simpleName.startsWith(className);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() throws Exception {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
package com.ai.cloud.skywalking.plugin.spring;
|
||||
|
||||
import org.springframework.aop.aspectj.AspectJExpressionPointcut;
|
||||
|
||||
public class TracingPattern {
|
||||
private String packageExpression = "";
|
||||
private String classExpression = "";
|
||||
private AspectJExpressionPointcut packageMatcher;
|
||||
private AspectJExpressionPointcut pointcut;
|
||||
|
||||
public String getPackageExpression() {
|
||||
return packageExpression;
|
||||
}
|
||||
|
||||
public void setPackageExpression(String packageExpression) {
|
||||
this.packageExpression = packageExpression;
|
||||
}
|
||||
|
||||
public String getClassExpression() {
|
||||
return classExpression;
|
||||
}
|
||||
|
||||
public void setClassExpression(String classExpression) {
|
||||
this.classExpression = classExpression;
|
||||
}
|
||||
|
||||
public AspectJExpressionPointcut getPackageMatcher() {
|
||||
return packageMatcher;
|
||||
}
|
||||
|
||||
public void setPackageMatcher(AspectJExpressionPointcut packageMatcher) {
|
||||
this.packageMatcher = packageMatcher;
|
||||
}
|
||||
|
||||
public AspectJExpressionPointcut getPointcut() {
|
||||
return pointcut;
|
||||
}
|
||||
|
||||
public void setPointcut(AspectJExpressionPointcut pointcut) {
|
||||
this.pointcut = pointcut;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,59 +0,0 @@
|
|||
package com.ai.cloud.skywalking.plugin.spring;
|
||||
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.RuntimeBeanReference;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
import org.springframework.beans.factory.xml.BeanDefinitionParser;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
public class TracingPatternParser implements BeanDefinitionParser {
|
||||
|
||||
private final String TRACE_ENHANCE_PROCESSOR_BEAN_NAME = "TracingEnhanceProcessor";
|
||||
|
||||
@Override
|
||||
public BeanDefinition parse(Element element, ParserContext parserContext) {
|
||||
RootBeanDefinition beanDefinition = new RootBeanDefinition();
|
||||
beanDefinition.setBeanClass(TracingPattern.class);
|
||||
String id = element.getAttribute("id");
|
||||
if (id == null || id.length() == 0) {
|
||||
id = TracingPattern.class.getName();
|
||||
int counter = 2;
|
||||
while (parserContext.getRegistry().containsBeanDefinition(id)) {
|
||||
id = id + (counter++);
|
||||
}
|
||||
}
|
||||
if (id != null && id.length() > 0) {
|
||||
if (parserContext.getRegistry().containsBeanDefinition(id)) {
|
||||
throw new IllegalStateException("Duplicate spring bean id " + id);
|
||||
}
|
||||
parserContext.getRegistry().registerBeanDefinition(id, beanDefinition);
|
||||
}
|
||||
NamedNodeMap nnm = element.getAttributes();
|
||||
for (int i = 0; i < nnm.getLength(); i++) {
|
||||
Node node = nnm.item(i);
|
||||
String key = node.getLocalName();
|
||||
String value = node.getNodeValue();
|
||||
if (key.equals("entity")) {
|
||||
if (parserContext.getRegistry().containsBeanDefinition(value)) {
|
||||
beanDefinition.getPropertyValues().add(key, parserContext.getRegistry().getBeanDefinition(value));
|
||||
} else {
|
||||
beanDefinition.getPropertyValues().add(key, new RuntimeBeanReference(value));
|
||||
}
|
||||
} else {
|
||||
beanDefinition.getPropertyValues().add(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
if (!parserContext.getRegistry().containsBeanDefinition(TRACE_ENHANCE_PROCESSOR_BEAN_NAME)){
|
||||
RootBeanDefinition traceEnhanceProcessorBeanDefinition = new RootBeanDefinition();
|
||||
traceEnhanceProcessorBeanDefinition.setBeanClass(TracingEnhanceProcessor.class);
|
||||
traceEnhanceProcessorBeanDefinition.setLazyInit(false);
|
||||
parserContext.getRegistry().registerBeanDefinition(TRACE_ENHANCE_PROCESSOR_BEAN_NAME, traceEnhanceProcessorBeanDefinition);
|
||||
}
|
||||
|
||||
return beanDefinition;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
package com.ai.cloud.skywalking.plugin.spring.util;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.AbstractSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class ConcurrentHashSet<E> extends AbstractSet<E> implements Set<E>, Serializable {
|
||||
private static final long serialVersionUID = -8672117787651310382L;
|
||||
private static final Object PRESENT = new Object();
|
||||
private final ConcurrentHashMap<E, Object> map;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public ConcurrentHashSet() {
|
||||
this.map = new ConcurrentHashMap();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public ConcurrentHashSet(int initialCapacity) {
|
||||
this.map = new ConcurrentHashMap(initialCapacity);
|
||||
}
|
||||
|
||||
public Iterator<E> iterator() {
|
||||
return this.map.keySet().iterator();
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return this.map.size();
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return this.map.isEmpty();
|
||||
}
|
||||
|
||||
public boolean contains(Object o) {
|
||||
return this.map.containsKey(o);
|
||||
}
|
||||
|
||||
public boolean add(E e) {
|
||||
return this.map.put(e, PRESENT) == null;
|
||||
}
|
||||
|
||||
public boolean remove(Object o) {
|
||||
return this.map.remove(o) == PRESENT;
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
this.map.clear();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<xsd:schema xmlns="http://cloud.asiainfo.com/schema/skywalking"
|
||||
xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://cloud.asiainfo.com/schema/skywalking">
|
||||
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace"/>
|
||||
|
||||
<xsd:element name="trace" type="traceType">
|
||||
</xsd:element>
|
||||
|
||||
<xsd:complexType name="traceType">
|
||||
<xsd:attribute name="packageExpression" use="required">
|
||||
<xsd:simpleType>
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:pattern value="[\w|.]*\.\*"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="classExpression" type="xsd:string" use="optional" default="*"/>
|
||||
</xsd:complexType>
|
||||
</xsd:schema>
|
||||
|
|
@ -1 +0,0 @@
|
|||
http\://cloud.asiainfo.com/schema/skywalking=com.ai.cloud.skywalking.plugin.spring.SpringTagNamespaceHandler
|
||||
|
|
@ -1 +0,0 @@
|
|||
http\://cloud.asiainfo.com/schema/skywalking/skywalking.xsd=META-INF/skywalking.xsd
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
package com.ai.cloud.skywalking.plugin.spring.test;
|
||||
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Service
|
||||
//@Transactional
|
||||
public class TestBean/* implements TestInterface*/ {
|
||||
private String value;
|
||||
|
||||
public void testPrintln(String value) {
|
||||
System.out.println(value);
|
||||
}
|
||||
|
||||
private void testPrintln2(String value) {
|
||||
System.out.println(value);
|
||||
}
|
||||
|
||||
|
||||
public static void main(String[] args) throws IllegalAccessException {
|
||||
ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("classpath*:springConfig-common.xml");
|
||||
TestBean testBean = classPathXmlApplicationContext.getBean(TestBean.class);
|
||||
testBean.testPrintln("Hello World");
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
jdbc.driverClassName=com.mysql.jdbc.Driver
|
||||
jdbc.url=jdbc:mysql://10.1.241.20:31306/sw_db
|
||||
jdbc.username=sw_dbusr01
|
||||
jdbc.password=sw_dbusr01
|
||||
jdbc.maxTotal=200
|
||||
jdbc.maxIdle=50
|
||||
jdbc.maxWaitMillis=1000
|
||||
jdbc.defaultAutoCommit=false
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Configuration status="error">
|
||||
<Appenders>
|
||||
<Console name="Console" target="SYSTEM_OUT">
|
||||
<PatternLayout pattern="%d [%t](%F:%L) %-5level %logger{36} - %msg%n" />
|
||||
</Console>
|
||||
</Appenders>
|
||||
<Loggers>
|
||||
<Root level="error">
|
||||
<AppenderRef ref="Console" />
|
||||
</Root>
|
||||
<logger name="com.ai.cloud.skywalking" level="debug">
|
||||
<AppenderRef ref="Console" />
|
||||
</logger>
|
||||
</Loggers>
|
||||
</Configuration>
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
#skyWalking用户ID
|
||||
skywalking.user_id=123
|
||||
#skyWalking应用编码
|
||||
skywalking.application_code=test
|
||||
#skywalking auth的环境变量名字
|
||||
skywalking.auth_system_env_name=SKYWALKING_RUN
|
||||
#skywalking数据编码
|
||||
skywalking.charset=UTF-8
|
||||
|
||||
#是否打印数据
|
||||
buriedpoint.printf=true
|
||||
#埋点异常的最大长度
|
||||
buriedpoint.max_exception_stack_length=4000
|
||||
#业务字段的最大长度
|
||||
buriedpoint.businesskey_max_length=300
|
||||
#过滤异常
|
||||
buriedpoint.exclusive_exceptions=java.lang.RuntimeException
|
||||
|
||||
#最大发送者的连接数阀比例
|
||||
sender.connect_percent=100
|
||||
#发送服务端配置
|
||||
sender.servers_addr=127.0.0.1:34000
|
||||
#最大发送的副本数量
|
||||
sender.max_copy_num=2
|
||||
#发送的最大长度
|
||||
sender.max_send_length=20000
|
||||
#当没有Sender时,尝试获取sender的等待周期
|
||||
sender.retry_get_sender_wait_interval=2000
|
||||
|
||||
|
||||
|
||||
|
||||
#最大消费线程数
|
||||
consumer.max_consumer=2
|
||||
#消费者最大等待时间
|
||||
consumer.max_wait_time=5
|
||||
#发送失败等待时间
|
||||
consumer.consumer_fail_retry_wait_interval=50
|
||||
|
||||
#每个Buffer的最大个数
|
||||
buffer.buffer_max_size=18000
|
||||
#Buffer池的最大长度
|
||||
buffer.pool_size=5
|
||||
|
||||
#发送检查线程检查周期
|
||||
senderchecker.check_polling_time=200
|
||||
|
||||
|
|
@ -1,50 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans
|
||||
xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:skywalking="http://cloud.asiainfo.com/schema/skywalking"
|
||||
xmlns:tx="http://www.springframework.org/schema/tx"
|
||||
xmlns:context="http://www.springframework.org/schema/context"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
|
||||
http://cloud.asiainfo.com/schema/skywalking
|
||||
http://cloud.asiainfo.com/schema/skywalking/skywalking.xsd
|
||||
http://www.springframework.org/schema/context
|
||||
http://www.springframework.org/schema/context/spring-context-3.0.xsd
|
||||
http://www.springframework.org/schema/tx
|
||||
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd ">
|
||||
|
||||
|
||||
<context:component-scan base-package="com.ai.cloud.skywalking.plugin.spring.test"/>
|
||||
<bean id="jdbcConfig"
|
||||
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
|
||||
<property name="order" value="1"/>
|
||||
<property name="ignoreUnresolvablePlaceholders" value="true"/>
|
||||
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE"/>
|
||||
<property name="locations" value="classpath:jdbc.properties"/>
|
||||
</bean>
|
||||
|
||||
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource">
|
||||
<property name="driverClassName" value="${jdbc.driverClassName}"/>
|
||||
<property name="url" value="${jdbc.url}"/>
|
||||
<property name="username" value="${jdbc.username}"/>
|
||||
<property name="password" value="${jdbc.password}"/>
|
||||
</bean>
|
||||
|
||||
<bean id="transactionManager"
|
||||
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
|
||||
<property name="dataSource" ref="dataSource"/>
|
||||
</bean>
|
||||
<!-- 注解事务类 -->
|
||||
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>
|
||||
|
||||
<!--AOP 事务配置-->
|
||||
<tx:advice id="txAdvice" transaction-manager="transactionManager">
|
||||
<tx:attributes>
|
||||
<tx:method name="*" propagation="REQUIRED"/>
|
||||
</tx:attributes>
|
||||
</tx:advice>
|
||||
|
||||
<skywalking:trace packageExpression="com.ai.cloud.skywalking.plugin.spring.test.*" classExpression="*"/>
|
||||
|
||||
</beans>
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
# 如何追踪web应用服务器访问?
|
||||
- 引入所需插件
|
||||
```xml
|
||||
<!-- web,监控web调用 -->
|
||||
<dependency>
|
||||
<groupId>com.ai.cloud</groupId>
|
||||
<artifactId>skywalking-web-plugin</artifactId>
|
||||
<version>{latest_version}</version>
|
||||
</dependency>
|
||||
```
|
||||
- 服务端使用Filter追踪web请求
|
||||
```xml
|
||||
<filter>
|
||||
<filter-name>tracingFilter</filter-name>
|
||||
<filter-class>com.ai.cloud.skywalking.plugin.web.SkyWalkingFilter</filter-class>
|
||||
<init-param>
|
||||
<param-name>tracing-name</param-name>
|
||||
<!--分布式埋点信息,默认放在request的header中,key=SkyWalking-TRACING-NAME,可根据需要修改-->
|
||||
<param-value>SkyWalking-TRACING-NAME</param-value>
|
||||
</init-param>
|
||||
</filter>
|
||||
<filter-mapping>
|
||||
<filter-name>tracingFilter</filter-name>
|
||||
<!--追踪路径应为MVC的请求路径,不建议包括js/css/图片等资源路径-->
|
||||
<url-pattern>/request-uri</url-pattern>
|
||||
</filter-mapping>
|
||||
```
|
||||
|
|
@ -1,68 +0,0 @@
|
|||
<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">
|
||||
<parent>
|
||||
<artifactId>skywalking-sdk-plugin</artifactId>
|
||||
<groupId>com.ai.cloud</groupId>
|
||||
<version>1.0-Final</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>skywalking-web-plugin</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>web-plugin</name>
|
||||
<url>http://maven.apache.org</url>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.ai.cloud</groupId>
|
||||
<artifactId>skywalking-api</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<!--
|
||||
<dependency>
|
||||
<groupId>com.ai.cloud</groupId>
|
||||
<artifactId>skywalking-auth</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
-->
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>javax.servlet-api</artifactId>
|
||||
<version>3.0.1</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<!-- 源码插件 -->
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-source-plugin</artifactId>
|
||||
<!-- 发布时自动将源码同时发布的配置 -->
|
||||
<executions>
|
||||
<execution>
|
||||
<id>attach-sources</id>
|
||||
<goals>
|
||||
<goal>jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<distributionManagement>
|
||||
<repository>
|
||||
<id>bintray-wu-sheng-sky-walking-repository</id>
|
||||
<name>wu-sheng-sky-walking-repository</name>
|
||||
<url>https://api.bintray.com/maven/wu-sheng/skywalking/com.ai.cloud.skywalking-web-plugin/;publish=1</url>
|
||||
</repository>
|
||||
</distributionManagement>
|
||||
</project>
|
||||
|
|
@ -1,80 +0,0 @@
|
|||
package com.ai.cloud.skywalking.plugin.web;
|
||||
|
||||
|
||||
import com.ai.cloud.skywalking.api.Tracing;
|
||||
import com.ai.cloud.skywalking.invoke.monitor.RPCServerInvokeMonitor;
|
||||
import com.ai.cloud.skywalking.conf.AuthDesc;
|
||||
import com.ai.cloud.skywalking.model.ContextData;
|
||||
import com.ai.cloud.skywalking.model.Identification;
|
||||
|
||||
import javax.servlet.*;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
|
||||
public class SkyWalkingFilter implements Filter {
|
||||
|
||||
private final String secondKey = "ContextData";
|
||||
private String tracingName;
|
||||
private static final String DEFAULT_TRACE_NAME = "SkyWalking-TRACING-NAME";
|
||||
private static final String TRACE_ID_HEADER_NAME = "SW-TraceId";
|
||||
|
||||
public void init(FilterConfig filterConfig) throws ServletException {
|
||||
tracingName = filterConfig.getInitParameter("tracing-name");
|
||||
if (tracingName == null || tracingName.length() <= 0) {
|
||||
tracingName = DEFAULT_TRACE_NAME;
|
||||
}
|
||||
}
|
||||
|
||||
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
|
||||
if (!AuthDesc.isAuth()) {
|
||||
filterChain.doFilter(servletRequest, servletResponse);
|
||||
return;
|
||||
}
|
||||
|
||||
RPCServerInvokeMonitor rpcServerInvokeMonitor = null;
|
||||
try {
|
||||
HttpServletRequest request = (HttpServletRequest) servletRequest;
|
||||
String tracingHeaderValue = request.getHeader(tracingName);
|
||||
ContextData contextData = null;
|
||||
if (tracingHeaderValue != null) {
|
||||
String contextDataStr = null;
|
||||
int index = tracingHeaderValue.indexOf("=");
|
||||
if (index > 0) {
|
||||
String key = tracingHeaderValue.substring(0, index);
|
||||
if (secondKey.equals(key)) {
|
||||
contextDataStr = tracingHeaderValue.substring(index + 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (contextDataStr != null && contextDataStr.length() > 0) {
|
||||
contextData = new ContextData(contextDataStr);
|
||||
}
|
||||
}
|
||||
rpcServerInvokeMonitor = new RPCServerInvokeMonitor();
|
||||
rpcServerInvokeMonitor.beforeInvoke(contextData, generateIdentification(request));
|
||||
filterChain.doFilter(servletRequest, servletResponse);
|
||||
|
||||
HttpServletResponse httpServletResponse = (HttpServletResponse) servletResponse;
|
||||
httpServletResponse.addHeader(TRACE_ID_HEADER_NAME, Tracing.getTraceId());
|
||||
} catch (Throwable e) {
|
||||
rpcServerInvokeMonitor.occurException(e);
|
||||
throw new ServletException(e);
|
||||
} finally {
|
||||
rpcServerInvokeMonitor.afterInvoke();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
private Identification generateIdentification(HttpServletRequest request) {
|
||||
return Identification.newBuilder()
|
||||
.viewPoint(request.getRequestURL().toString())
|
||||
.spanType(WebBuriedPointType.instance())
|
||||
.build();
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
// do-nothing
|
||||
}
|
||||
}
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
package com.ai.cloud.skywalking.plugin.web;
|
||||
|
||||
import com.ai.cloud.skywalking.api.IBuriedPointType;
|
||||
import com.ai.cloud.skywalking.protocol.common.CallType;
|
||||
|
||||
public class WebBuriedPointType implements IBuriedPointType {
|
||||
|
||||
private static WebBuriedPointType webBuriedPointType;
|
||||
|
||||
public static IBuriedPointType instance() {
|
||||
if (webBuriedPointType == null) {
|
||||
webBuriedPointType = new WebBuriedPointType();
|
||||
}
|
||||
|
||||
return webBuriedPointType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTypeName() {
|
||||
return "W";
|
||||
}
|
||||
|
||||
@Override
|
||||
public CallType getCallType() {
|
||||
return CallType.SYNC;
|
||||
}
|
||||
|
||||
private WebBuriedPointType() {
|
||||
// Non
|
||||
}
|
||||
}
|
||||
|
|
@ -1,102 +1,102 @@
|
|||
<?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/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.ai.cloud</groupId>
|
||||
<artifactId>skywalking-protocol</artifactId>
|
||||
<name>skywalking-protocol</name>
|
||||
<version>1.0-Final</version>
|
||||
<url>http://maven.apache.org</url>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>2.4.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<shadedArtifactAttached>false</shadedArtifactAttached>
|
||||
<createDependencyReducedPom>true</createDependencyReducedPom>
|
||||
<createSourcesJar>true</createSourcesJar>
|
||||
<shadeSourcesContent>true</shadeSourcesContent>
|
||||
<relocations>
|
||||
<relocation>
|
||||
<pattern>${shade.com.google.protobuf.source}</pattern>
|
||||
<shadedPattern>${shade.com.google.protobuf.target}</shadedPattern>
|
||||
</relocation>
|
||||
</relocations>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>build-helper-maven-plugin</artifactId>
|
||||
<version>1.9.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>add-source</id>
|
||||
<phase>generate-sources</phase>
|
||||
<goals>
|
||||
<goal>add-source</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<sources>
|
||||
<source>${project.basedir}/src/main/gen-java</source>
|
||||
</sources>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-resources-plugin</artifactId>
|
||||
<version>2.4.3</version>
|
||||
<configuration>
|
||||
<encoding>${project.build.sourceEncoding}</encoding>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-source-plugin</artifactId>
|
||||
<version>2.4</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>attach-sources</id>
|
||||
<goals>
|
||||
<goal>jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.12</version>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>hamcrest-core</artifactId>
|
||||
<groupId>org.hamcrest</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<distributionManagement>
|
||||
<repository>
|
||||
<id>bintray-wu-sheng-sky-walking-repository</id>
|
||||
<name>wu-sheng-sky-walking-repository</name>
|
||||
<url>https://api.bintray.com/maven/wu-sheng/skywalking/com.ai.cloud.skywalking-protocol/;publish=1</url>
|
||||
</repository>
|
||||
</distributionManagement>
|
||||
<properties>
|
||||
<shade.com.google.protobuf.source>com.google.protobuf</shade.com.google.protobuf.source>
|
||||
<shade.com.google.protobuf.target>com.ai.cloud.skywalking.protocol.dependencies.com.google.protobuf</shade.com.google.protobuf.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
</project>
|
||||
|
||||
<?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/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.ai.cloud</groupId>
|
||||
<artifactId>skywalking-protocol</artifactId>
|
||||
<name>skywalking-protocol</name>
|
||||
<version>1.0-Final</version>
|
||||
<url>http://maven.apache.org</url>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>2.4.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<shadedArtifactAttached>false</shadedArtifactAttached>
|
||||
<createDependencyReducedPom>true</createDependencyReducedPom>
|
||||
<createSourcesJar>true</createSourcesJar>
|
||||
<shadeSourcesContent>true</shadeSourcesContent>
|
||||
<relocations>
|
||||
<relocation>
|
||||
<pattern>${shade.com.google.protobuf.source}</pattern>
|
||||
<shadedPattern>${shade.com.google.protobuf.target}</shadedPattern>
|
||||
</relocation>
|
||||
</relocations>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>build-helper-maven-plugin</artifactId>
|
||||
<version>1.9.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>add-source</id>
|
||||
<phase>generate-sources</phase>
|
||||
<goals>
|
||||
<goal>add-source</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<sources>
|
||||
<source>${project.basedir}/src/main/gen-java</source>
|
||||
</sources>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-resources-plugin</artifactId>
|
||||
<version>2.4.3</version>
|
||||
<configuration>
|
||||
<encoding>${project.build.sourceEncoding}</encoding>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-source-plugin</artifactId>
|
||||
<version>2.4</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>attach-sources</id>
|
||||
<goals>
|
||||
<goal>jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.12</version>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>hamcrest-core</artifactId>
|
||||
<groupId>org.hamcrest</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<distributionManagement>
|
||||
<repository>
|
||||
<id>bintray-wu-sheng-sky-walking-repository</id>
|
||||
<name>wu-sheng-sky-walking-repository</name>
|
||||
<url>https://api.bintray.com/maven/wu-sheng/skywalking/com.ai.cloud.skywalking-protocol/;publish=1</url>
|
||||
</repository>
|
||||
</distributionManagement>
|
||||
<properties>
|
||||
<shade.com.google.protobuf.source>com.google.protobuf</shade.com.google.protobuf.source>
|
||||
<shade.com.google.protobuf.target>com.ai.cloud.skywalking.protocol.dependencies.com.google.protobuf</shade.com.google.protobuf.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
</project>
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue