当Spring Boot应用从Java 17升级到Java 25时,会抛出异常java.lang.NoClassDefFoundError: sun/security/action/GetPropertyAction

后端开发 2026-07-10

我有一个基于Java 17的应用程序,使用IIOP CORBA协议来监听JMS消息连接并对其进行后续处理。

从Java 17升级到Java25之后,我得到如下错误,提示 “Exception java.lang.NoClassDefFoundError: sun/security/action/GetPropertyAction”。

我不想将系统降级到Java 21或更低版本,我希望系统继续使用Java 25。

我想监听来自仅支持IIOP CORBA协议的服务器的JMS消息/事件。现在在Java 25中,如何实现?我听说IBM在 Java 25中移除了这项支持。

import java.util.Properties;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.ReentrantLock;
import javax.jms.*;
import javax.naming.Context;
import javax.naming.InitialContext;

import com.ibm.ws.sib.api.jms.impl.JmsObjectMessageImpl;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import com.aa.oss.dd.access.notification.Event;

@Component
public class NasdaNotificationListener
                implements MessageListener
{
    private static final Logger LOGGER = LogManager.getLogger( NasdaNotificationListener.class );
    private static final int MAX_RECONNECT_BACKOFF_MS = 60000; // 1 minute max backoff
    private static final int INITIAL_RECONNECT_DELAY_MS = 2000; // 2 seconds initial delay
    private final ReentrantLock lock = new ReentrantLock();
    @Value( "${java-naming-provider-url}" )
    private String javaNamingProviderUrl;
    private TopicConnection connection = null;
    private TopicSession subSession = null;
    private TopicSubscriber subscriber = null;
    private volatile boolean isConnected = false;
    private final AtomicInteger consecutiveFailures = new AtomicInteger( 0 );

    public void startConnection()
    {
        lock.lock();
        try
        {
            // If already connected, skip
            if( isConnected )
            {
                LOGGER.info( "NotificationListener already connected, skipping startConnection" );
                return;
            }

            String methodName = "startConnection";

            LOGGER.info( NWConstants.SE_NAME + " " + methodName + " Trust store: " + System.getProperty(
                            "javax.net.ssl.trustStore" ) );
            LOGGER.info( NWConstants.SE_NAME + " " + methodName + " Key store: " + System.getProperty(
                            "javax.net.ssl.keyStore" ) );

            Properties properties = new Properties();
            properties.put( Context.INITIAL_CONTEXT_FACTORY,
                            NWConstants.NASDA_INITIAL_CONTEXT_FACTORY );
            properties.put( Context.PROVIDER_URL, javaNamingProviderUrl );

            InitialContext jndi = new InitialContext( properties );
            LOGGER.info( NWConstants.SE_NAME + " " + methodName + " got initial context" );
            TopicConnectionFactory conFactory = (TopicConnectionFactory)jndi.lookup(
                            NWConstants.NASDA_TCF_NAME );
            connection = conFactory.createTopicConnection();
            LOGGER.info( NWConstants.SE_NAME + " " + methodName + " creating sub session" );

            subSession = connection.createTopicSession( false, Session.AUTO_ACKNOWLEDGE );
            LOGGER.info( NWConstants.SE_NAME + " " + methodName + " creating topic" );
            // Look up a JMS topic
            Topic nasdaTopic = (Topic)jndi.lookup( NWConstants.NASDA_TOPIC_NAME );

            LOGGER.info( NWConstants.SE_NAME + " " + methodName + " creating subscriber" );
            subscriber = subSession.createSubscriber( nasdaTopic );

            LOGGER.info( NWConstants.SE_NAME + " " + methodName + " creating message listener" );
            // Set a JMS message listener
            subscriber.setMessageListener( this );
            LOGGER.info( NWConstants.SE_NAME + " " + methodName + " starting consumer" );
            // Start the JMS connection; allows messages to be delivered

            connection.start();
            isConnected = true;
            consecutiveFailures.set( 0 ); // Reset backoff counter on success

            Message msg = new JmsObjectMessageImpl(
                            new Event( NWConstants.NASDA_EVENT_CLIENT_START, null ) );
            msg.setJMSMessageID( NWConstants.NASDA_START_NOTIFICATION_MESSAGE_ID );

            NotificationQueue.getInstance().offerMessage( msg );

            connection.setExceptionListener( jmsexception -> {
                LOGGER.warn( NWConstants.SE_NAME + " connection exception handler: " + jmsexception.getMessage(),
                             jmsexception );
                silentStopConnection();
            } );
            LOGGER.info( "NasdaNotificationListener startConnection end" );

        }
        catch( Exception e )
        {
            isConnected = false;
            int failures = consecutiveFailures.incrementAndGet();
            LOGGER.error( NWConstants.SE_NAME + " Starting connection failed (attempt {}): {}",
                          failures, e.getMessage(), e );
            // Clean up partially created resources to avoid resource leaks
            silentStopConnection();
        }
        finally
        {
            lock.unlock();
        }
    }

    public final void stopConnection()
    {
        lock.lock();
        try
        {
            silentClose( subscriber, "subscriber" );
            subscriber = null;

            silentClose( subSession, "subSession" );
            subSession = null;

            if( connection != null )
            {
                try
                {
                    connection.close();
                    LOGGER.info( NWConstants.SE_NAME + " Closed connection" );
                }
                catch( Exception e )
                {
                    LOGGER.debug( "Error closing JMS connection (may already be closed): {}", e.getMessage() );
                }
                connection = null;
            }

            try
            {
                Message msg = new JmsObjectMessageImpl(
                                new Event( NWConstants.NASDA_EVENT_CLIENT_STOP, null ) );
                msg.setJMSMessageID( NWConstants.NASDA_STOP_NOTIFICATION_MESSAGE_ID );
                NotificationQueue.getInstance().offerMessage( msg );
            }
            catch( Exception e )
            {
                LOGGER.debug( "Error sending stop notification message: {}", e.getMessage() );
            }
        }
        finally
        {
            isConnected = false;
            lock.unlock();
        }
    }

    /**
     * Stop connection silently without acquiring lock (used from exception listener
     * which may be called while lock is not held by this thread).
     */
    private void silentStopConnection()
    {
        try
        {
            silentClose( subscriber, "subscriber" );
            subscriber = null;
            silentClose( subSession, "subSession" );
            subSession = null;
            if( connection != null )
            {
                try
                {
                    connection.close();
                }
                catch( Exception ignored )
                {
                    // Already broken
                }
                connection = null;
            }
        }
        catch( Exception e )
        {
            LOGGER.debug( "Error during silent stop: {}", e.getMessage() );
        }
        finally
        {
            isConnected = false;
        }
    }

    /**
     * Safely close a JMS resource, ignoring any exceptions.
     */
    private void silentClose( AutoCloseable resource, String name )
    {
        if( resource != null )
        {
            try
            {
                if( resource instanceof TopicSubscriber )
                {
                    ( (TopicSubscriber)resource ).setMessageListener( null );
                }
                resource.close();
            }
            catch( Exception e )
            {
                LOGGER.debug( "Error closing {} (may already be closed): {}", name, e.getMessage() );
            }
        }
    }

    @Override
    public final void onMessage( Message msg )
    {
        try
        {
            LOGGER.debug( NWConstants.SE_NAME + " Recieved message from topic: " + msg );
        }
        catch( Exception e )
        {
            LOGGER.error( NWConstants.SE_NAME + "Invalid notifiaction from Nasda.", e );
        }
    }
}

并出现如下错误:

Failed to initialize the ORB
javax.naming.NamingException: Failed to initialize the ORB
        at com.ibm.ws.naming.util.Helpers.getOrb(Helpers.java:517)
        at com.ibm.ws.naming.util.WsnInitCtxFactory.getInitialContextInternal(WsnInitCtxFactory.java:478)
        at com.ibm.ws.naming.util.WsnInitCtx.getContext(WsnInitCtx.java:128)
        at com.ibm.ws.naming.util.WsnInitCtx.getContextIfNull(WsnInitCtx.java:765)
        at com.ibm.ws.naming.util.WsnInitCtx.lookup(WsnInitCtx.java:164)
        at com.ibm.ws.naming.util.WsnInitCtx.lookup(WsnInitCtx.java:179)
        at java.naming/javax.naming.InitialContext.lookup(InitialContext.java:409)
        at com.nokia.oss.mediation.ne3sws.nasda.NasdaNotificationListener.startConnection(NasdaNotificationListener.java:62)
        at com.nokia.oss.mediation.ne3sws.NE3SWSApplicationRunner.run(NE3SWSApplicationRunner.java:59)
        at org.springframework.boot.SpringApplication.lambda$callRunner$0(SpringApplication.java:788)
        at org.springframework.util.function.ThrowingConsumer$1.acceptWithException(ThrowingConsumer.java:82)
        at org.springframework.util.function.ThrowingConsumer.accept(ThrowingConsumer.java:60)
        at org.springframework.util.function.ThrowingConsumer$1.accept(ThrowingConsumer.java:86)
        at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:800)
        at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:788)
        at org.springframework.boot.SpringApplication.lambda$callRunners$0(SpringApplication.java:776)
        at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:186)
        at java.base/java.util.stream.SortedOps$SizedRefSortingSink.end(SortedOps.java:357)
        at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:571)
        at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:560)
        at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:153)
        at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:176)
        at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:265)
        at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:632)
        at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:776)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:328)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1365)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1354)
        at com.nokia.oss.mediation.ne3sws.NE3SWSMediationApp.main(NE3SWSMediationApp.java:36)
        at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
        at java.base/java.lang.reflect.Method.invoke(Method.java:565)
        at org.springframework.boot.loader.launch.Launcher.launch(Launcher.java:106)
        at org.springframework.boot.loader.launch.Launcher.launch(Launcher.java:64)
        at org.springframework.boot.loader.launch.JarLauncher.main(JarLauncher.java:40)
Caused by: java.lang.reflect.InvocationTargetException
        at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:119)
        at java.base/java.lang.reflect.Method.invoke(Method.java:565)
        at com.ibm.ws.naming.util.Helpers.getOrb(Helpers.java:508)
        ... 33 more
Caused by: java.lang.NoClassDefFoundError: Could not initialize class javax.rmi.CORBA.Util
        at com.ibm.rmi.corba.PluginRegistry.instantiatePlugins(PluginRegistry.java:116)
        at com.ibm.rmi.corba.ORB.instantiatePlugins(ORB.java:1525)
        at com.ibm.rmi.corba.ORB.orbParameters(ORB.java:1430)
        at com.ibm.rmi.corba.ORB.set_parameters(ORB.java:1356)
        at com.ibm.CORBA.iiop.ORB.set_parameters(ORB.java:1697)
        at org.omg.CORBA.ORB.init(ORB.java:473)
        at com.ibm.ws.orb.GlobalORBFactory.init(GlobalORBFactory.java:95)
        at com.ibm.ejs.oa.EJSORBImpl.initializeORB(EJSORBImpl.java:169)
        at com.ibm.ejs.oa.EJSClientORBImpl.<init>(EJSClientORBImpl.java:64)
        at com.ibm.ejs.oa.EJSClientORBImpl.<init>(EJSClientORBImpl.java:44)
        at com.ibm.ejs.oa.EJSORB.init(EJSORB.java:85)
        at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
        ... 35 more
Caused by: java.lang.ExceptionInInitializerError: Exception java.lang.NoClassDefFoundError: sun/security/action/GetPropertyAction [in thread "P=286519:O=0:CT"]
        at javax.rmi.CORBA.Util.createDelegate(Util.java:338)
        at javax.rmi.CORBA.Util.<clinit>(Util.java:65)
        at com.ibm.rmi.corba.PluginRegistry.instantiatePlugins(PluginRegistry.java:116)
        at com.ibm.rmi.corba.ORB.instantiatePlugins(ORB.java:1525)
        at com.ibm.rmi.corba.ORB.orbParameters(ORB.java:1430)
        at com.ibm.rmi.corba.ORB.set_parameters(ORB.java:1356)
        at com.ibm.CORBA.iiop.ORB.set_parameters(ORB.java:1697)
        at org.omg.CORBA.ORB.init(ORB.java:473)
        at com.ibm.ws.orb.GlobalORBFactory.init(GlobalORBFactory.java:95)
        at com.ibm.ejs.oa.EJSORBImpl.initializeORB(EJSORBImpl.java:169)
        at com.ibm.ejs.oa.EJSClientORBImpl.<init>(EJSClientORBImpl.java:64)
        at com.ibm.ejs.oa.EJSClientORBImpl.<init>(EJSClientORBImpl.java:44)
        at com.ibm.ejs.oa.EJSORB.init(EJSORB.java:85)
        at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
        at java.base/java.lang.reflect.Method.invoke(Method.java:565)
        at com.ibm.ws.naming.util.Helpers.getOrb(Helpers.java:508)
        at com.ibm.ws.naming.util.WsnInitCtxFactory.getInitialContextInternal(WsnInitCtxFactory.java:478)
        at com.ibm.ws.naming.util.WsnInitCtx.getContext(WsnInitCtx.java:128)
        at com.ibm.ws.naming.util.WsnInitCtx.getContextIfNull(WsnInitCtx.java:765)
        at com.ibm.ws.naming.util.WsnInitCtx.lookup(WsnInitCtx.java:164)
        at com.ibm.ws.naming.util.WsnInitCtx.lookup(WsnInitCtx.java:179)
        at java.naming/javax.naming.InitialContext.lookup(InitialContext.java:409)
        at org.springframework.jndi.JndiTemplate.lambda$lookup$0(JndiTemplate.java:154)
        at org.springframework.jndi.JndiTemplate.execute(JndiTemplate.java:89)
        at org.springframework.jndi.JndiTemplate.lookup(JndiTemplate.java:154)
        at org.springframework.jndi.JndiTemplate.lookup(JndiTemplate.java:176)
        at org.springframework.jndi.JndiLocatorSupport.lookup(JndiLocatorSupport.java:106)
        at org.springframework.jndi.JndiLocatorDelegate.lookup(JndiLocatorDelegate.java:65)
        at org.springframework.jndi.JndiLocatorSupport.lookup(JndiLocatorSupport.java:79)
        at org.springframework.jndi.JndiLocatorDelegate.lookup(JndiLocatorDelegate.java:60)
        at org.springframework.jndi.JndiPropertySource.getProperty(JndiPropertySource.java:93)
        at org.springframework.boot.context.properties.source.SpringConfigurationPropertySource.getPropertySourceProperty(SpringConfigurationPropertySource.java:110)
        at org.springframework.boot.context.properties.source.SpringConfigurationPropertySource.getConfigurationProperty(SpringConfigurationPropertySource.java:92)
        at org.springframework.boot.context.properties.source.ConfigurationPropertySourcesPropertySource.findConfigurationProperty(ConfigurationPropertySourcesPropertySource.java:72)
        at org.springframework.boot.context.properties.source.ConfigurationPropertySourcesPropertyResolver.findPropertyValue(ConfigurationPropertySourcesPropertyResolver.java:101)
        at org.springframework.boot.context.properties.source.ConfigurationPropertySourcesPropertyResolver.getProperty(ConfigurationPropertySourcesPropertyResolver.java:78)
        at org.springframework.boot.context.properties.source.ConfigurationPropertySourcesPropertyResolver.getProperty(ConfigurationPropertySourcesPropertyResolver.java:64)
        at org.springframework.core.env.AbstractEnvironment.getProperty(AbstractEnvironment.java:552)
        at org.springframework.boot.cloud.CloudPlatform.isActive(CloudPlatform.java:191)
        at org.springframework.boot.cloud.CloudFoundryVcapEnvironmentPostProcessor.postProcessEnvironment(CloudFoundryVcapEnvironmentPostProcessor.java:120)
        at org.springframework.boot.support.EnvironmentPostProcessorApplicationListener.onApplicationEnvironmentPreparedEvent(EnvironmentPostProcessorApplicationListener.java:137)
        at org.springframework.boot.support.EnvironmentPostProcessorApplicationListener.onApplicationEvent(EnvironmentPostProcessorApplicationListener.java:120)
        at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:180)
        at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:173)
        at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:151)
        at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:133)
        at org.springframework.boot.context.event.EventPublishingRunListener.multicastInitialEvent(EventPublishingRunListener.java:137)
        at org.springframework.boot.context.event.EventPublishingRunListener.environmentPrepared(EventPublishingRunListener.java:82)
        at org.springframework.boot.SpringApplicationRunListeners.lambda$environmentPrepared$0(SpringApplicationRunListeners.java:66)
        at java.base/java.util.ImmutableCollections$List12.forEach(ImmutableCollections.java:681)
        at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:123)
        at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:117)
        at org.springframework.boot.SpringApplicationRunListeners.environmentPrepared(SpringApplicationRunListeners.java:65)
        at org.springframework.boot.SpringApplication.prepareEnvironment(SpringApplication.java:356)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:316)
        ... 8 more

解决方案

You’re hitting two separate but related issues caused by moving to JDK 25:

  1. sun.security.action.GetPropertyAction 是一个内部JDK类,已不再对外部访问(并且实际已移除以供外部使用)。
  2. CORBA/IIOP支持自Java 11起就从JDK中移除(JEP 320),因此依赖内置ORB的任何内容在JDK 25上都无法工作。

There is no supported way to re-enable the old CORBA/IIOP stack in JDK 25.

Why your application breaks

Your JMS 客户端正在使用IIOP(很可能通过 JNDI 与一个基于CORBA的提供者一起使用)。

That stack depends on:

  • The old JDK CORBA implementation (removed)
  • Internal sun.* classes (now strongly encapsulated/absent)

Even if you work around the sun.* access, the CORBA transport itself is gone, so the client cannot function.

What will NOT work:

  • Downgrading compiler flags or adding --add-exports is not a real solution in JDK 25.
  • Adding --add-opens or similar may bypass some reflective access in older JDKs, but does not restore CORBA.
  • There is no official replacement for java.corba inside the JDK.

Viable options

1) Replace IIOP with a supported transport (recommended)

Check whether your JMS provider supports a non-IIOP protocol:

Direct TCP-based JMS client Vendor “thin client” HTTP-based JMS endpoints

Examples:

  • IBM MQ: use the MQ JMS client over TCP instead of IIOP
  • WebSphere: use thin client libraries instead of CORBA-based JNDI

This is the only clean solution that works natively on JDK 25.

2) Use an external CORBA implementation

You can try adding a third-party ORB such as JacORB.

This requires:

  • Adding CORBA libraries manually
  • Reconfiguring ORB initialization
  • Ensuring your JMS provider supports a non-vendor-specific ORB

In practice, this often fails with older enterprise servers (e.g., WebSphere) because they rely on proprietary ORB behavior.

3) Introduce a bridge service (common enterprise workaround)

Run the legacy integration on an older JDK that still works (e.g., 8 or 17), and connect your JDK 25 application to it via a modern protocol.

Architecture:

Legacy service (JDK 8/11/17):

  • Connects via IIOP
  • Consumes JMS messages

New service (JDK 25):

  • Communicates via REST, HTTP, Kafka, etc.

This isolates the unsupported technology while allowing the main system to run on JDK 25.

4) Migrate the server side (long-term)

If you control the JMS server:

Disable IIOP Enable modern protocols (TCP, AMQP, HTTP) Upgrade middleware if necessary

About the specific error

NoClassDefFoundError: sun/security/action/GetPropertyAction

This indicates a dependency (likely your JMS client or CORBA stack) is using internal JDK APIs.

Even if you try:

--add-exports java.base/sun.security.action=ALL-UNNAMED

this is not reliable in JDK 25 and does not solve the missing CORBA implementation.

Bottom line

  • JDK 25 does not include support for CORBA/IIOP.
  • Your current approach (JMS over IIOP using JDK-provided CORBA) cannot be made to work directly.

You must:

  • Switch to a non-IIOP JMS client, or
  • Use a bridge service on an older JDK, or
  • Attempt (with risk) a third-party CORBA ORB.
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章