【java】【服务器】线程上下文丢失 是指什么

目录

■前言

■正文开始

线程上下文的核心组成部分

为什么会出现上下文丢失?

直观示例说明

为什么上下文如此重要?

解决上下文丢失的关键

总结

■如果我想在servlet中使用线程,代码应该如何实现

推荐方案:使用 ManagedExecutorService(WebSphere 托管线程池)

备选方案:手动管理线程上下文(如果无法使用 ManagedExecutorService)

关键配置步骤(WebSphere 控制台)

两种方案对比

最佳实践建议

完整示例(生产级代码)

■ManagedExecutorService 这个类,在那个jar中

规范定义包(通用)

总结

注意:不适用WebSphere 8.5.5,没有【com.ibm.ws.concurrent.jar】这个jar

■各个WebSphere版本中,线程(线程池)相关的jar

■WebSphere Liberty 是什么

🚀 核心特性

🏢 与传统 WebSphere 的关系

■我在WebSphere 8.5.5中,找到了runtime.jar,但是里面没有【com.ibm.ws.threading.WSManagedExecutorService】这个类

🔍 根本原因分析

类【com.ibm.ws.threading.ThreadPoolManager】也没有找到,而且根本不存在 com.ibm.ws.threading 这个包。

■WorkManager


■前言

Web应用中,为了提高效率,某段和主业务无关的处理,使用异步处理来处理。

(使用的服务器是WebSphere)

结果报如下错误

WebContextsService getStandardContext Failed to retrieve application name

这个错误的原因是线程上下文丢失造成的,

因此,整理解释一下什么是线程上下文丢失

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

■正文开始

线程上下文的核心组成部分

  1. 类加载器(ClassLoader)

    • Web 应用有独立的类加载器(隔离其他应用)

    • 负责加载应用中的类、资源和库

    • 丢失后果ClassNotFoundExceptionNoClassDefFoundError

  2. JNDI(Java Naming and Directory Interface)上下文

    • 提供对应用服务器资源的访问(如数据源、JMS 队列)

    • 丢失后果NamingException、无法查找 java:comp/env 资源

  3. Web 应用上下文(ServletContext)

    • 包含 Web 应用元数据:应用名称、上下文路径、初始化参数

    • 丢失后果getStandardContext failed to retrieve application name(我遇到的错误)

  4. 安全上下文(Security Context)

    • 包含用户认证/授权信息(如 Principal、角色)

    • 丢失后果NullPointerException 或权限检查失败

  5. 事务上下文(Transaction Context)

    • 管理数据库事务边界

    • 丢失后果:事务无法提交/回滚


为什么会出现上下文丢失?

  1. 线程创建方式

    // 自定义线程不会继承上下文
    new Thread(() -> {// 此处丢失所有上下文!
    }).start();

  2. Web 容器管理的线程 vs 自定义线程

    特性Web 容器线程 (如 HTTP 请求线程)自定义线程
    类加载器自动设置正确默认使用系统类加载器
    JNDI 上下文自动可用InitialContext() 失败
    ServletContext通过 getServletContext() 获取返回 null 或抛出异常
    事务传播支持事务边界中断
  3. WebSphere 的上下文隔离机制

    • 为每个应用创建独立的沙箱环境

    • 自定义线程被视为"外部线程",无权访问应用沙箱


直观示例说明

假设在 Servlet 中启动线程:

public class MyServlet extends HttpServlet {protected void doGet(HttpServletRequest req, HttpServletResponse resp) {// 正确环境 (有上下文)String appName = getServletContext().getContextPath(); // 成功获取new Thread(() -> {// 危险区域 (上下文丢失)!try {// 尝试获取相同信息Context ctx = new InitialContext();String name = (String) ctx.lookup("java:app/AppName"); // 抛出异常!} catch (NamingException e) {// 报错: getStandardContext failed to retrieve application name}}).start();}
}

为什么上下文如此重要?

当调用以下 API 时会依赖上下文:

// 依赖 Web 上下文
servletContext.getResource("/WEB-INF/config.xml"); // 依赖 JNDI 上下文
dataSource = (DataSource) new InitialContext().lookup("jdbc/myDB");// 依赖类加载器
Class.forName("com.myapp.CustomClass"); // 依赖安全上下文
request.isUserInRole("Admin");

解决上下文丢失的关键

必须通过以下方式之一传递上下文:

  1. 显式传递数据

    // 在 Web 线程中预先获取值
    String appName = getServletContext().getContextPath(); 
    executor.submit(new MyTask(appName)); // 传递值而非依赖上下文

  2. 使用托管线程服务(推荐)

    @Resource
    private ManagedExecutorService managedExecutor; // WebSphere 托管managedExecutor.submit(() -> {// WebSphere 自动注入上下文Context ctx = new InitialContext(); // 现在正常工作了!
    });

  3. 手动恢复上下文(复杂)

    // 在 Web 线程中捕获当前类加载器
    ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader();new Thread(() -> {// 手动恢复类加载器Thread.currentThread().setContextClassLoader(originalClassLoader);// 注意:这无法恢复 JNDI 或 ServletContext!
    }).start();


总结

线程上下文丢失本质是:当代码脱离 Web 容器管控的线程时,应用服务器无法自动提供运行所需的环境信息。解决的关键在于:

  1. 避免在自定义线程中直接访问 Web API

  2. 使用服务器托管线程池(ManagedExecutorService

  3. 在 Web 线程中预先获取数据并传递值

这正是您遇到的 getStandardContext failed to retrieve application name 的根本原因——自定义线程中无法关联到 Web 应用的 ServletContext

===

■如果我想在servlet中使用线程,代码应该如何实现

在 Servlet 中使用自定义线程时,为了正确处理线程上下文问题(特别是在 WebSphere 环境中),强烈推荐使用 Java EE 标准的 ManagedExecutorService。以下是完整的实现方案:

推荐方案:使用 ManagedExecutorService(WebSphere 托管线程池)

import javax.annotation.Resource;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.enterprise.concurrent.ManagedExecutorService;
import java.io.IOException;
import java.io.PrintWriter;@WebServlet("/asyncTask")
public class ThreadedServlet extends HttpServlet {// 注入 WebSphere 托管的线程池服务@Resourceprivate ManagedExecutorService managedExecutor;@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {response.setContentType("text/plain");PrintWriter out = response.getWriter();// 提交任务到托管线程池(自动传递线程上下文)managedExecutor.submit(() -> {try {// 在托管线程中安全访问上下文String appName = (String) new InitialContext().lookup("java:app/AppName");String contextPath = request.getServletContext().getContextPath();// 执行实际业务逻辑processTask(appName, contextPath);out.println("Task completed successfully in managed thread!");} catch (Exception e) {out.println("Error in managed thread: " + e.getMessage());e.printStackTrace();}});out.println("Background task started using ManagedExecutorService...");}private void processTask(String appName, String contextPath) {// 这里是实际的业务逻辑System.out.println("Processing task for application: " + appName);System.out.println("Context path: " + contextPath);// 模拟耗时操作try {Thread.sleep(2000);} catch (InterruptedException e) {Thread.currentThread().interrupt();}}
}
 

备选方案:手动管理线程上下文(如果无法使用 ManagedExecutorService)

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import javax.naming.InitialContext;@WebServlet("/manualThread")
public class ManualThreadServlet extends HttpServlet {// 创建普通线程池(不推荐,仅作演示)private final ExecutorService executor = Executors.newFixedThreadPool(5);@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {response.setContentType("text/plain");PrintWriter out = response.getWriter();// 在Web线程中预先获取所需上下文信息final String appName = getPredefinedAppName();final String contextPath = request.getServletContext().getContextPath();final ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();// 提交任务到普通线程池executor.submit(() -> {// 保存原始类加载器(用于恢复)ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader();try {// 手动设置上下文类加载器Thread.currentThread().setContextClassLoader(contextClassLoader);// 使用预先获取的上下文信息processTask(appName, contextPath);out.println("Task completed in manual thread!");} catch (Exception e) {out.println("Error in manual thread: " + e.getMessage());e.printStackTrace();} finally {// 恢复原始类加载器Thread.currentThread().setContextClassLoader(originalClassLoader);}});out.println("Background task started using manual thread...");}private String getPredefinedAppName() {try {// 在Web线程中预先获取应用名称return (String) new InitialContext().lookup("java:app/AppName");} catch (Exception e) {return "default-app";}}private void processTask(String appName, String contextPath) {// 业务逻辑同上}@Overridepublic void destroy() {// 关闭线程池executor.shutdown();super.destroy();}
}
 

关键配置步骤(WebSphere 控制台)

  1. 启用并发策略

    • 登录 WebSphere 管理控制台

    • 导航到:资源 > 并发策略

    • 创建或使用默认的并发策略

  2. 绑定到应用(可选,通常自动注入即可工作):
    在 ibm-application-bnd.xml 中添加:

    <application-bnd><managed-executor-service name="concurrent/executorSvc" />
    </application-bnd>
     

两种方案对比

特性ManagedExecutorService手动线程管理
上下文传播自动完整传播(类加载器、JNDI、安全等)仅能手动传递类加载器
资源管理WebSphere 自动管理生命周期需手动关闭线程池
事务支持支持事务上下文传播不支持事务传播
Servlet API 访问可直接访问(如 requestresponse只能访问预先获取的数据
WebSphere 兼容性完全兼容可能仍有上下文问题
代码复杂度简单(声明式注入)复杂(需手动管理上下文)
推荐度⭐⭐⭐⭐⭐(首选方案)⭐⭐(备选方案)

最佳实践建议

  1. 首选托管线程池

    @Resource
    private ManagedExecutorService executor; // 始终使用这个
     
  2. 避免在子线程中直接使用 Servlet API

    // 错误做法(可能引发问题):
    managedExecutor.submit(() -> {request.getSession(); // 可能不安全
    });// 正确做法(预先获取所需数据):
    String sessionId = request.getSession().getId();
    managedExecutor.submit(() -> processSession(sessionId));
     
  3. 处理线程中的异常

    managedExecutor.submit(() -> {try {// 业务逻辑} catch (Exception e) {// 1. 记录日志// 2. 不要吞掉异常// 3. 考虑通知主线程}
    });

  4. 生命周期管理

    • 不需要手动关闭 ManagedExecutorService

    • 对于普通线程池,在 Servlet.destroy() 中关闭:

      @Override
      public void destroy() {executor.shutdown();try {if (!executor.awaitTermination(10, TimeUnit.SECONDS)) {executor.shutdownNow();}} catch (InterruptedException e) {executor.shutdownNow();Thread.currentThread().interrupt();}
      }

完整示例(生产级代码)

@WebServlet("/task")
public class ProductionReadyServlet extends HttpServlet {@Resourceprivate ManagedExecutorService managedExecutor;private static final Logger logger = LoggerFactory.getLogger(ProductionReadyServlet.class);@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {// 预先获取所需上下文信息String appName = (String) req.getServletContext().getAttribute("app.name");String clientIP = req.getRemoteAddr();// 提交任务managedExecutor.submit(new TrackedTask(appName, clientIP));resp.getWriter().write("Task submitted successfully");}// 封装任务的内部类private class TrackedTask implements Runnable {private final String appName;private final String clientIP;TrackedTask(String appName, String clientIP) {this.appName = appName;this.clientIP = clientIP;}@Overridepublic void run() {MDC.put("app", appName); // 日志上下文MDC.put("client", clientIP);try {logger.info("Starting background task");// 业务逻辑...logger.info("Task completed");} catch (Exception e) {logger.error("Task failed", e);} finally {MDC.clear();}}}
}

使用这种模式,您可以:

  1. 安全地在后台线程执行任务

  2. 保留必要的上下文信息

  3. 获得完善的错误处理和日志跟踪

  4. 完全兼容 WebSphere 环境

  5. 避免 getStandardContext failed 错误

对于大多数场景,使用 ManagedExecutorService 并遵循上述模式即可解决线程上下文问题。

==

■ManagedExecutorService 这个类,在那个jar中

规范定义包(通用)

  • 包名javax.enterprise.concurrent(Java EE 7/8)或 jakarta.enterprise.concurrent(Jakarta EE 9+)

  • API JAR:

    • Java EE 7/8: javax.enterprise.concurrent-api.jar(例如 WildFly/JBoss 提供)

    • Jakarta EE 9+: jakarta.enterprise.concurrent-api.jar

  • 说明
    此 JAR 仅包含接口定义(如 ManagedExecutorService),不包含实现。实现由应用服务器提供

总结

  • 开发阶段:依赖 javax.enterprise.concurrent-api 或 jakarta.enterprise.concurrent-api 编写接口代码。

  • 运行时:实现类由应用服务器提供(如 WebSphere 的 com.ibm.ws.concurrent.jar)。

  • 配置建议:通过 @Resource 注入或 JNDI 获取实例,避免手动创建线程池

注意:不适用WebSphere 8.5.5,没有【com.ibm.ws.concurrent.jar】这个jar

WebSphere 8.5.5 里面没有 

WebSphere 8.5.5

在8.5.5版本中,并发工具的实现通常在以下jar包中:

- `com.ibm.ws.concurrent_1.0.0.jar` (在传统版本中可能是`com.ibm.ws.concurrent.jar`)

- 或者合并到`com.ibm.ws.runtime.jar`中(因为并发工具是运行时的一部分)

WebSphere 9.0及以上

在9.0及更高版本中,通常有独立的并发jar包,例如:

- `com.ibm.ws.concurrent_1.0.0.jar`

- `com.ibm.ws.concurrent.cdi_1.0.0.jar`(用于CDI集成)

■各个WebSphere版本中,线程(线程池)相关的jar

===

我在WebSphere 8.5.5中,找到了runtime.jar,但是里面没有【com.ibm.ws.threading.WSManagedExecutorService】这个类

- 确保版本至少为8.5.5.0(初始版本)

- 推荐升级到8.5.5.20或更高

2. 考虑功能缺失:

- 某些精简安装可能未包含并发工具

- 重新安装时选择“完整功能”

3. 使用传统WorkManager:

===

WebSphere 版本实现位置实现类名
8.5.x 及更早lib/com.ibm.ws.runtime.jarcom.ibm.ws.threading.WSManagedExecutorService
9.x+plugins/com.ibm.ws.concurrent_*.jarcom.ibm.ws.concurrent.WSManagedExecutorService
Libertywlp/lib/com.ibm.websphere.concurrent_*.jarcom.ibm.ws.concurrent.WSManagedExecutorServiceImpl

===

■WebSphere Liberty 是什么

===

WebSphere Liberty 是 IBM 推出的新一代轻量级、高性能应用服务器,专为云原生和微服务架构设计。它是传统 WebSphere Application Server(WAS)的现代化替代品,代表了应用服务器技术的未来发展方向。

🚀 核心特性

特性传统 WebSphereWebSphere Liberty
架构单体式,重量级模块化,轻量级
启动时间分钟级(30s-5min)秒级(<3s)
内存占用高(GB级)极低(<100MB)
配置方式XML + 控制台声明式配置(server.xml)
运行时模型全功能运行按需加载特性
云支持有限原生云集成(K8s,OpenShift)

===

🏢 与传统 WebSphere 的关系

维度WebSphere TraditionalWebSphere Liberty
定位企业级关键业务系统云原生/微服务/敏捷开发
许可证需单独购买免费开发者版 + 商业版
迁移路径-提供 传统到Liberty迁移工具
管理方式集中式管理控制台REST API + 命令行 + 图形界面
版本更新年度大版本季度滚动更新

===

■我在WebSphere 8.5.5中,找到了runtime.jar,但是里面没有【com.ibm.ws.threading.WSManagedExecutorService】这个类

===

com.ibm.ws.threading.ThreadPoolManager 这里类也没有呀,根本就不存在 com.ibm.ws.threading 这个包。

===

🔍 根本原因分析

在 WebSphere 8.5.5 中:

  1. ManagedExecutorService 的实现不是通过单独的类
    而是通过动态代理机制实现

  2. 实际工作类
    com.ibm.ws.threading.ThreadPoolManager

  3. 位置
    plugins/com.ibm.ws.runtime.jar (不是 lib/ 目录)

===

# Linux/Unix
jar -tvf $WAS_INSTALL_ROOT/plugins/com.ibm.ws.runtime.jar | grep ThreadPoolManager# Windows
jar -tvf "%WAS_INSTALL_ROOT%\plugins\com.ibm.ws.runtime.jar" | findstr ThreadPoolManager

com.ibm.ws.threading.ThreadPoolManager】也没有找到,而且根本不存在 com.ibm.ws.threading 这个包。

===

虽然找到了runtime.jar,但是,jar里面没有【com.ibm.ws.threading】这个包

===

■WorkManager

===

ls $WAS_INSTALL_ROOT/AppServer/lib/asynchbeans.jar

====

import com.ibm.websphere.asynchbeans.Work;
import com.ibm.websphere.asynchbeans.WorkManager;
import javax.naming.InitialContext;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;@WebServlet("/workManager")
public class WorkManagerServlet extends HttpServlet {protected void doGet(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) {try {WorkManager wm = (WorkManager) new InitialContext().lookup("java:comp/env/wm/default");wm.startWork(new Work() {@Overridepublic void run() {System.out.println("Task running via WorkManager");performTask();}@Overridepublic void release() {// 清理资源}});} catch (Exception e) {e.printStackTrace();}}private void performTask() {// 同上}
}

===

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/news/908905.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

代码规范和架构【立芯理论一】(2025.06.08)

1、代码规范的目标 代码简洁精炼、美观&#xff0c;可持续性好高效率高复用&#xff0c;可移植性好高内聚&#xff0c;低耦合没有冗余规范性&#xff0c;代码有规可循&#xff0c;可以看出自己当时的思考过程特殊排版&#xff0c;特殊语法&#xff0c;特殊指令&#xff0c;必须…

【samba】umount:**** target is busy. ubuntu24.04 卸载挂载点

当你看到 target is busy&#xff0c;说明仍有进程在使用该挂载点或你当前的 shell 就位于该目录下。可以按下面步骤排查并强制卸载&#xff1a; 1. 确保不在挂载目录下 先切换到其它目录&#xff0c;避免当前 shell 占用&#xff1a; cd ~2. 查找占用该挂载点的进程 使用 fu…

网站首页菜单两种布局vue+elementui顶部和左侧栏导航

顶部菜单实现 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Vue.js Element UI 路由导航</…

使用 Python 正则表达式实现文本替换与电话号码规范化

文章大纲 以下是针对“使用 Python 正则表达式进行文本替换与电话号码规范化”主题的详细技术文章大纲。文章将全面探讨正则表达式在文本替换中的应用&#xff0c;特别是在处理电话号码规范化问题中的具体实现。每个部分的预计字符数反映了其在文章中的重要性&#xff0c;总计…

Python爬虫实战:从零构建高性能分布式爬虫系统

Python爬虫实战&#xff1a;从零构建高性能分布式爬虫系统 引言 在当今数据驱动的时代&#xff0c;网络爬虫已成为获取和分析互联网数据的重要工具。本文将带你从零开始构建一个高性能的分布式爬虫系统&#xff0c;涵盖从基础概念到高级技巧的全方位知识&#xff0c;帮助你在…

PostgreSQL 技术峰会,聚焦国产生态与前沿技术

PostgreSQL 技术峰会是由重庆思庄携手工信部中国开源软件联盟 PostgreSQL 分会联合举办的一场技术盛宴。峰会以 “PostgreSQL 与国产生态” 为主题&#xff0c;聚焦国产生态与前沿技术&#xff0c;致力于为开发者、运维工程师和技术决策者提供全面且深入的知识赋能。以下是其相…

Java详解LeetCode 热题 100(27):LeetCode 21. 合并两个有序链表(Merge Two Sorted Lists)详解

文章目录 1. 题目描述1.1 链表节点定义 2. 理解题目2.1 问题可视化2.2 核心挑战 3. 解法一&#xff1a;迭代法&#xff08;哨兵节点&#xff09;3.1 算法思路3.2 Java代码实现3.3 详细执行过程演示3.4 执行结果示例3.5 复杂度分析3.6 优缺点分析 4. 解法二&#xff1a;递归法4.…

面试高频问题

文章目录 &#x1f680; 消息队列核心技术揭秘&#xff1a;从入门到秒杀面试官1️⃣ Kafka为何能"吞云吐雾"&#xff1f;性能背后的秘密1.1 顺序写入与零拷贝&#xff1a;性能的双引擎1.2 分区并行&#xff1a;数据的"八车道高速公路"1.3 页缓存与批量处理…

Day49 Python打卡训练营

知识点回顾&#xff1a; 1.通道注意力模块复习 2.空间注意力模块 3.CBAM的定义 cbam模块介绍 cbam注意力 之前我们介绍了se通道注意力&#xff0c;我们说所有的模块本质上只是对特征进一步提取&#xff0c;今天进一步介绍cbam注意力 CBAM 是一种能够集成到任何卷积神经网络…

MySQL:Cannot remove all partitions, use DROP TABLE instead

目录 一、 出现场景二、问题原因三、 解决方案 一、 出现场景 在MySQL创建分区之后&#xff0c;要删除所有分区时&#xff0c;最后一个分区删除不了。 二、问题原因 这是因为 MySQL 不允许通过 ALTER TABLE … DROP PARTITION 删除所有分区&#xff0c;因为分区是表的核心结…

深度学习水论文:mamba+图像增强

&#x1f9c0;当前视觉领域对高效长序列建模需求激增&#xff0c;对Mamba图像增强这方向的研究自然也逐渐火热。原因在于其高效长程建模&#xff0c;以及动态计算优势&#xff0c;在图像质量提升和细节恢复方面有难以替代的作用。 &#x1f9c0;因此短时间内&#xff0c;就有不…

今天对C语言中static和extern关键字的作用认识又深刻了

用了这么久的C语言&#xff0c;之前对于static关键字的用法总是一知半解&#xff0c;今天终于搞清楚了&#xff0c;写个文章简单记录一下。 用static修饰的变量&#xff0c;不管是全局变量还是局部变量&#xff0c;其存储位置都是静态存储区&#xff0c;全局变量作用域是当前文…

河北对口计算机高考MySQL笔记(完结版)(2026高考)持续更新~~~~

MySQL 基础概念 数据&#xff08;Data&#xff09;&#xff1a;文本&#xff0c;数字&#xff0c;图片&#xff0c;视频&#xff0c;音频等多种表现形式&#xff0c;能够被计算机存储和处理。 **数据库&#xff08;Data Base—简称DB&#xff09;&#xff1a;**存储数据的仓库…

vmware ubuntu扩展硬盘(可用)

一、 右键需要的虚拟机&#xff0c;选择设置&#xff0c;调整最大内存 二、安装gparted软件 sudo apt-get install gparted 三、搜索应用然后打开 四、右键/dev/sda3 五、调整大小 六、勾选确定 点绿色勾&#xff1a;

RoBERTa 和 BERT 的简介与对比

RoBERTa 和 BERT 是什么 一、BERT(Bidirectional Encoder Representations from Transformers) 提出背景:由谷歌于2019年提出,是自然语言处理领域的里程碑模型,基于Transformer编码器架构,通过预训练生成双向语言表示。 核心特点: 双向预训练:通过掩码语言模型(MLM)…

前端绘制道路鱼骨图

项目背景&#xff1a;需要实现道路情况鱼骨图&#xff0c;根据上下行道路分别显示对应的道路情况和沿路设施状况&#xff0c;箭头根据所示方向平滑移动 1.封装组件&#xff0c;创建FishboneDiagram.vue文件 <template><div class"fishedOneBox flex items-cente…

selinux firewalld

一、selinux 1.说明 SELinux 是 Security-Enhanced Linux 的缩写,意思是安全强化的 linux; SELinux 主要由美国国家安全局(NSA)开发,当初开发的目的是为了避免资源的误用 DAC(Discretionary Access Control)自主访问控制系统MAC(Mandatory Access Control)强制访问控…

RSS 2025|从说明书学习复杂机器人操作任务:NUS邵林团队提出全新机器人装配技能学习框架Manual2Skill

视觉语言模型&#xff08;Vision-Language Models, VLMs&#xff09;&#xff0c;为真实环境中的机器人操作任务提供了极具潜力的解决方案。 尽管 VLMs 取得了显著进展&#xff0c;机器人仍难以胜任复杂的长时程任务&#xff08;如家具装配&#xff09;&#xff0c;主要受限于人…

NPOI Excel用OLE对象的形式插入文件附件以及插入图片

static void Main(string[] args) {XlsWithObjData();Console.WriteLine("输出完成"); }static void XlsWithObjData() {// 创建工作簿和单元格,只有HSSFWorkbook,XSSFWorkbook不可以HSSFWorkbook workbook new HSSFWorkbook();HSSFSheet sheet (HSSFSheet)workboo…

企业数字化转型实战:某行业研究院如何通过SD-WAN技术优化网络架构?

一、引言 随着企业数字化转型的深入推进&#xff0c;传统网络架构在灵活性、可靠性和管理效率方面逐渐暴露不足。SD-WAN&#xff08;软件定义广域网&#xff09;技术凭借其智能化、自动化和高效的特点&#xff0c;逐渐成为企业网络架构优化的首选方案。本文以某研究院数字化基…