You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java17升级后sun.net.SocksProxy非法访问错误求助

问题:Java 17升级后访问sun.net.SocksProxy触发IllegalAccessError

我的应用在Java 11环境运行正常,但升级到Java 17后出现以下错误:

2022-08-05 09:02:09.323 ERROR 1 --- [      ASYNC-182] .a.i.SimpleAsyncUncaughtExceptionHandler : Unexpected exception occurred invoking async method: public void com.freeproxy.sdkservice.services.asyncProxyCheck.async.AsyncProxyCheck.asyncProxyCheck(java.lang.String,java.lang.String,java.lang.String,int,java.lang.String,java.lang.String,java.lang.String)
java.lang.IllegalAccessError: class com.freeproxy.sdkservice.services.asyncProxyCheck.async.AsyncProxyCheck (in unnamed module @0xd7b1517) cannot access class sun.net.SocksProxy (in module java.base) because module java.base does not export sun.net to unnamed module @0xd7b1517
    at com.freeproxy.sdkservice.services.asyncProxyCheck.async.AsyncProxyCheck.socksProxyCheck(AsyncProxyCheck.groovy:130) ~[classes!/:na]
    at com.freeproxy.sdkservice.services.asyncProxyCheck.async.AsyncProxyCheck.asyncProxyCheck(AsyncProxyCheck.groovy:112) ~[classes!/:na]
    at com.freeproxy.sdkservice.services.asyncProxyCheck.async.AsyncProxyCheck$$FastClassBySpringCGLIB$$4cf6e456.invoke(<generated>) ~[classes!/:na]
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) ~[spring-core-5.3.20.jar!/:5.3.20]
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:793) ~[spring-aop-5.3.20.jar!/:5.3.20]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-5.3.20.jar!/:5.3.20]
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763) ~[spring-aop-5.3.20.jar!/:5.3.20]
    at org.springframework.aop.interceptor.AsyncExecutionInterceptor.lambda$invoke$0(AsyncExecutionInterceptor.java:115) ~[spring-aop-5.3.20.jar!/:5.3.20]
    at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) ~[na:na]
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) ~[na:na]
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) ~[na:na]
    at java.base/java.lang.Thread.run(Thread.java:833) ~[na:na]

该错误在调用以下使用SocksProxy的方法时触发:

int socksProxyCheck(String proxyIp, int proxyPort, String url, int version, String proxyLogin = null, String proxyPassword = null) {
        try {
            URL webUrl = new URL(url)
            SocksProxy proxy = SocksProxy.create(new InetSocketAddress(proxyIp, proxyPort), version)
            if (proxyLogin && proxyPassword) {
                setAuthentication(proxyLogin, proxyPassword)
            }
            URLConnection con = (HttpURLConnection) webUrl.openConnection(proxy)
            con.setRequestMethod("GET")
            con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded")
            con.setRequestProperty("Content-Language", "en-US")
            con.setConnectTimeout(5000)
            con.connect()
            int responseCode = con.responseCode
            con.disconnect()
            return responseCode
        } catch (e) {
        }
        return -1
    }

我的gradle-wrapper.properties文件:

distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

build.gradle文件:

plugins {
    id 'org.springframework.boot' version '2.7.0'
    id 'io.spring.dependency-management' version '1.0.11.RELEASE'
    id 'groovy'
//  id 'com.avast.gradle.docker-compose' version '0.7.1'
}

allprojects {

    apply plugin: 'groovy'
    apply plugin: 'org.springframework.boot'
    apply plugin: 'io.spring.dependency-management'

    group = 'com.free-proxy'
    sourceCompatibility = '17'
    targetCompatibility = '17'
    buildDir = '../build'

    configurations {
        compileOnly {
            extendsFrom annotationProcessor
        }
    }

    dependencies {

        // different dependencies go here
    }

    repositories {
        mavenCentral()
    }

}

我推测是Java 17相对Java 11的配置变更导致的,求修复方案。


解决方案

问题根源

Java 9引入模块系统后,sun.net.SocksProxy属于java.base模块的内部非公开API。Java 11对内部API的访问限制较宽松,但Java 17严格执行了模块封装规则,禁止未命名模块(你的应用)访问java.base模块未对外导出的包,因此触发IllegalAccessError。

方法一:替换为Java标准API(推荐)

不要依赖内部API,改用Java标准库提供的Proxy类实现SOCKS代理功能,认证部分用Authenticator处理:

int socksProxyCheck(String proxyIp, int proxyPort, String url, int version, String proxyLogin = null, String proxyPassword = null) {
    try {
        URL webUrl = new URL(url)
        // 使用标准Proxy类创建SOCKS代理
        Proxy proxy = new Proxy(Proxy.Type.SOCKS, new InetSocketAddress(proxyIp, proxyPort))
        
        // 处理代理认证(如果需要)
        if (proxyLogin != null && proxyPassword != null) {
            Authenticator originalAuthenticator = Authenticator.getDefault()
            Authenticator.setDefault(new Authenticator() {
                @Override
                protected PasswordAuthentication getPasswordAuthentication() {
                    return new PasswordAuthentication(proxyLogin, proxyPassword.toCharArray())
                }
            })
        }

        URLConnection con = (HttpURLConnection) webUrl.openConnection(proxy)
        con.setRequestMethod("GET")
        con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded")
        con.setRequestProperty("Content-Language", "en-US")
        con.setConnectTimeout(5000)
        con.connect()
        
        int responseCode = con.getResponseCode()
        con.disconnect()
        
        // 恢复默认Authenticator,避免影响其他请求
        if (proxyLogin != null && proxyPassword != null) {
            Authenticator.setDefault(originalAuthenticator)
        }
        
        return responseCode
    } catch (Exception e) {
        e.printStackTrace()
    }
    return -1
}

方法二:添加JVM参数临时放宽限制(仅过渡用)

如果暂时无法重构代码,可以通过JVM参数强制让java.base模块导出sun.net包给未命名模块:

--add-exports java.base/sun.net=ALL-UNNAMED

在Spring Boot的Gradle配置中,可将参数添加到bootRun任务:

bootRun {
    jvmArgs = ['--add-exports', 'java.base/sun.net=ALL-UNNAMED']
}

注意:这只是临时方案,未来Java版本可能彻底移除这些内部API,最终仍需替换为标准API。

内容的提问来源于stack exchange,提问作者Oleksandr Popov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 10:06:45