4

I have to run a java task, with a very large number of classpath (1000, totaling 150k characters if concatenated).

The problem is that java returns an error when I try to execute this class:

/jdk/JAVA8/bin/java: Argument list too long 

The error code is 7

I've tried to put the classpaths using "export CLASSPATH=CLASSPATH:....." and so I shouldn't specify them through the -cp java parameter, but it returned the same error.

I'm pretty sure that the problem revolves round a classpath's limit, because if I delete some of the classpath, the error disappears (but then I will have logical errors in the execution, because I need all the classpaths)

M4rk
  • 2,172
  • 5
  • 36
  • 70
  • Why? Why not run a JAR file that lists them all in its Manifest Class-path entry? – user207421 Jan 20 '17 at 01:03
  • This would be a class to make some prebuild code analysis, so it needs all the classpaths and it doesn't need to be a jar itself. I could generate jar, would it solve the problem? – M4rk Jan 20 '17 at 01:05

3 Answers3

2
  • You could use classpath wildcards. Especially if many of your jars/class files are in the same directory, this would help a lot.

  • It could be environment variable size limit or command-line size limit as well rather than javac classpath arg limit.

  • javac takes arguments from file input as well. You can add all your arguments to this file and pass this file argument to command. Refer this for more.

  • Unfortunately they are all in different directories (using build systems that cache libs internally), and there is no need to use javac since I just have to execute a class which is part of a prebuild task. – M4rk Jan 20 '17 at 22:07
2

You didn’t hit a java-specific limitation, but a system dependent limit. This is best illustrated by the fact, that the attempt to set the CLASSPATH variable fails as well, but setting an environment variable via export name=value in the shell isn’t related to Java.

As said by others, you could try to use wildcards for jar files within the same directory, but you have to care that Java does the expansion rather than the shell, as in the latter case, it would again yield a too long command line. So you have to escape the * character to ensure it will not be processed by the shell.

javac supports reading the command line arguments from an external file specified via @filename, but unfortunately, the java launcher doesn’t support this option.

An alternative would be to create symbolic links pointing to the jar files, having shorter paths and specifying these. You could even combine the approaches by creating one directory full of symbolic links and specifying that/directory/* as class path.

But there seems to be a logical error in the requirement. In a comment, you are mentioning “code analysis” and an analyzing tool should not require having the code to analyze in its own application class path. You can access class files via ordinary I/O, if you want to read and parse them. In case you want to load them, e.g. for using the builtin Reflection, you can create new ClassLoader instances pointing to the locations. So the tool doesn’t depend on the application class path and could read the locations from a configuration file, for example.

Using distinct class loaders has the additional advantage that you can close them when you’re done.

Holger
  • 285,553
  • 42
  • 434
  • 765
1

JVM does not limit classpath length. However, there is a hard OS limit on command line length and environment variables size.

On Linux check getconf ARG_MAX to see the limit.
On older kernel versions it is only 128KB. On newer kernels it is somewhere around 2MB.

If you want to set really long classpaths, you may need a JAR-Manifest trick. See this question for details.

Community
  • 1
  • 1
apangin
  • 92,924
  • 10
  • 193
  • 247