agora inbox for pljava-dev@postgresql.org  
help / color / mirror / Atom feed
[Pljava-dev] stack depth limit exceeded (NOT from infinite recursion)
7+ messages / 0 participants
[nested] [flat]

* [Pljava-dev] stack depth limit exceeded (NOT from infinite recursion)
@ 2005-09-23 08:56 
  2005-09-23 09:42 ` [Pljava-dev] stack depth limit exceeded (NOT from infinite	recursion) 
  2005-09-23 10:38 ` [Pljava-dev] stack depth limit exceeded (NOT from infinite	recursion) 
  0 siblings, 2 replies; 7+ messages in thread

From:  @ 2005-09-23 08:56 UTC (permalink / raw)

Hi,

I created the following Trigger and Function:

======================================
        CREATE FUNCTION afterUpdateTsr()
            RETURNS trigger
            AS 'pljava.Triggers.afterUpdateTservicerequest'
            LANGUAGE java;

        CREATE TRIGGER tsr_afterUpdate
            AFTER UPDATE ON tsr
            FOR EACH ROW
            EXECUTE PROCEDURE afterUpdateTsr(name);   
==========================================

Then in the afterUpdateTsr() java function, I was writing codes to 
connect to servicemix (a JBI container).

In order to do that, I had to install 11 jar files in my postgresql 
table using sqlj.install_jar function.

When the aferUpdateTsr() got triggered, it was throwing "stack depth 
limit exceeded" exception from native C. (I believed it's from 
ExecutionPlan.c).  I also printed out the loaded classes from 
sqlj/Loader.java (findClass function) and found that pljava was loading 
a lot of classes. 

Was it the main reason causing this exception?  How do I resolve this 
problem?

debug print from sqlj/Loader.java findClass function:
========================================================
path = org/activemq/ActiveMQConnectionFactory.class, entryId[0] = 259
path = javax/jms/ConnectionFactory.class, entryId[0] = 6
path = javax/jms/QueueConnectionFactory.class, entryId[0] = 30
path = javax/jms/TopicConnectionFactory.class, entryId[0] = 45
path = org/activemq/service/Service.class, entryId[0] = 645
path = org/activemq/management/StatsCapable.class, entryId[0] = 503
path = org/activemq/jndi/JNDIBaseStorable.class, entryId[0] = 474
path = org/activemq/jndi/JNDIStorableInterface.class, entryId[0] = 476
path = javax/jms/JMSException.class, entryId[0] = 15
path = org/activemq/broker/BrokerConnector.class, entryId[0] = 307
path = org/activemq/message/ActiveMQDestination.class, entryId[0] = 510
path = org/activemq/message/ActiveMQTopic.class, entryId[0] = 519
path = javax/jms/Topic.class, entryId[0] = 43
path = org/activemq/message/ActiveMQQueue.class, entryId[0] = 514
path = javax/jms/Queue.class, entryId[0] = 27
path = org/activemq/broker/BrokerContainerFactory.class, entryId[0] = 309
path = org/activemq/management/StatsImpl.class, entryId[0] = 504
path = javax/management/j2ee/statistics/Stats.class, entryId[0] = 2505
path = org/activemq/management/Resettable.class, entryId[0] = 501
path = org/activemq/management/StatisticImpl.class, entryId[0] = 502
path = javax/management/j2ee/statistics/Statistic.class, entryId[0] = 2504
path = org/activemq/management/JMSStatsImpl.class, entryId[0] = 498
path = javax/jms/Connection.class, entryId[0] = 4
path = org/activemq/io/WireFormat.class, entryId[0] = 469
path = org/apache/commons/logging/LogFactory.class, entryId[0] = 2524
path = org/apache/commons/logging/LogConfigurationException.class, 
entryId[0] = 2525
path = org/apache/commons/logging/LogFactory$1.class, entryId[0] = 2521
path = org/apache/commons/logging/LogFactory$3.class, entryId[0] = 2523
path = org/apache/commons/logging/LogFactory$2.class, entryId[0] = 2522
path = org/apache/commons/logging/impl/LogFactoryImpl.class, entryId[0] 
= 2514
path = org/apache/commons/logging/impl/LogFactoryImpl$1.class, 
entryId[0] = 2513
path = org/apache/commons/logging/impl/Jdk14Logger.class, entryId[0] = 2509
path = org/apache/commons/logging/Log.class, entryId[0] = 2520
path = org/activemq/broker/BrokerContext.class, entryId[0] = 310
path = EDU/oswego/cs/dl/util/concurrent/ConcurrentHashMap.class, 
entryId[0] = 2549
path = EDU/oswego/cs/dl/util/concurrent/ConcurrentHashMap$Segment.class, 
entryId[0] = 2546
path = EDU/oswego/cs/dl/util/concurrent/ConcurrentHashMap$Entry.class, 
entryId[0] = 2541
path = EDU/oswego/cs/dl/util/concurrent/CopyOnWriteArrayList.class, 
entryId[0] = 2564
path = org/activemq/io/impl/DefaultWireFormat.class, entryId[0] = 423
path = org/activemq/io/impl/AbstractDefaultWireFormat.class, entryId[0] 
= 391
path = org/activemq/io/AbstractWireFormat.class, entryId[0] = 390
path = org/activemq/io/impl/PacketWriter.class, entryId[0] = 433
path = org/activemq/io/impl/PacketReader.class, entryId[0] = 432
path = org/activemq/message/Packet.class, entryId[0] = 535
path = org/activemq/io/util/WireByteArrayOutputStream.class, entryId[0] 
= 467
path = org/activemq/io/util/WireByteArrayInputStream.class, entryId[0] = 466
path = org/activemq/io/impl/ActiveMQMessageReader.class, entryId[0] = 399
path = org/activemq/io/impl/AbstractPacketReader.class, entryId[0] = 393
path = org/activemq/io/impl/ActiveMQTextMessageReader.class, entryId[0] 
= 405
path = org/activemq/io/impl/ActiveMQObjectMessageReader.class, 
entryId[0] = 401
path = org/activemq/io/impl/ActiveMQBytesMessageReader.class, entryId[0] 
= 395
path = org/activemq/io/impl/ActiveMQStreamMessageReader.class, 
entryId[0] = 403
path = org/activemq/io/impl/ActiveMQMapMessageReader.class, entryId[0] = 397
path = org/activemq/io/impl/MessageAckReader.class, entryId[0] = 430
path = org/activemq/io/impl/ReceiptReader.class, entryId[0] = 436
path = org/activemq/io/impl/ConsumerInfoReader.class, entryId[0] = 421
path = org/activemq/io/impl/ProducerInfoReader.class, entryId[0] = 434
path = org/activemq/io/impl/TransactionInfoReader.class, entryId[0] = 443
path = org/activemq/io/impl/XATransactionInfoReader.class, entryId[0] = 447
path = org/activemq/io/impl/BrokerInfoReader.class, entryId[0] = 409
path = org/activemq/io/impl/ConnectionInfoReader.class, entryId[0] = 419
path = org/activemq/io/impl/SessionInfoReader.class, entryId[0] = 440
path = org/activemq/io/impl/DurableUnsubscribeReader.class, entryId[0] = 424
path = org/activemq/io/impl/ResponseReceiptReader.class, entryId[0] = 438
path = org/activemq/io/impl/IntResponseReceiptReader.class, entryId[0] = 426
path = org/activemq/io/impl/CapacityInfoReader.class, entryId[0] = 413
path = org/activemq/io/impl/CapacityInfoRequestReader.class, entryId[0] 
= 414
path = org/activemq/io/impl/WireFormatInfoReader.class, entryId[0] = 445
path = org/activemq/io/impl/KeepAliveReader.class, entryId[0] = 428
path = org/activemq/io/impl/BrokerAdminCommandReader.class, entryId[0] = 407
path = org/activemq/io/impl/CachedValueReader.class, entryId[0] = 411
path = org/activemq/io/impl/CleanupConnectionInfoReader.class, 
entryId[0] = 417
path = org/activemq/io/impl/ActiveMQMessageWriter.class, entryId[0] = 400
path = org/activemq/io/impl/AbstractPacketWriter.class, entryId[0] = 394
path = org/activemq/io/impl/ActiveMQTextMessageWriter.class, entryId[0] 
= 406
path = org/activemq/io/impl/ActiveMQObjectMessageWriter.class, 
entryId[0] = 402
path = org/activemq/io/impl/ActiveMQBytesMessageWriter.class, entryId[0] 
= 396
path = org/activemq/io/impl/ActiveMQStreamMessageWriter.class, 
entryId[0] = 404
path = org/activemq/io/impl/ActiveMQMapMessageWriter.class, entryId[0] = 398
path = org/activemq/io/impl/MessageAckWriter.class, entryId[0] = 431
path = org/activemq/io/impl/ReceiptWriter.class, entryId[0] = 437
path = org/activemq/io/impl/ConsumerInfoWriter.class, entryId[0] = 422
path = org/activemq/io/impl/ProducerInfoWriter.class, entryId[0] = 435
path = org/activemq/io/impl/TransactionInfoWriter.class, entryId[0] = 444
path = org/activemq/io/impl/XATransactionInfoWriter.class, entryId[0] = 448
path = org/activemq/io/impl/BrokerInfoWriter.class, entryId[0] = 410
path = org/activemq/io/impl/ConnectionInfoWriter.class, entryId[0] = 420
path = org/activemq/io/impl/SessionInfoWriter.class, entryId[0] = 441
path = org/activemq/io/impl/DurableUnsubscribeWriter.class, entryId[0] = 425
path = org/activemq/io/impl/ResponseReceiptWriter.class, entryId[0] = 439
path = org/activemq/io/impl/IntResponseReceiptWriter.class, entryId[0] = 427
path = org/activemq/io/impl/CapacityInfoWriter.class, entryId[0] = 416
path = org/activemq/io/impl/CapacityInfoRequestWriter.class, entryId[0] 
= 415
path = org/activemq/io/impl/WireFormatInfoWriter.class, entryId[0] = 446
path = org/activemq/io/impl/KeepAliveWriter.class, entryId[0] = 429
path = org/activemq/io/impl/BrokerAdminCommandWriter.class, entryId[0] = 408
path = org/activemq/io/impl/CachedValueWriter.class, entryId[0] = 412
path = org/activemq/io/impl/CleanupConnectionInfoWriter.class, 
entryId[0] = 418
path = org/activemq/util/IdGenerator.class, entryId[0] = 863
path = org/activemq/ActiveMQPrefetchPolicy.class, entryId[0] = 266
path = org/activemq/message/ActiveMQTemporaryTopic.class, entryId[0] = 517
path = javax/jms/TemporaryTopic.class, entryId[0] = 41
path = org/activemq/message/ActiveMQTemporaryQueue.class, entryId[0] = 516
path = javax/jms/TemporaryQueue.class, entryId[0] = 40
path = org/activemq/management/JMSDestinationStats.class, entryId[0] = 493
INFO:  23 Sep 05 16:02:29 pljava.Triggers Connecting to JMS Server...
path = org/activemq/ActiveMQConnection.class, entryId[0] = 257
path = org/activemq/message/PacketListener.class, entryId[0] = 537
path = javax/jms/ExceptionListener.class, entryId[0] = 10
path = javax/jms/TopicConnection.class, entryId[0] = 44
path = javax/jms/QueueConnection.class, entryId[0] = 29
path = org/activemq/capacity/CapacityMonitorEventListener.class, 
entryId[0] = 330
path = org/activemq/transport/TransportStatusEventListener.class, 
entryId[0] = 834
path = org/activemq/Closeable.class, entryId[0] = 332
path = org/activemq/filter/FilterFactory.class, entryId[0] = 362
path = org/activemq/filter/Filter.class, entryId[0] = 361
path = org/activemq/message/MessageAcknowledge.class, entryId[0] = 534
path = javax/jms/IllegalStateException.class, entryId[0] = 11
path = org/activemq/ActiveMQMessageDispatcher.class, entryId[0] = 263
path = org/activemq/ConnectionClosedException.class, entryId[0] = 334
path = javax/jms/QueueSession.class, entryId[0] = 34
path = javax/jms/Session.class, entryId[0] = 38
path = javax/jms/TopicSession.class, entryId[0] = 48
path = javax/jms/ConnectionConsumer.class, entryId[0] = 5
path = org/activemq/management/JMSConnectionStatsImpl.class, entryId[0] 
= 491
path = javax/jms/ConnectionMetaData.class, entryId[0] = 7
path = org/activemq/TimeoutExpiredException.class, entryId[0] = 740
path = org/activemq/transport/TransportChannelProvider.class, entryId[0] 
= 827
path = org/activemq/util/FactoryFinder.class, entryId[0] = 860
path = org/activemq/transport/tcp/TcpTransportChannelFactory.class, 
entryId[0] = 820
path = org/activemq/transport/TransportChannelFactorySupport.class, 
entryId[0] = 825
path = org/activemq/transport/TransportChannelFactory.class, entryId[0] 
= 824
path = org/activemq/transport/TransportChannel.class, entryId[0] = 823
path = org/activemq/transport/tcp/TcpTransportChannel.class, entryId[0] 
= 819
path = org/activemq/transport/TransportChannelSupport.class, entryId[0] 
= 828
path = org/activemq/UnsupportedWireFormatException.class, entryId[0] = 849
path = org/activemq/transport/tcp/TcpBufferedOutputStream.class, 
entryId[0] = 817
path = EDU/oswego/cs/dl/util/concurrent/Channel.class, entryId[0] = 2536
path = EDU/oswego/cs/dl/util/concurrent/Puttable.class, entryId[0] = 2609
path = EDU/oswego/cs/dl/util/concurrent/Takable.class, entryId[0] = 2647
path = EDU/oswego/cs/dl/util/concurrent/Executor.class, entryId[0] = 2570
path = EDU/oswego/cs/dl/util/concurrent/BoundedChannel.class, entryId[0] 
= 2531
path = org/activemq/io/WireFormatLoader.class, entryId[0] = 470
path = EDU/oswego/cs/dl/util/concurrent/SynchronizedBoolean.class, 
entryId[0] = 2635
path = EDU/oswego/cs/dl/util/concurrent/SynchronizedVariable.class, 
entryId[0] = 2644
path = EDU/oswego/cs/dl/util/concurrent/BoundedLinkedQueue.class, 
entryId[0] = 2532
path = EDU/oswego/cs/dl/util/concurrent/LinkedNode.class, entryId[0] = 2591
path = org/activemq/util/URIHelper.class, entryId[0] = 878
path = EDU/oswego/cs/dl/util/concurrent/SynchronizedInt.class, 
entryId[0] = 2640
path = org/activemq/ActiveMQConnectionMetaData.class, entryId[0] = 260
path = org/activemq/io/util/MemoryBoundedObjectManager.class, entryId[0] 
= 460
path = org/activemq/capacity/BasicCapacityMonitor.class, entryId[0] = 326
path = org/activemq/capacity/CapacityMonitor.class, entryId[0] = 328
path = EDU/oswego/cs/dl/util/concurrent/SynchronizedLong.class, 
entryId[0] = 2641
path = org/activemq/io/util/MemoryBoundedQueueManager.class, entryId[0] 
= 463
path = org/activemq/io/util/MemoryBoundedPrioritizedQueue.class, 
entryId[0] = 461
path = org/activemq/io/util/MemoryBoundedQueue.class, entryId[0] = 462
path = org/activemq/io/util/MemoryBoundedObject.class, entryId[0] = 459
path = javax/jms/XAConnection.class, entryId[0] = 52
path = org/activemq/transport/TransportStatusEvent.class, entryId[0] = 833
path = 
EDU/oswego/cs/dl/util/concurrent/CopyOnWriteArrayList$COWIterator.class, 
entryId[0] = 2561
INFO:  23 Sep 05 16:02:29 org.activemq.ActiveMQConnection channel status 
changed: Channel: TcpTransportChannel: 
Socket[addr=localhost/127.0.0.1,port=61616,localport=4748] has connected
path = org/activemq/message/WireFormatInfo.class, entryId[0] = 545
path = org/activemq/message/AbstractPacket.class, entryId[0] = 508
path = org/activemq/util/BitArray.class, entryId[0] = 853
INFO:  23 Sep 05 16:02:29 com.tokuii.pljava.Triggers Before start
path = org/activemq/message/ConnectionInfo.class, entryId[0] = 528
path = org/activemq/message/ReceiptHolder.class, entryId[0] = 540
path = org/activemq/util/SerializationHelper.class, entryId[0] = 875
path = org/activemq/message/Receipt.class, entryId[0] = 539
INFO:  23 Sep 05 16:02:29 org.postgresql.pljava.sqlj.Loader Failed to 
load class
        org.postgresql.pljava.internal.ServerException: stack depth 
limit exceeded
                at 
org.postgresql.pljava.internal.ExecutionPlan._cursorOpen(Native Method)
                at 
org.postgresql.pljava.internal.ExecutionPlan.cursorOpen(ExecutionPlan.java:136)
                at 
org.postgresql.pljava.jdbc.SPIStatement.executePlan(SPIStatement.java:114)
                at 
org.postgresql.pljava.jdbc.SPIPreparedStatement.execute(SPIPreparedStatement.java:263)
                at 
org.postgresql.pljava.jdbc.SPIPreparedStatement.executeQuery(SPIPreparedStatement.java:72)
                at 
org.postgresql.pljava.sqlj.Loader.findClass(Loader.java:172)
                at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
                at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
                at 
java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319)
                at 
org.activemq.io.impl.ReceiptReader.createPacket(ReceiptReader.java:47)
                at 
org.activemq.io.impl.DefaultWireFormat.readPacket(DefaultWireFormat.java:126)
                at 
org.activemq.io.impl.AbstractDefaultWireFormat.readPacket(AbstractDefaultWireFormat.java:185)
                at 
org.activemq.io.AbstractWireFormat.readPacket(AbstractWireFormat.java:235)
                at 
org.activemq.transport.tcp.TcpTransportChannel.run(TcpTransportChannel.java:309)
                at java.lang.Thread.run(Thread.java:595)
================================================================

Thank you so much for helping.

Regards,
Kong





^ permalink  raw  reply  [nested|flat] 7+ messages in thread

* [Pljava-dev] stack depth limit exceeded (NOT from infinite	recursion)
  2005-09-23 08:56 [Pljava-dev] stack depth limit exceeded (NOT from infinite recursion) 
@ 2005-09-23 09:42 ` 
  1 sibling, 0 replies; 7+ messages in thread

From:  @ 2005-09-23 09:42 UTC (permalink / raw)

kstian wrote:

> Hi,
>
> I created the following Trigger and Function:
>
> ======================================
>        CREATE FUNCTION afterUpdateTsr()
>            RETURNS trigger
>            AS 'pljava.Triggers.afterUpdateTservicerequest'
>            LANGUAGE java;
>
>        CREATE TRIGGER tsr_afterUpdate
>            AFTER UPDATE ON tsr
>            FOR EACH ROW
>            EXECUTE PROCEDURE afterUpdateTsr(name);   
> ==========================================
>
> Then in the afterUpdateTsr() java function, I was writing codes to 
> connect to servicemix (a JBI container).
>
> In order to do that, I had to install 11 jar files in my postgresql 
> table using sqlj.install_jar function.
>
> When the aferUpdateTsr() got triggered, it was throwing "stack depth 
> limit exceeded" exception from native C. (I believed it's from 
> ExecutionPlan.c).  I also printed out the loaded classes from 
> sqlj/Loader.java (findClass function) and found that pljava was 
> loading a lot of classes.
> Was it the main reason causing this exception?  How do I resolve this 
> problem?
>
Normally, a "stack depth limit exceeded" exception is caused by a 
function that calls SQL, that in turn calls a function that calls SQL, 
etc. until you recurse so deep that the PostgreSQL callstack is 
exhausted. If it's a controlled and expected recursion you can try to 
increase the max_stack_depth variable in your postgresql.conf

If you this doesn't help, then I'll have to know a bit more about what 
your triggers are doing in order to assist you.

Kind regards,
Thomas Hallgren








^ permalink  raw  reply  [nested|flat] 7+ messages in thread

* [Pljava-dev] stack depth limit exceeded (NOT from infinite	recursion)
  2005-09-23 08:56 [Pljava-dev] stack depth limit exceeded (NOT from infinite recursion) 
@ 2005-09-23 10:38 ` 
  2005-09-23 10:47   ` [Pljava-dev] stack depth limit exceeded (NOT from infinite	recursion) 
  2005-09-28 01:51   ` [Pljava-dev] stack depth limit exceeded (NOT from infinite	recursion) 
  1 sibling, 2 replies; 7+ messages in thread

From:  @ 2005-09-23 10:38 UTC (permalink / raw)

Hi Thomas,

Thanks for replying.

I have gradually increased max_stack_depth in postgresql.conf to 16384 
(verified from show all in the db) but it did not seem to help.

The following is the code I have for the trigger function.  Basically, 
what I wanted it to do is, upon data update, I wanted to connect to 
serivcemix (jbi container) and publish the event to activeMQ.  The 
problem happened on the line where I marked "==>  <==".  I also printed 
out the loaded classes from sqlj.Loader.java in findClass method and it 
showed a lot of loaded classes.  These classes were to be passed to sql 
statement for loading.

=================================
mport java.sql.SQLException;
import java.sql.ResultSet;
import java.util.logging.Logger;

import org.postgresql.pljava.TriggerData;
import org.postgresql.pljava.TriggerException;


import javax.jms.Connection;
import javax.jms.JMSException;
import javax.jms.Session;
import javax.jms.MessageProducer;

import org.activemq.ActiveMQConnectionFactory;
import org.activemq.ActiveMQConnection;
import org.activemq.message.ActiveMQTopic;

public class Triggers {

    public static void afterUpdateTsr(TriggerData td) throws 
SQLException, JMSException
    {
        if (td.isFiredForStatement())
            throw new TriggerException(td, "Cannot process statement 
events.");
           
        if (td.isFiredBefore())
            throw new TriggerException(td, "Must be fired after event.");
           
        if (!td.isFiredByUpdate())
            throw new TriggerException(td, "Can only process UPDATE event");
           
        ResultSet _new = td.getNew();
        ResultSet _old = td.getOld();
        String[] args = td.getArguments();
        String status = args[1];
       
        if (args.length != 1)
            throw new TriggerException(td, "One argument is expected.");
       
        Logger log = Logger.getAnonymousLogger();
        log.info("After UPDATE to tservicerequest table with new tstatus 
= " + _new.getString(status) + ", old tstatus = " + _old.getString(status));
       
        ActiveMQConnectionFactory factory = new 
ActiveMQConnectionFactory(ActiveMQConnection.DEFAULT_USER, 
ActiveMQConnection.DEFAULT_PASSWORD, 
ActiveMQConnection.DEFAULT_BROKER_URL); //"tcp://localhost:61616");
        ActiveMQTopic pubTopic = new 
ActiveMQTopic("demo.org.servicemix.source");
        //ActiveMQTopic subTopic = new 
ActiveMQTopic("demo.org.servicemix.result");
       
        log.info("Connecting to JMS Server...");
        Connection connection = factory.createConnection();
        log.info("Before setClientID");
==>connection.start();  <==
        Session session = connection.createSession(false, 
Session.AUTO_ACKNOWLEDGE);
        MessageProducer producer = session.createProducer(pubTopic);
        //connection.start();
       
        log.info("Sending request to JMS Server...");
        producer.send(session.createTextMessage("New tstatus= " + 
_new.getString(status) + ", old tstatus= " + _old.getString(status)));
       
        log.info("Sent message: New tstatus= " + _new.getString(status) 
+ ", old tstatus= " + _old.getString(status));
        //connection.close();

    }
}

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

Thanks a lot for help.

Regards,
Kong

Thomas Hallgren wrote:

> kstian wrote:
>
>> Hi,
>>
>> I created the following Trigger and Function:
>>
>> ======================================
>>        CREATE FUNCTION afterUpdateTsr()
>>            RETURNS trigger
>>            AS 'pljava.Triggers.afterUpdateTservicerequest'
>>            LANGUAGE java;
>>
>>        CREATE TRIGGER tsr_afterUpdate
>>            AFTER UPDATE ON tsr
>>            FOR EACH ROW
>>            EXECUTE PROCEDURE afterUpdateTsr(name);   
>> ==========================================
>>
>> Then in the afterUpdateTsr() java function, I was writing codes to 
>> connect to servicemix (a JBI container).
>>
>> In order to do that, I had to install 11 jar files in my postgresql 
>> table using sqlj.install_jar function.
>>
>> When the aferUpdateTsr() got triggered, it was throwing "stack depth 
>> limit exceeded" exception from native C. (I believed it's from 
>> ExecutionPlan.c).  I also printed out the loaded classes from 
>> sqlj/Loader.java (findClass function) and found that pljava was 
>> loading a lot of classes.
>> Was it the main reason causing this exception?  How do I resolve this 
>> problem?
>>
> Normally, a "stack depth limit exceeded" exception is caused by a 
> function that calls SQL, that in turn calls a function that calls SQL, 
> etc. until you recurse so deep that the PostgreSQL callstack is 
> exhausted. If it's a controlled and expected recursion you can try to 
> increase the max_stack_depth variable in your postgresql.conf
>
> If you this doesn't help, then I'll have to know a bit more about what 
> your triggers are doing in order to assist you.
>
> Kind regards,
> Thomas Hallgren
>
>
>
>
>
>





^ permalink  raw  reply  [nested|flat] 7+ messages in thread

* [Pljava-dev] stack depth limit exceeded (NOT from infinite	recursion)
  2005-09-23 08:56 [Pljava-dev] stack depth limit exceeded (NOT from infinite recursion) 
  2005-09-23 10:38 ` [Pljava-dev] stack depth limit exceeded (NOT from infinite	recursion) 
@ 2005-09-23 10:47   ` 
  1 sibling, 0 replies; 7+ messages in thread

From:  @ 2005-09-23 10:47 UTC (permalink / raw)

OK, I see the problem. The connection spawns a new thread, that thread 
loads classes. And of course, the stack of that thread cannot be 
compared to the stack of the caller thread. PostgresSQL (since it's 
singlethreaded) thinks that you eat a vast amount of stack.

I'll address this on the PostgreSQL hackers mailing list and see if I 
can convince them to install something that makes it possible to 
temporary shut off the stack-check. A temporary work-around is to 
reference the needed classes before making the connect call. That way, 
the current thread will be the one who loads them.

Regards,
Thomas Hallgren


kstian wrote:

> Hi Thomas,
>
> Thanks for replying.
>
> I have gradually increased max_stack_depth in postgresql.conf to 16384 
> (verified from show all in the db) but it did not seem to help.
>
> The following is the code I have for the trigger function.  Basically, 
> what I wanted it to do is, upon data update, I wanted to connect to 
> serivcemix (jbi container) and publish the event to activeMQ.  The 
> problem happened on the line where I marked "==>  <==".  I also 
> printed out the loaded classes from sqlj.Loader.java in findClass 
> method and it showed a lot of loaded classes.  These classes were to 
> be passed to sql statement for loading.
>
> =================================
> mport java.sql.SQLException;
> import java.sql.ResultSet;
> import java.util.logging.Logger;
>
> import org.postgresql.pljava.TriggerData;
> import org.postgresql.pljava.TriggerException;
>
>
> import javax.jms.Connection;
> import javax.jms.JMSException;
> import javax.jms.Session;
> import javax.jms.MessageProducer;
>
> import org.activemq.ActiveMQConnectionFactory;
> import org.activemq.ActiveMQConnection;
> import org.activemq.message.ActiveMQTopic;
>
> public class Triggers {
>
>    public static void afterUpdateTsr(TriggerData td) throws 
> SQLException, JMSException
>    {
>        if (td.isFiredForStatement())
>            throw new TriggerException(td, "Cannot process statement 
> events.");
>                  if (td.isFiredBefore())
>            throw new TriggerException(td, "Must be fired after event.");
>                  if (!td.isFiredByUpdate())
>            throw new TriggerException(td, "Can only process UPDATE 
> event");
>                  ResultSet _new = td.getNew();
>        ResultSet _old = td.getOld();
>        String[] args = td.getArguments();
>        String status = args[1];
>              if (args.length != 1)
>            throw new TriggerException(td, "One argument is expected.");
>              Logger log = Logger.getAnonymousLogger();
>        log.info("After UPDATE to tservicerequest table with new 
> tstatus = " + _new.getString(status) + ", old tstatus = " + 
> _old.getString(status));
>              ActiveMQConnectionFactory factory = new 
> ActiveMQConnectionFactory(ActiveMQConnection.DEFAULT_USER, 
> ActiveMQConnection.DEFAULT_PASSWORD, 
> ActiveMQConnection.DEFAULT_BROKER_URL); //"tcp://localhost:61616");
>        ActiveMQTopic pubTopic = new 
> ActiveMQTopic("demo.org.servicemix.source");
>        //ActiveMQTopic subTopic = new 
> ActiveMQTopic("demo.org.servicemix.result");
>              log.info("Connecting to JMS Server...");
>        Connection connection = factory.createConnection();
>        log.info("Before setClientID");
> ==>connection.start();  <==
>        Session session = connection.createSession(false, 
> Session.AUTO_ACKNOWLEDGE);
>        MessageProducer producer = session.createProducer(pubTopic);
>        //connection.start();
>              log.info("Sending request to JMS Server...");
>        producer.send(session.createTextMessage("New tstatus= " + 
> _new.getString(status) + ", old tstatus= " + _old.getString(status)));
>              log.info("Sent message: New tstatus= " + 
> _new.getString(status) + ", old tstatus= " + _old.getString(status));
>        //connection.close();
>
>    }
> }
>
> ===============================================
>
> Thanks a lot for help.
>
> Regards,
> Kong
>
> Thomas Hallgren wrote:
>
>> kstian wrote:
>>
>>> Hi,
>>>
>>> I created the following Trigger and Function:
>>>
>>> ======================================
>>>        CREATE FUNCTION afterUpdateTsr()
>>>            RETURNS trigger
>>>            AS 'pljava.Triggers.afterUpdateTservicerequest'
>>>            LANGUAGE java;
>>>
>>>        CREATE TRIGGER tsr_afterUpdate
>>>            AFTER UPDATE ON tsr
>>>            FOR EACH ROW
>>>            EXECUTE PROCEDURE afterUpdateTsr(name);   
>>> ==========================================
>>>
>>> Then in the afterUpdateTsr() java function, I was writing codes to 
>>> connect to servicemix (a JBI container).
>>>
>>> In order to do that, I had to install 11 jar files in my postgresql 
>>> table using sqlj.install_jar function.
>>>
>>> When the aferUpdateTsr() got triggered, it was throwing "stack depth 
>>> limit exceeded" exception from native C. (I believed it's from 
>>> ExecutionPlan.c).  I also printed out the loaded classes from 
>>> sqlj/Loader.java (findClass function) and found that pljava was 
>>> loading a lot of classes.
>>> Was it the main reason causing this exception?  How do I resolve 
>>> this problem?
>>>
>> Normally, a "stack depth limit exceeded" exception is caused by a 
>> function that calls SQL, that in turn calls a function that calls 
>> SQL, etc. until you recurse so deep that the PostgreSQL callstack is 
>> exhausted. If it's a controlled and expected recursion you can try to 
>> increase the max_stack_depth variable in your postgresql.conf
>>
>> If you this doesn't help, then I'll have to know a bit more about 
>> what your triggers are doing in order to assist you.
>>
>> Kind regards,
>> Thomas Hallgren
>>
>>
>>
>>
>>
>>
>






^ permalink  raw  reply  [nested|flat] 7+ messages in thread

* [Pljava-dev] stack depth limit exceeded (NOT from infinite	recursion)
  2005-09-23 08:56 [Pljava-dev] stack depth limit exceeded (NOT from infinite recursion) 
  2005-09-23 10:38 ` [Pljava-dev] stack depth limit exceeded (NOT from infinite	recursion) 
@ 2005-09-28 01:51   ` 
  2005-09-28 05:42     ` [Pljava-dev] stack depth limit exceeded (NOT from infinite	recursion) 
  2005-09-28 06:38     ` [Pljava-dev] stack depth limit exceeded (NOT from infinite	recursion) 
  1 sibling, 2 replies; 7+ messages in thread

From:  @ 2005-09-28 01:51 UTC (permalink / raw)

Hi Thomas,

Thanks a lot for the info.  I went through reorganizing the installed 
jar file and reduced the size of the jar file to contain about 263 
required class files (as compared to thousands originally).  Then I 
re-ran the 3rd party connection from within pljava again and still 
seeing the same 'stack depth limit exceeded' problem.

May I know what is the stack depth limit for the second thread that 
spawned from pljava?  As of now, I have no idea how to work around this 
problem.

Thanks so much.

Regards,
Kong

Thomas Hallgren wrote:

> OK, I see the problem. The connection spawns a new thread, that thread 
> loads classes. And of course, the stack of that thread cannot be 
> compared to the stack of the caller thread. PostgresSQL (since it's 
> singlethreaded) thinks that you eat a vast amount of stack.
>
> I'll address this on the PostgreSQL hackers mailing list and see if I 
> can convince them to install something that makes it possible to 
> temporary shut off the stack-check. A temporary work-around is to 
> reference the needed classes before making the connect call. That way, 
> the current thread will be the one who loads them.
>
> Regards,
> Thomas Hallgren
>
>
> kstian wrote:
>
>> Hi Thomas,
>>
>> Thanks for replying.
>>
>> I have gradually increased max_stack_depth in postgresql.conf to 
>> 16384 (verified from show all in the db) but it did not seem to help.
>>
>> The following is the code I have for the trigger function.  
>> Basically, what I wanted it to do is, upon data update, I wanted to 
>> connect to serivcemix (jbi container) and publish the event to 
>> activeMQ.  The problem happened on the line where I marked "==>  
>> <==".  I also printed out the loaded classes from sqlj.Loader.java in 
>> findClass method and it showed a lot of loaded classes.  These 
>> classes were to be passed to sql statement for loading.
>>
>> =================================
>> mport java.sql.SQLException;
>> import java.sql.ResultSet;
>> import java.util.logging.Logger;
>>
>> import org.postgresql.pljava.TriggerData;
>> import org.postgresql.pljava.TriggerException;
>>
>>
>> import javax.jms.Connection;
>> import javax.jms.JMSException;
>> import javax.jms.Session;
>> import javax.jms.MessageProducer;
>>
>> import org.activemq.ActiveMQConnectionFactory;
>> import org.activemq.ActiveMQConnection;
>> import org.activemq.message.ActiveMQTopic;
>>
>> public class Triggers {
>>
>>    public static void afterUpdateTsr(TriggerData td) throws 
>> SQLException, JMSException
>>    {
>>        if (td.isFiredForStatement())
>>            throw new TriggerException(td, "Cannot process statement 
>> events.");
>>                  if (td.isFiredBefore())
>>            throw new TriggerException(td, "Must be fired after event.");
>>                  if (!td.isFiredByUpdate())
>>            throw new TriggerException(td, "Can only process UPDATE 
>> event");
>>                  ResultSet _new = td.getNew();
>>        ResultSet _old = td.getOld();
>>        String[] args = td.getArguments();
>>        String status = args[1];
>>              if (args.length != 1)
>>            throw new TriggerException(td, "One argument is expected.");
>>              Logger log = Logger.getAnonymousLogger();
>>        log.info("After UPDATE to tservicerequest table with new 
>> tstatus = " + _new.getString(status) + ", old tstatus = " + 
>> _old.getString(status));
>>              ActiveMQConnectionFactory factory = new 
>> ActiveMQConnectionFactory(ActiveMQConnection.DEFAULT_USER, 
>> ActiveMQConnection.DEFAULT_PASSWORD, 
>> ActiveMQConnection.DEFAULT_BROKER_URL); //"tcp://localhost:61616");
>>        ActiveMQTopic pubTopic = new 
>> ActiveMQTopic("demo.org.servicemix.source");
>>        //ActiveMQTopic subTopic = new 
>> ActiveMQTopic("demo.org.servicemix.result");
>>              log.info("Connecting to JMS Server...");
>>        Connection connection = factory.createConnection();
>>        log.info("Before setClientID");
>> ==>connection.start();  <==
>>        Session session = connection.createSession(false, 
>> Session.AUTO_ACKNOWLEDGE);
>>        MessageProducer producer = session.createProducer(pubTopic);
>>        //connection.start();
>>              log.info("Sending request to JMS Server...");
>>        producer.send(session.createTextMessage("New tstatus= " + 
>> _new.getString(status) + ", old tstatus= " + _old.getString(status)));
>>              log.info("Sent message: New tstatus= " + 
>> _new.getString(status) + ", old tstatus= " + _old.getString(status));
>>        //connection.close();
>>
>>    }
>> }
>>
>> ===============================================
>>
>> Thanks a lot for help.
>>
>> Regards,
>> Kong
>>
>> Thomas Hallgren wrote:
>>
>>> kstian wrote:
>>>
>>>> Hi,
>>>>
>>>> I created the following Trigger and Function:
>>>>
>>>> ======================================
>>>>        CREATE FUNCTION afterUpdateTsr()
>>>>            RETURNS trigger
>>>>            AS 'pljava.Triggers.afterUpdateTservicerequest'
>>>>            LANGUAGE java;
>>>>
>>>>        CREATE TRIGGER tsr_afterUpdate
>>>>            AFTER UPDATE ON tsr
>>>>            FOR EACH ROW
>>>>            EXECUTE PROCEDURE afterUpdateTsr(name);   
>>>> ==========================================
>>>>
>>>> Then in the afterUpdateTsr() java function, I was writing codes to 
>>>> connect to servicemix (a JBI container).
>>>>
>>>> In order to do that, I had to install 11 jar files in my postgresql 
>>>> table using sqlj.install_jar function.
>>>>
>>>> When the aferUpdateTsr() got triggered, it was throwing "stack 
>>>> depth limit exceeded" exception from native C. (I believed it's 
>>>> from ExecutionPlan.c).  I also printed out the loaded classes from 
>>>> sqlj/Loader.java (findClass function) and found that pljava was 
>>>> loading a lot of classes.
>>>> Was it the main reason causing this exception?  How do I resolve 
>>>> this problem?
>>>>
>>> Normally, a "stack depth limit exceeded" exception is caused by a 
>>> function that calls SQL, that in turn calls a function that calls 
>>> SQL, etc. until you recurse so deep that the PostgreSQL callstack is 
>>> exhausted. If it's a controlled and expected recursion you can try 
>>> to increase the max_stack_depth variable in your postgresql.conf
>>>
>>> If you this doesn't help, then I'll have to know a bit more about 
>>> what your triggers are doing in order to assist you.
>>>
>>> Kind regards,
>>> Thomas Hallgren
>>>
>>>
>>>
>>>
>>>
>>>
>>
>
>
>
>





^ permalink  raw  reply  [nested|flat] 7+ messages in thread

* [Pljava-dev] stack depth limit exceeded (NOT from infinite	recursion)
  2005-09-23 08:56 [Pljava-dev] stack depth limit exceeded (NOT from infinite recursion) 
  2005-09-23 10:38 ` [Pljava-dev] stack depth limit exceeded (NOT from infinite	recursion) 
  2005-09-28 01:51   ` [Pljava-dev] stack depth limit exceeded (NOT from infinite	recursion) 
@ 2005-09-28 05:42     ` 
  1 sibling, 0 replies; 7+ messages in thread

From:  @ 2005-09-28 05:42 UTC (permalink / raw)

Kong,
PostgreSQL only defines one stack, and thus one stack_depth_limit. It's 
not built for multiple threads and at present and PL/Java has no way of 
telling PostgreSQL that another thread is about to do something. 
PostgreSQL still thinks it's the same stack, hence the problem. The 
stack-depth of the other thread is irrelevant. The problem is caused by 
PostgreSQL comparing the stack_pointer from one stack with the 
stack_base from another.

You encounter this problem because a thread other then the main thread 
is the first to encounter a class. That causes the classloader to make 
an attempt to load the class in that thread. If you can find out what 
class it is and then reference this class in advance from the main 
thread, the problem will go away since the main thread will be the one 
that loads the class.

An alternative to this is to set the max_stack_depth to a ridiculously 
high value and thus turn of stack checks altogether. I don't think that 
will cause a major problem anyway. If you run into a stack-overflow, the 
process will page-fault and terminate.

I know none of those solutions are ideal but until I can convince the 
PostgreSQL people to provide a function whereby I can set another 
stack_base, there's nothing else I can do.

Regards,
Thomas Hallgren

kstian wrote:

> Hi Thomas,
>
> Thanks a lot for the info.  I went through reorganizing the installed 
> jar file and reduced the size of the jar file to contain about 263 
> required class files (as compared to thousands originally).  Then I 
> re-ran the 3rd party connection from within pljava again and still 
> seeing the same 'stack depth limit exceeded' problem.
>
> May I know what is the stack depth limit for the second thread that 
> spawned from pljava?  As of now, I have no idea how to work around 
> this problem.
>
> Thanks so much.
>
> Regards,
> Kong
>
> Thomas Hallgren wrote:
>
>> OK, I see the problem. The connection spawns a new thread, that 
>> thread loads classes. And of course, the stack of that thread cannot 
>> be compared to the stack of the caller thread. PostgresSQL (since 
>> it's singlethreaded) thinks that you eat a vast amount of stack.
>>
>> I'll address this on the PostgreSQL hackers mailing list and see if I 
>> can convince them to install something that makes it possible to 
>> temporary shut off the stack-check. A temporary work-around is to 
>> reference the needed classes before making the connect call. That 
>> way, the current thread will be the one who loads them.
>>
>> Regards,
>> Thomas Hallgren
>






^ permalink  raw  reply  [nested|flat] 7+ messages in thread

* [Pljava-dev] stack depth limit exceeded (NOT from infinite	recursion)
  2005-09-23 08:56 [Pljava-dev] stack depth limit exceeded (NOT from infinite recursion) 
  2005-09-23 10:38 ` [Pljava-dev] stack depth limit exceeded (NOT from infinite	recursion) 
  2005-09-28 01:51   ` [Pljava-dev] stack depth limit exceeded (NOT from infinite	recursion) 
@ 2005-09-28 06:38     ` 
  1 sibling, 0 replies; 7+ messages in thread

From:  @ 2005-09-28 06:38 UTC (permalink / raw)

Thanks a lot Thomas, "set the max_stack_depth to a ridiculously high 
value" appeared to work around the problem for now.  This is the 
quickest solution at the moment and I will try that till I see another 
problem.

Thanks again.

Regards,
Kong

Thomas Hallgren wrote:

> Kong,
> PostgreSQL only defines one stack, and thus one stack_depth_limit. 
> It's not built for multiple threads and at present and PL/Java has no 
> way of telling PostgreSQL that another thread is about to do 
> something. PostgreSQL still thinks it's the same stack, hence the 
> problem. The stack-depth of the other thread is irrelevant. The 
> problem is caused by PostgreSQL comparing the stack_pointer from one 
> stack with the stack_base from another.
>
> You encounter this problem because a thread other then the main thread 
> is the first to encounter a class. That causes the classloader to make 
> an attempt to load the class in that thread. If you can find out what 
> class it is and then reference this class in advance from the main 
> thread, the problem will go away since the main thread will be the one 
> that loads the class.
>
> An alternative to this is to set the max_stack_depth to a ridiculously 
> high value and thus turn of stack checks altogether. I don't think 
> that will cause a major problem anyway. If you run into a 
> stack-overflow, the process will page-fault and terminate.
>
> I know none of those solutions are ideal but until I can convince the 
> PostgreSQL people to provide a function whereby I can set another 
> stack_base, there's nothing else I can do.
>
> Regards,
> Thomas Hallgren
>
> kstian wrote:
>
>> Hi Thomas,
>>
>> Thanks a lot for the info.  I went through reorganizing the installed 
>> jar file and reduced the size of the jar file to contain about 263 
>> required class files (as compared to thousands originally).  Then I 
>> re-ran the 3rd party connection from within pljava again and still 
>> seeing the same 'stack depth limit exceeded' problem.
>>
>> May I know what is the stack depth limit for the second thread that 
>> spawned from pljava?  As of now, I have no idea how to work around 
>> this problem.
>>
>> Thanks so much.
>>
>> Regards,
>> Kong
>>
>> Thomas Hallgren wrote:
>>
>>> OK, I see the problem. The connection spawns a new thread, that 
>>> thread loads classes. And of course, the stack of that thread cannot 
>>> be compared to the stack of the caller thread. PostgresSQL (since 
>>> it's singlethreaded) thinks that you eat a vast amount of stack.
>>>
>>> I'll address this on the PostgreSQL hackers mailing list and see if 
>>> I can convince them to install something that makes it possible to 
>>> temporary shut off the stack-check. A temporary work-around is to 
>>> reference the needed classes before making the connect call. That 
>>> way, the current thread will be the one who loads them.
>>>
>>> Regards,
>>> Thomas Hallgren
>>
>>
>
>
>
>





^ permalink  raw  reply  [nested|flat] 7+ messages in thread


end of thread, other threads:[~2005-09-28 06:38 UTC | newest]

Thread overview: 7+ messages (download: mbox mbox.gz follow: Atom feed)
-- links below jump to the message on this page --
2005-09-23 08:56 [Pljava-dev] stack depth limit exceeded (NOT from infinite recursion) 
2005-09-23 09:42 ` [Pljava-dev] stack depth limit exceeded (NOT from infinite	recursion) 
2005-09-23 10:38 ` [Pljava-dev] stack depth limit exceeded (NOT from infinite	recursion) 
2005-09-23 10:47   ` [Pljava-dev] stack depth limit exceeded (NOT from infinite	recursion) 
2005-09-28 01:51   ` [Pljava-dev] stack depth limit exceeded (NOT from infinite	recursion) 
2005-09-28 05:42     ` [Pljava-dev] stack depth limit exceeded (NOT from infinite	recursion) 
2005-09-28 06:38     ` [Pljava-dev] stack depth limit exceeded (NOT from infinite	recursion) 

This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox