Rstudio Connect Shiny dashboard only shows plot if table is visible

121 Views Asked by At

I want to have a Shiny dashboard on Rstudio Connect where data is read from my companies data store via JDBC, and then plotted. Ultimately the user would be able to give some parameters and the appropriate output would be displayed.

What I've discovered is that if I show a table of the data and the plot, everything works out fine. However, if I do not display the table I get an error:

Error: An error has occurred. Check your logs or contact the app author for clarification.

The line in the log files related to the error is not meaningful to me, but appears to be java related (and so maybe related to the JDBC connection):

Warning: Error in .jcheck: Java Exception <no description because toString() failed>
.jcall(conn@jc, "Ljava/sql/Statement;", "createStatement")
new("jobjRef", jobj = <pointer: 0x55cbc9a35608>, jclass = "java/lang/Throwable")

What works?

Here's as minimum a reproducible example as I could get. I appreciate that the architecture is internal to my company, so it won't run for others, but I think it can be helpful. The below code works:

# app.R
library(RJDBC)
library(shiny)


getconnection <- function(){
    ORACLE_JAR <- '/usr/lib/oracle/21/client64/lib/ojdbc8.jar'
    db_host = "db_host.company.information:1521"
    drv <- RJDBC::JDBC("oracle.jdbc.OracleDriver",
                       ORACLE_JAR,
                       identifier.quote="`")
    sid <- "sid.prd.tns"
    url <- paste("jdbc:oracle:thin:@/",
                 db_host,
                 sid, sep = '/')
    connection<-dbConnect(drv,
                          url,
                          user='****', # anonymised for stack overflow
                          password='****',
                          believeNRows=FALSE )
   return(connection)

}


ui <- fluidPage(
  titlePanel("MinRepEx"),
  tableOutput('result'),
  plotOutput('plot')
)

server <- function(input, output) {
  conn <- getconnection()
  mydata <- reactive({query_result(conn)})
  output$result <- renderTable(head(mydata()))
  output$result <- NULL
  myplot <- reactive({plot(OBS_VALUE ~ OBS_DATE, data = mydata())})
  output$plot <-renderPlot({myplot()})
}


shinyApp(ui = ui, server = server)

When I deploy this, as I say it works: table and data

What doesn't work?

If I remove the lines related to result, i.e. the table output things stop working:


## Everyhing above this line is kept unchanged

ui <- fluidPage(
  titlePanel("MinRepEx"),
#  tableOutput('result'),
  plotOutput('plot')
)

server <- function(input, output) {
  conn <- getconnection()
  mydata <- reactive({query_result(conn)})
# output$result <- renderTable(head(mydata()))
  myplot <- reactive({plot(OBS_VALUE ~ OBS_DATE, data = mydata())})
  output$plot <-renderPlot({myplot()})
}


shinyApp(ui = ui, server = server)

which leads to: not working

Possible solutions that need tweeking:

The code works as intended on my machine it does not work when I ship it to RStudio Connect.

The code is a minimised version of the code where there is a need for query_result to be a reactive function, so I can't take it out of the reactive world. However, if I do, I can display the chart on its own. `

Likewise, if I open the connection conn inside mydata it will generate the image. However opening the connection each time is very slow. If there was someway to check if a connection was open and if not open one, or to make the connection visible inside mydata?

What else have I tried?

I've tried a few other things that might help inform about the solution:

  • If I just do renderTable, there are no problems (except that I do't have the chart I want).
  • If I change the order of plotOutput and tableOutput in the UI, the table and plot appear
  • If I change the order of renderTable and renderPlot in the server, neither table nor plot are produced and I have the same error message in the logs twice.
  • If I introduce a Sys.sleep(60) command to myplot, it doesn't fix the issue
  • I have put a the line data <- mydata() inside the renderPlot({...}) before myplot()

The above 'possible solutions' might yield something, but rather frustratingly, I would like to know why the connection remains visible if I show the table or the table and plot, but not the plot on its own. Likewise, the code works without this issue locally, but not remotely. It would be interesting to understand why.

0

There are 0 best solutions below