0

I have a really weird problem that I cannot find a solution for. I have a Java class that extends Thread. I instantiate it (from a thread form a ThreadPoolExecutor) and run start(). However, the execution just hangs and never returns from the constructor, despite its first statement not being run.

Here's the only constructor declared in the class:

public class Recorder extends Thread{

private String channelId;
private RecorderCallback recorderCallback;
public Recorder(String channelId, String workingDirectory, RecorderCallback RecorderCallback){
    //super();
    try{
        System.out.println(getCurrentTimeStamp() + " DEBUG new recorder: " + channelId + " | " + workingDirectory);
        this.channelId = channelId;
        String timeString = new SimpleDateFormat("dd.MM.yyyy-HHmmss").format(new Date());
        this.directory = timeString + "_" + channelId;
        new File(workingDirectory + File.separator + directory).mkdirs();
    } catch (Exception exception){
        System.out.println(getCurrentTimeStamp() + " An unexpected exception occurred: " + exception.getMessage());
        exception.printStackTrace();
    } finally {
        System.out.println(getCurrentTimeStamp() + " DEBUG FINALLY called in CONSTRUCTOR");
    }
}

Here's the point where I initialize and run a new Recorder (which is NOT wrapped in a try/catch block and the method this code is in isn't declared to throw any exceptions):

System.out.println(getCurrentTimeStamp() + " Creating new recorder [" + channelId + "]");
Recorder recorder = new Recorder(channelId, Constants.RECORDING_WORKING_DIR, this);
System.out.println(getCurrentTimeStamp() + " DEBUG Instance created"));
recorder.start();

When I run the application, I get this trace:

[timestamp] Creating new recorder [channelname]

No other output at all. I'm using OpenJDK 1.8.0_242.

Is the problem that the print just isn't processed? What am I missing?

Tephelon
  • 105
  • 2
  • 8
  • 2
    Run it in a debugger. Place a breakpoint a the line with the `println` and step through. – Axel Feb 03 '20 at 11:44
  • I'm unfortunately unable to debug it properly because it's being run in a server environment using config and key files I don't have access to. The code is also only run on external webhooks, so I'd have to write a huge test suite to debug it properly. – Tephelon Feb 03 '20 at 11:46
  • 1
    If you can't slim the code down to a [mcve] and reproduce it from the small sample, because the problem only occurs when you run it on your server, then it's very unlikely that the lines of code that have posted above allow "people on the internet" to solve your problem. My advice: do try to slim your real-world code down to a mcve that reproduces the problem, before posting on StackOverflow. – Erwin Bolwidt Feb 03 '20 at 11:56
  • I was apparently a bit dramatic, I was able to slim it down because I misjudged what modules I needed for a local test. On my local machine, the code works as expected. The Recorder is initialized and run properly and everything functions as it should. Of course, I disabled some code, but I don't think I disabled any code that interferes with the process at all... – Tephelon Feb 03 '20 at 11:58
  • Does your program run ok on your local machine, but you have this problem when you try to run on an application server? What server are you using? – CocoNess Feb 03 '20 at 12:09
  • Exactly. Locally, I use Oracle's JDK 1.8.0_111, on my server I use OpenJDK 1.8.0_242 on Ubuntu 19.10. – Tephelon Feb 03 '20 at 12:13
  • Rights on the directories? You could comment out mkdirs / only conditionally call it when not you on the other side. – Joop Eggen Feb 03 '20 at 12:14
  • That is a very good point. The same code has worked in the past and I should have the rights for that. As far as I now, mkdirs doesn't throw but returns false. In any case, I should still get some output on the cli, right? I may try moving that code outside the constructor and run it beforehand, thanks for the idea. – Tephelon Feb 03 '20 at 12:18
  • Do you creating files on network share? Path may looks local, but can in the same time mapped on some network resource and you actually need to access network when call mkdirs. – user1516873 Feb 03 '20 at 12:26
  • The whole thing runs on DigitalOcean and uses a Volume, which is mounted as a disk on the server. Writing and reading is more or less instant, and behaves like a regular disk drive as far as I know. This is a very good point, but all other file interactions on the volume work fine. I still in any case should see the first printline though, right? That's what's really confusing me. – Tephelon Feb 03 '20 at 12:34
  • 2
    You can use `jstack` to get a thread dump of a Java process. That should tell you if it is blocked anywhere. – Tom Hawtin - tackline Feb 03 '20 at 12:52
  • Thank you, this is an excellent idea. I can't find any of the threads there, so I assume they stopped execution. I found out that the Threads from the framework I was using had a try/catch block wrapped around their body and by default don't act on exceptions. I added an exception handler, but now all of a sudden everything works server-side as well. I'm even more confused now but I guess it works sometimes at least. Thanks everyone for your ideas and constructive criticism. – Tephelon Feb 03 '20 at 13:53
  • Two more unrelated yet important things: **1.** You should follow the Java Naming Conventions – variable names are written in camelCase, so `RecorderCallback` should be `recorderCallback`. (You are not using that variable by the way.) **2.** You shouldn't use the [obsolete and troublesome](https://stackoverflow.com/questions/1969442/whats-wrong-with-java-date-time-api) `Date` and `SimpleDateFormat` classes. Use classes from the [`java.time`](https://stackoverflow.com/a/48255274/507738) package instead. – MC Emperor Feb 03 '20 at 14:30
  • One more unrelated this: extending `Thread` and commenting out call to `super();` inside constructor is not a good idea. – Ivan Feb 03 '20 at 16:12
  • you can try remote debugging – Alexei Kaigorodov Feb 03 '20 at 22:42

0 Answers0